Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add support of client report #552

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 22 additions & 5 deletions src/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { eventFromException, eventFromMessage } from '@sentry/browser';
import { BaseClient } from '@sentry/core';
import type {
ClientReportEnvelope,
ClientReportItem,
Envelope,
Event,
EventHint,
Expand All @@ -10,12 +12,14 @@ import type {
Thread,
UserFeedback,
} from '@sentry/types';
import { logger, SentryError } from '@sentry/utils';
import { dateTimestampInSeconds, logger, SentryError } from '@sentry/utils';

import type { CapacitorClientOptions } from './options';
import { mergeOutcomes } from './utils/outcome';
import { NATIVE } from './wrapper';

export const EnvelopeitemsIndex = 1;
lucas-zimerman marked this conversation as resolved.
Show resolved Hide resolved

/**
* The Sentry Capacitor SDK Client.
*
Expand Down Expand Up @@ -108,8 +112,7 @@ export class CapacitorClient extends BaseClient<CapacitorClientOptions> {
this._outcomesBuffer = mergeOutcomes(this._outcomesBuffer, outcomes);

if (this._options.sendClientReports) {
// TODO: Implement Cleint Report.
// this._attachClientReportTo(this._outcomesBuffer, envelope as ClientReportEnvelope);
this._attachClientReportTo(this._outcomesBuffer, envelope as ClientReportEnvelope);
}

let shouldClearOutcomesBuffer = true;
Expand Down Expand Up @@ -163,6 +166,20 @@ export class CapacitorClient extends BaseClient<CapacitorClientOptions> {
console.log('Sentry Warning, could not connect to Sentry native SDK.\nIf you do not want to use the native component please pass `enableNative: false` in the options.\nVisit: https://docs.sentry.io/platforms/javascript/guides/capacitor/configuration/options/#hybrid-sdk-options for more details.');
}
}

// TODO: implement Attaches clients report.
/**
* Attaches a client report from outcomes to the envelope.
*/
private _attachClientReportTo(outcomes: Outcome[], envelope: ClientReportEnvelope): void {
if (outcomes.length > 0) {
const clientReportItem: ClientReportItem = [
{ type: 'client_report' },
{
timestamp: dateTimestampInSeconds(),
discarded_events: outcomes,
},
];

envelope[EnvelopeitemsIndex].push(clientReportItem);
lucas-zimerman marked this conversation as resolved.
Show resolved Hide resolved
}
}
}
87 changes: 50 additions & 37 deletions test/client.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import type { Envelope, Transport } from '@sentry/types';
import type { Envelope, Outcome, Transport } from '@sentry/types';

import { CapacitorClient } from '../src/client';
import type { CapacitorClientOptions } from '../src/options';
import { NativeTransport } from '../src/transports/native';
import { NATIVE } from '../src/wrapper';
import {
envelopeItemHeader,
envelopeItemPayload,
envelopeItems,
firstArg,
getSyncPromiseRejectOnFirstCall,
} from './testutils';

interface MockedCapacitor {
Platform: {
Expand Down Expand Up @@ -68,6 +75,8 @@ jest.mock('../src/plugin', () => {
};
});

import { rejectedSyncPromise,SentryError } from '@sentry/utils';

import * as Plugin from '../src/plugin';


Expand Down Expand Up @@ -294,35 +303,35 @@ describe('Tests CapacitorClient', () => {
});
});
*/
/* TODO: Fix SDKInfo
describe('event data enhancement', () => {
test('event contains sdk default information', async () => {
const mockedSend = jest.fn<PromiseLike<void>, [Envelope]>().mockResolvedValue(undefined);
const mockedTransport = (): Transport => ({
send: mockedSend,
flush: jest.fn().mockResolvedValue(true),
});
const client = new CapacitorClient({
...DEFAULT_OPTIONS,
dsn: EXAMPLE_DSN,
transport: mockedTransport,
});

client.captureEvent({ message: 'test event' });

expect(mockedSend).toBeCalled();
const actualEvent: Event | undefined = <Event>(
mockedSend.mock.calls[0][firstArg][envelopeItems][0][envelopeItemPayload]
);
expect(actualEvent?.sdk?.packages).toEqual([
{
name: SDK_PACKAGE_NAME,
version: SDK_VERSION,
},
]);
/* TODO: Fix SDKInfo
describe('event data enhancement', () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

L: From what I see this is unrelated to the PR, looks like only the indentation changed.

What needs to be fixed with SDKInfo?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah only the indentation changed.

I made a PR only for SDKInfo separately just to avoid fixing everything on a single PR.

It's basically missing the default export from the SDK on the integration.

test('event contains sdk default information', async () => {
const mockedSend = jest.fn<PromiseLike<void>, [Envelope]>().mockResolvedValue(undefined);
const mockedTransport = (): Transport => ({
send: mockedSend,
flush: jest.fn().mockResolvedValue(true),
});
const client = new CapacitorClient({
...DEFAULT_OPTIONS,
dsn: EXAMPLE_DSN,
transport: mockedTransport,
});

client.captureEvent({ message: 'test event' });

expect(mockedSend).toBeCalled();
const actualEvent: Event | undefined = <Event>(
mockedSend.mock.calls[0][firstArg][envelopeItems][0][envelopeItemPayload]
);
expect(actualEvent?.sdk?.packages).toEqual([
{
name: SDK_PACKAGE_NAME,
version: SDK_VERSION,
},
]);
});

});
*/
describe('normalizes events', () => {
/* TODO: Fix later
Expand Down Expand Up @@ -359,7 +368,6 @@ describe('Tests CapacitorClient', () => {
*/
});

/* TODO: To be fixed on Client Report implementation.
describe('clientReports', () => {
test('does not send client reports if disabled', () => {
const mockTransportSend = jest.fn((_envelope: Envelope) => Promise.resolve());
Expand All @@ -380,7 +388,6 @@ describe('Tests CapacitorClient', () => {
expectOnlyMessageEventInEnvelope(mockTransportSend);
});

/* TODO: Implement Client Report
test('send client reports on event envelope', () => {
const mockTransportSend = jest.fn((_envelope: Envelope) => Promise.resolve());
const client = new CapacitorClient({
Expand Down Expand Up @@ -431,9 +438,7 @@ describe('Tests CapacitorClient', () => {

expectOnlyMessageEventInEnvelope(mockTransportSend);
});
*/
/*
TODO: To be implemented

test('keeps outcomes in case envelope fails to send', () => {
const mockTransportSend = jest.fn((_envelope: Envelope) => rejectedSyncPromise(new SentryError('Test')));
const client = new CapacitorClient({
Expand All @@ -454,10 +459,7 @@ describe('Tests CapacitorClient', () => {
{ reason: 'before_send', category: 'error', quantity: 1 },
]);
});
*/

/*
TODO: To be implemented.
test('sends buffered client reports on second try', () => {
const mockTransportSend = getSyncPromiseRejectOnFirstCall<[Envelope]>(new SentryError('Test'));
const client = new CapacitorClient({
Expand Down Expand Up @@ -493,9 +495,19 @@ describe('Tests CapacitorClient', () => {
);
expect((client as unknown as { _outcomesBuffer: Outcome[] })._outcomesBuffer).toEqual(<Outcome[]>[]);
});
*/
});

function expectOnlyMessageEventInEnvelope(transportSend: jest.Mock) {
expect(transportSend).toBeCalledTimes(1);
expect(transportSend.mock.calls[0][firstArg][envelopeItems]).toHaveLength(1);
expect(transportSend.mock.calls[0][firstArg][envelopeItems][0][envelopeItemHeader]).toEqual(
expect.objectContaining({ type: 'event' }),
);
}

function mockDroppedEvent(client: CapacitorClient) {
client.recordDroppedEvent('before_send', 'error');
}
});

function mockedOptions(options: Partial<CapacitorClientOptions>): CapacitorClientOptions {
return {
Expand All @@ -508,3 +520,4 @@ describe('Tests CapacitorClient', () => {
...options,
};
}
});
Loading