Skip to content

Commit 4bbe220

Browse files
committed
cleanup
1 parent 6da04d6 commit 4bbe220

File tree

3 files changed

+0
-547
lines changed

3 files changed

+0
-547
lines changed

packages/feedback/jest.setup.ts

Lines changed: 0 additions & 267 deletions
Original file line numberDiff line numberDiff line change
@@ -1,272 +1,5 @@
1-
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
2-
import { getCurrentHub } from '@sentry/core';
3-
import type { ReplayRecordingData, Transport } from '@sentry/types';
4-
import { TextEncoder } from 'util';
5-
6-
import type { ReplayContainer, Session } from './src/types';
7-
8-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
9-
(global as any).TextEncoder = TextEncoder;
10-
11-
type MockTransport = jest.MockedFunction<Transport['send']>;
12-
131
jest.mock('./src/util/isBrowser', () => {
142
return {
153
isBrowser: () => true,
164
};
175
});
18-
19-
type EnvelopeHeader = {
20-
event_id: string;
21-
sent_at: string;
22-
sdk: {
23-
name: string;
24-
version?: string;
25-
};
26-
};
27-
28-
type ReplayEventHeader = { type: 'replay_event' };
29-
type ReplayEventPayload = Record<string, unknown>;
30-
type RecordingHeader = { type: 'replay_recording'; length: number };
31-
type RecordingPayloadHeader = Record<string, unknown>;
32-
type SentReplayExpected = {
33-
envelopeHeader?: EnvelopeHeader;
34-
replayEventHeader?: ReplayEventHeader;
35-
replayEventPayload?: ReplayEventPayload;
36-
recordingHeader?: RecordingHeader;
37-
recordingPayloadHeader?: RecordingPayloadHeader;
38-
recordingData?: ReplayRecordingData;
39-
};
40-
41-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
42-
const toHaveSameSession = function (received: jest.Mocked<ReplayContainer>, expected: undefined | Session) {
43-
const pass = this.equals(received.session?.id, expected?.id) as boolean;
44-
45-
const options = {
46-
isNot: this.isNot,
47-
promise: this.promise,
48-
};
49-
50-
return {
51-
pass,
52-
message: () =>
53-
`${this.utils.matcherHint(
54-
'toHaveSameSession',
55-
undefined,
56-
undefined,
57-
options,
58-
)}\n\n${this.utils.printDiffOrStringify(expected, received.session, 'Expected', 'Received')}`,
59-
};
60-
};
61-
62-
type Result = {
63-
passed: boolean;
64-
key: string;
65-
expectedVal: SentReplayExpected[keyof SentReplayExpected];
66-
actualVal: SentReplayExpected[keyof SentReplayExpected];
67-
};
68-
type Call = [
69-
EnvelopeHeader,
70-
[
71-
[ReplayEventHeader | undefined, ReplayEventPayload | undefined],
72-
[RecordingHeader | undefined, RecordingPayloadHeader | undefined],
73-
],
74-
];
75-
type CheckCallForSentReplayResult = { pass: boolean; call: Call | undefined; results: Result[] };
76-
77-
function checkCallForSentReplay(
78-
call: Call | undefined,
79-
expected?: SentReplayExpected | { sample: SentReplayExpected; inverse: boolean },
80-
): CheckCallForSentReplayResult {
81-
const envelopeHeader = call?.[0];
82-
const envelopeItems = call?.[1] || [[], []];
83-
const [[replayEventHeader, replayEventPayload], [recordingHeader, recordingPayload] = []] = envelopeItems;
84-
85-
// @ts-ignore recordingPayload is always a string in our tests
86-
const [recordingPayloadHeader, recordingData] = recordingPayload?.split('\n') || [];
87-
88-
const actualObj: Required<SentReplayExpected> = {
89-
// @ts-ignore Custom envelope
90-
envelopeHeader: envelopeHeader,
91-
// @ts-ignore Custom envelope
92-
replayEventHeader: replayEventHeader,
93-
// @ts-ignore Custom envelope
94-
replayEventPayload: replayEventPayload,
95-
// @ts-ignore Custom envelope
96-
recordingHeader: recordingHeader,
97-
recordingPayloadHeader: recordingPayloadHeader && JSON.parse(recordingPayloadHeader),
98-
recordingData,
99-
};
100-
101-
const isObjectContaining = expected && 'sample' in expected && 'inverse' in expected;
102-
const expectedObj = isObjectContaining
103-
? (expected as { sample: SentReplayExpected }).sample
104-
: (expected as SentReplayExpected);
105-
106-
if (isObjectContaining) {
107-
console.warn('`expect.objectContaining` is unnecessary when using the `toHaveSentReplay` matcher');
108-
}
109-
110-
const results = expected
111-
? Object.keys(expectedObj)
112-
.map(key => {
113-
const actualVal = actualObj[key as keyof SentReplayExpected];
114-
const expectedVal = expectedObj[key as keyof SentReplayExpected];
115-
const passed = !expectedVal || this.equals(actualVal, expectedVal);
116-
117-
return { passed, key, expectedVal, actualVal };
118-
})
119-
.filter(({ passed }) => !passed)
120-
: [];
121-
122-
const pass = Boolean(call && (!expected || results.length === 0));
123-
124-
return {
125-
pass,
126-
call,
127-
results,
128-
};
129-
}
130-
131-
/**
132-
* Only want calls that send replay events, i.e. ignore error events
133-
*/
134-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
135-
function getReplayCalls(calls: any[][][]): any[][][] {
136-
return calls
137-
.map(call => {
138-
const arg = call[0];
139-
if (arg.length !== 2) {
140-
return [];
141-
}
142-
143-
if (!arg[1][0].find(({ type }: { type: string }) => ['replay_event', 'replay_recording'].includes(type))) {
144-
return [];
145-
}
146-
147-
return [arg];
148-
})
149-
.filter(Boolean);
150-
}
151-
152-
/**
153-
* Checks all calls to `fetch` and ensures a replay was uploaded by
154-
* checking the `fetch()` request's body.
155-
*/
156-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
157-
const toHaveSentReplay = function (
158-
_received: jest.Mocked<ReplayContainer>,
159-
expected?: SentReplayExpected | { sample: SentReplayExpected; inverse: boolean },
160-
) {
161-
const { calls } = (getCurrentHub().getClient()?.getTransport()?.send as MockTransport).mock;
162-
163-
let result: CheckCallForSentReplayResult;
164-
165-
const expectedKeysLength = expected
166-
? ('sample' in expected ? Object.keys(expected.sample) : Object.keys(expected)).length
167-
: 0;
168-
169-
const replayCalls = getReplayCalls(calls);
170-
171-
for (const currentCall of replayCalls) {
172-
result = checkCallForSentReplay.call(this, currentCall[0], expected);
173-
if (result.pass) {
174-
break;
175-
}
176-
177-
// stop on the first call where any of the expected obj passes
178-
if (result.results.length < expectedKeysLength) {
179-
break;
180-
}
181-
}
182-
183-
// @ts-ignore use before assigned
184-
const { results, call, pass } = result;
185-
186-
const options = {
187-
isNot: this.isNot,
188-
promise: this.promise,
189-
};
190-
191-
return {
192-
pass,
193-
message: () =>
194-
!call
195-
? pass
196-
? 'Expected Replay to not have been sent, but a request was attempted'
197-
: 'Expected Replay to have been sent, but a request was not attempted'
198-
: `${this.utils.matcherHint('toHaveSentReplay', undefined, undefined, options)}\n\n${results
199-
.map(({ key, expectedVal, actualVal }: Result) =>
200-
this.utils.printDiffOrStringify(
201-
expectedVal,
202-
actualVal,
203-
`Expected (key: ${key})`,
204-
`Received (key: ${key})`,
205-
),
206-
)
207-
.join('\n')}`,
208-
};
209-
};
210-
211-
/**
212-
* Checks the last call to `fetch` and ensures a replay was uploaded by
213-
* checking the `fetch()` request's body.
214-
*/
215-
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
216-
const toHaveLastSentReplay = function (
217-
_received: jest.Mocked<ReplayContainer>,
218-
expected?: SentReplayExpected | { sample: SentReplayExpected; inverse: boolean },
219-
) {
220-
const { calls } = (getCurrentHub().getClient()?.getTransport()?.send as MockTransport).mock;
221-
const replayCalls = getReplayCalls(calls);
222-
223-
const lastCall = replayCalls[calls.length - 1]?.[0];
224-
225-
const { results, call, pass } = checkCallForSentReplay.call(this, lastCall, expected);
226-
227-
const options = {
228-
isNot: this.isNot,
229-
promise: this.promise,
230-
};
231-
232-
return {
233-
pass,
234-
message: () =>
235-
!call
236-
? pass
237-
? 'Expected Replay to not have been sent, but a request was attempted'
238-
: 'Expected Replay to have last been sent, but a request was not attempted'
239-
: `${this.utils.matcherHint('toHaveSentReplay', undefined, undefined, options)}\n\n${results
240-
.map(({ key, expectedVal, actualVal }: Result) =>
241-
this.utils.printDiffOrStringify(
242-
expectedVal,
243-
actualVal,
244-
`Expected (key: ${key})`,
245-
`Received (key: ${key})`,
246-
),
247-
)
248-
.join('\n')}`,
249-
};
250-
};
251-
252-
expect.extend({
253-
toHaveSameSession,
254-
toHaveSentReplay,
255-
toHaveLastSentReplay,
256-
});
257-
258-
declare global {
259-
// eslint-disable-next-line @typescript-eslint/no-namespace
260-
namespace jest {
261-
interface AsymmetricMatchers {
262-
toHaveSentReplay(expected?: SentReplayExpected): void;
263-
toHaveLastSentReplay(expected?: SentReplayExpected): void;
264-
toHaveSameSession(expected: undefined | Session): void;
265-
}
266-
interface Matchers<R> {
267-
toHaveSentReplay(expected?: SentReplayExpected): R;
268-
toHaveLastSentReplay(expected?: SentReplayExpected): R;
269-
toHaveSameSession(expected: undefined | Session): R;
270-
}
271-
}
272-
}

0 commit comments

Comments
 (0)