Skip to content

Commit 817fc6c

Browse files
committed
add more unit tests
1 parent 8dd273b commit 817fc6c

File tree

2 files changed

+156
-43
lines changed

2 files changed

+156
-43
lines changed

packages/browser/src/tracing/previousTrace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface PreviousTraceInfo {
1919
export const PREVIOUS_TRACE_MAX_DURATION = 216_000;
2020

2121
// session storage key
22-
const PREVIOUS_TRACE_KEY = 'sentry_previous_trace';
22+
export const PREVIOUS_TRACE_KEY = 'sentry_previous_trace';
2323

2424
/**
2525
* Adds a previous_trace span link to the passed span if the passed
Lines changed: 155 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,83 @@
1-
import { describe, it, expect, vi } from 'vitest';
1+
import { describe, it, expect, beforeEach, vi } from 'vitest';
22
import type { PreviousTraceInfo } from '../../src/tracing/previousTrace';
3-
import { addPreviousTraceSpanLink, PREVIOUS_TRACE_MAX_DURATION } from '../../src/tracing/previousTrace';
4-
import type { StartSpanOptions } from '@sentry/core';
3+
import {
4+
addPreviousTraceSpanLink,
5+
getPreviousTraceFromSessionStorage,
6+
PREVIOUS_TRACE_KEY,
7+
PREVIOUS_TRACE_MAX_DURATION,
8+
} from '../../src/tracing/previousTrace';
9+
import { SentrySpan, spanToJSON, timestampInSeconds, type StartSpanOptions } from '@sentry/core';
10+
import { storePreviousTraceInSessionStorage } from '../../src/tracing/previousTrace';
11+
import { get } from 'http';
512

613
describe('addPreviousTraceSpanLink', () => {
7-
it(`adds a previous_trace span link to startSpanOptions if the previous trace was created within ${PREVIOUS_TRACE_MAX_DURATION}M`, () => {
14+
it(`adds a previous_trace span link to startSpanOptions if the previous trace was created within ${PREVIOUS_TRACE_MAX_DURATION}s`, () => {
15+
const currentSpanStart = timestampInSeconds();
16+
817
const previousTraceInfo: PreviousTraceInfo = {
918
spanContext: {
1019
traceId: '123',
1120
spanId: '456',
1221
traceFlags: 1,
1322
},
14-
// max time reached exactly
15-
startTimestamp: Date.now() / 1000 - PREVIOUS_TRACE_MAX_DURATION,
23+
// max time reached almost exactly
24+
startTimestamp: currentSpanStart - PREVIOUS_TRACE_MAX_DURATION + 1,
1625
};
1726

18-
const startSpanOptions: StartSpanOptions = {
19-
name: '/dashboard',
20-
};
27+
const currentSpan = new SentrySpan({
28+
name: 'test',
29+
startTimestamp: currentSpanStart,
30+
parentSpanId: '789',
31+
spanId: 'abc',
32+
traceId: 'def',
33+
sampled: true,
34+
});
2135

22-
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, startSpanOptions);
36+
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, currentSpan);
2337

24-
expect(updatedPreviousTraceInfo).toBe(previousTraceInfo);
25-
expect(startSpanOptions.links).toEqual([
38+
expect(spanToJSON(currentSpan).links).toEqual([
2639
{
2740
attributes: {
2841
'sentry.link.type': 'previous_trace',
2942
},
30-
context: {
31-
spanId: '456',
32-
traceFlags: 1,
33-
traceId: '123',
34-
},
43+
trace_id: '123',
44+
span_id: '456',
45+
sampled: true,
3546
},
3647
]);
48+
49+
expect(updatedPreviousTraceInfo).toEqual({
50+
spanContext: currentSpan.spanContext(),
51+
startTimestamp: currentSpanStart,
52+
});
53+
});
54+
55+
it(`doesn't add a previous_trace span link if the previous trace was created more than ${PREVIOUS_TRACE_MAX_DURATION}s ago`, () => {
56+
const currentSpanStart = timestampInSeconds();
57+
58+
const previousTraceInfo: PreviousTraceInfo = {
59+
spanContext: {
60+
traceId: '123',
61+
spanId: '456',
62+
traceFlags: 0,
63+
},
64+
startTimestamp: Date.now() / 1000 - PREVIOUS_TRACE_MAX_DURATION - 1,
65+
};
66+
67+
const currentSpan = new SentrySpan({
68+
name: '/dashboard',
69+
startTimestamp: currentSpanStart,
70+
});
71+
72+
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, currentSpan);
73+
74+
expect(spanToJSON(currentSpan).links).toBeUndefined();
75+
76+
// but still updates the previousTraceInfo to the current span
77+
expect(updatedPreviousTraceInfo).toEqual({
78+
spanContext: currentSpan.spanContext(),
79+
startTimestamp: currentSpanStart,
80+
});
3781
});
3882

3983
it("doesn't overwrite previously existing span links", () => {
@@ -46,7 +90,9 @@ describe('addPreviousTraceSpanLink', () => {
4690
startTimestamp: Date.now() / 1000,
4791
};
4892

49-
const startSpanOptions: StartSpanOptions = {
93+
const currentSpanStart = timestampInSeconds();
94+
95+
const currentSpan = new SentrySpan({
5096
name: '/dashboard',
5197
links: [
5298
{
@@ -60,18 +106,16 @@ describe('addPreviousTraceSpanLink', () => {
60106
},
61107
},
62108
],
63-
};
109+
startTimestamp: currentSpanStart,
110+
});
64111

65-
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, startSpanOptions);
112+
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, currentSpan);
66113

67-
expect(updatedPreviousTraceInfo).toBe(previousTraceInfo);
68-
expect(startSpanOptions.links).toEqual([
114+
expect(spanToJSON(currentSpan).links).toEqual([
69115
{
70-
context: {
71-
traceId: '789',
72-
spanId: '101',
73-
traceFlags: 1,
74-
},
116+
trace_id: '789',
117+
span_id: '101',
118+
sampled: true,
75119
attributes: {
76120
someKey: 'someValue',
77121
},
@@ -80,34 +124,103 @@ describe('addPreviousTraceSpanLink', () => {
80124
attributes: {
81125
'sentry.link.type': 'previous_trace',
82126
},
83-
context: {
84-
spanId: '456',
85-
traceFlags: 1,
86-
traceId: '123',
87-
},
127+
trace_id: '123',
128+
span_id: '456',
129+
sampled: true,
88130
},
89131
]);
132+
133+
expect(updatedPreviousTraceInfo).toEqual({
134+
spanContext: currentSpan.spanContext(),
135+
startTimestamp: currentSpanStart,
136+
});
137+
});
138+
139+
it("doesn't add a link and returns the current span's data as previous trace info, if previous trace info was undefined", () => {
140+
const currentSpanStart = timestampInSeconds();
141+
const currentSpan = new SentrySpan({ name: 'test', startTimestamp: currentSpanStart });
142+
143+
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(undefined, currentSpan);
144+
145+
expect(spanToJSON(currentSpan).links).toBeUndefined();
146+
147+
expect(updatedPreviousTraceInfo).toEqual({
148+
spanContext: currentSpan.spanContext(),
149+
startTimestamp: currentSpanStart,
150+
});
90151
});
91152

92-
it(`doesn't add a previous_trace span link if the previous trace was created more than ${PREVIOUS_TRACE_MAX_DURATION}M ago`, () => {
153+
it("doesn't add a link and returns the unchanged previous trace info if the current span is part of the same trace", () => {
154+
const currentSpanStart = timestampInSeconds();
155+
const currentSpan = new SentrySpan({
156+
name: 'test',
157+
startTimestamp: currentSpanStart,
158+
traceId: '123',
159+
spanId: '456',
160+
});
161+
93162
const previousTraceInfo: PreviousTraceInfo = {
94163
spanContext: {
95164
traceId: '123',
96165
spanId: '456',
97-
traceFlags: 0,
166+
traceFlags: 1,
98167
},
99-
startTimestamp: Date.now() / 1000 - PREVIOUS_TRACE_MAX_DURATION - 1,
168+
startTimestamp: currentSpanStart - 1,
100169
};
101170

102-
const startSpanOptions: StartSpanOptions = {
103-
name: '/dashboard',
104-
};
171+
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, currentSpan);
105172

106-
const updatedPreviousTraceInfo = addPreviousTraceSpanLink(previousTraceInfo, startSpanOptions);
173+
expect(spanToJSON(currentSpan).links).toBeUndefined();
107174

108-
expect(updatedPreviousTraceInfo).toBeUndefined();
109-
expect(startSpanOptions.links).toBeUndefined();
175+
expect(updatedPreviousTraceInfo).toBe(previousTraceInfo);
110176
});
111177
});
112178

113-
// TODO: Add tests for sessionstorage helpers
179+
describe('store and retrieve previous trace data via sessionStorage ', () => {
180+
const storage: Record<string, unknown> = {};
181+
const sessionStorageMock = {
182+
setItem: vi.fn((key, value) => {
183+
storage[key] = value;
184+
}),
185+
getItem: vi.fn(key => storage[key]),
186+
};
187+
188+
beforeEach(() => {
189+
vi.clearAllMocks();
190+
// @ts-expect-error - mock contains only necessary API
191+
globalThis.sessionStorage = sessionStorageMock;
192+
});
193+
194+
it('stores the previous trace info in sessionStorage', () => {
195+
const previousTraceInfo: PreviousTraceInfo = {
196+
spanContext: {
197+
traceId: '123',
198+
spanId: '456',
199+
traceFlags: 1,
200+
},
201+
startTimestamp: Date.now() / 1000,
202+
};
203+
204+
storePreviousTraceInSessionStorage(previousTraceInfo);
205+
expect(sessionStorageMock.setItem).toHaveBeenCalledWith(PREVIOUS_TRACE_KEY, JSON.stringify(previousTraceInfo));
206+
expect(getPreviousTraceFromSessionStorage()).toEqual(previousTraceInfo);
207+
});
208+
209+
it("doesn't throw if accessing sessionStorage fails and returns undefined", () => {
210+
// @ts-expect-error - this is fine
211+
globalThis.sessionStorage = undefined;
212+
213+
const previousTraceInfo: PreviousTraceInfo = {
214+
spanContext: {
215+
traceId: '123',
216+
spanId: '456',
217+
traceFlags: 1,
218+
},
219+
startTimestamp: Date.now() / 1000,
220+
};
221+
222+
expect(() => storePreviousTraceInSessionStorage(previousTraceInfo)).not.toThrow();
223+
expect(getPreviousTraceFromSessionStorage).not.toThrow();
224+
expect(getPreviousTraceFromSessionStorage()).toBeUndefined();
225+
});
226+
});

0 commit comments

Comments
 (0)