123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- import {
- ReplayRequestFrameFixture,
- ReplayResourceFrameFixture,
- } from 'sentry-fixture/replay/replaySpanFrameData';
- import {ReplayRecordFixture} from 'sentry-fixture/replayRecord';
- import {render, screen} from 'sentry-test/reactTestingLibrary';
- import hydrateSpans from 'sentry/utils/replays/hydrateSpans';
- import useProjectSdkNeedsUpdate from 'sentry/utils/useProjectSdkNeedsUpdate';
- import NetworkDetailsContent from 'sentry/views/replays/detail/network/details/content';
- import type {TabKey} from 'sentry/views/replays/detail/network/details/tabs';
- jest.mock('sentry/utils/useProjectSdkNeedsUpdate');
- function mockNeedsUpdate(needsUpdate: boolean) {
- jest
- .mocked(useProjectSdkNeedsUpdate)
- .mockReturnValue({isError: false, isFetching: false, needsUpdate});
- }
- const [
- img,
- fetchNoDataObj,
- fetchUrlSkipped,
- fetchBodySkipped,
- fetchWithHeaders,
- fetchWithRespBody,
- ] = hydrateSpans(ReplayRecordFixture(), [
- ReplayResourceFrameFixture({
- op: 'resource.img',
- startTimestamp: new Date(),
- endTimestamp: new Date(),
- description: '/static/img/logo.png',
- }),
- ReplayRequestFrameFixture({
- op: 'resource.fetch',
- startTimestamp: new Date(),
- endTimestamp: new Date(),
- description: '/api/0/issues/1234',
- }),
- ReplayRequestFrameFixture({
- op: 'resource.fetch',
- startTimestamp: new Date(),
- endTimestamp: new Date(),
- description: '/api/0/issues/1234',
- data: {
- method: 'GET',
- statusCode: 200,
- request: {_meta: {warnings: ['URL_SKIPPED']}, headers: {}},
- response: {_meta: {warnings: ['URL_SKIPPED']}, headers: {}},
- },
- }),
- ReplayRequestFrameFixture({
- op: 'resource.fetch',
- startTimestamp: new Date(),
- endTimestamp: new Date(),
- description: '/api/0/issues/1234',
- data: {
- method: 'GET',
- statusCode: 200,
- request: {
- // @ts-expect-error
- _meta: {warnings: ['BODY_SKIPPED']},
- headers: {accept: 'application/json'},
- },
- response: {
- // @ts-expect-error
- _meta: {warnings: ['BODY_SKIPPED']},
- headers: {'content-type': 'application/json'},
- },
- },
- }),
- ReplayRequestFrameFixture({
- op: 'resource.fetch',
- startTimestamp: new Date(),
- endTimestamp: new Date(),
- description: '/api/0/issues/1234',
- data: {
- method: 'GET',
- statusCode: 200,
- request: {
- _meta: {},
- headers: {accept: 'application/json'},
- },
- response: {
- _meta: {},
- headers: {'content-type': 'application/json'},
- },
- },
- }),
- ReplayRequestFrameFixture({
- op: 'resource.fetch',
- startTimestamp: new Date(),
- endTimestamp: new Date(),
- description: '/api/0/issues/1234',
- data: {
- method: 'GET',
- statusCode: 200,
- request: {
- _meta: {},
- headers: {accept: 'application/json'},
- },
- response: {
- _meta: {},
- headers: {'content-type': 'application/json'},
- body: {success: true},
- },
- },
- }),
- ]);
- const mockItems = {
- img,
- fetchNoDataObj,
- fetchUrlSkipped,
- fetchBodySkipped,
- fetchWithHeaders,
- fetchWithRespBody,
- };
- function basicSectionProps() {
- return {
- projectId: '',
- startTimestampMs: new Date('2023-12-24').getTime(),
- };
- }
- function queryScreenState() {
- return {
- dataSectionHeaders: screen
- .queryAllByLabelText('toggle section')
- .map(elem => elem.textContent),
- isShowingSetup: Boolean(screen.queryByTestId('network-setup-steps')),
- isShowingUnsupported: Boolean(screen.queryByTestId('network-op-unsupported')),
- };
- }
- describe('NetworkDetailsContent', () => {
- mockNeedsUpdate(false);
- describe('Details Tab', () => {
- const visibleTab = 'details' as TabKey;
- describe('Unsupported Operation', () => {
- it.each([
- {isSetup: false, itemName: 'img'},
- {isSetup: true, itemName: 'img'},
- ])(
- 'should render the `general` & `unsupported` sections when the span is not FETCH or XHR and isSetup=$isSetup. [$itemName]',
- ({isSetup}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems.img}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['General'],
- isShowingSetup: false,
- isShowingUnsupported: true,
- });
- }
- );
- });
- describe('Supported Operation', () => {
- it.each([
- {isSetup: false, itemName: 'fetchNoDataObj'},
- {isSetup: false, itemName: 'fetchUrlSkipped'},
- {isSetup: false, itemName: 'fetchBodySkipped'},
- {isSetup: false, itemName: 'fetchWithHeaders'},
- {isSetup: false, itemName: 'fetchWithRespBody'},
- ])(
- 'should render the `general` & `setup` sections when isSetup=false, no matter the item. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['General'],
- isShowingSetup: true,
- isShowingUnsupported: false,
- });
- }
- );
- it.each([
- {isSetup: true, itemName: 'fetchNoDataObj'},
- {isSetup: true, itemName: 'fetchUrlSkipped'},
- ])(
- 'should render the `general` & `setup` sections when the item has no data. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['General'],
- isShowingSetup: true,
- isShowingUnsupported: false,
- });
- }
- );
- it.each([
- {isSetup: true, itemName: 'fetchBodySkipped'},
- {isSetup: true, itemName: 'fetchWithHeaders'},
- {isSetup: true, itemName: 'fetchWithRespBody'},
- ])(
- 'should render the `general` & two `headers` sections, and always the setup section, when things are setup and the item has some data. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['General', 'Request Headers', 'Response Headers'],
- isShowingUnsupported: false,
- isShowingSetup: true,
- });
- }
- );
- });
- });
- describe('Request Tab', () => {
- const visibleTab = 'request' as TabKey;
- describe('Unsupported Operation', () => {
- it.each([
- {isSetup: false, itemName: 'img'},
- {isSetup: true, itemName: 'img'},
- ])(
- 'should render the `query params` & `unsupported` sections when the span is not FETCH or XHR and isSetup=$isSetup. [$itemName]',
- ({isSetup}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems.img}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['Query String Parameters'],
- isShowingSetup: false,
- isShowingUnsupported: true,
- });
- }
- );
- });
- describe('Supported Operation', () => {
- it.each([
- {isSetup: false, itemName: 'fetchNoDataObj'},
- {isSetup: false, itemName: 'fetchUrlSkipped'},
- {isSetup: false, itemName: 'fetchBodySkipped'},
- {isSetup: false, itemName: 'fetchWithHeaders'},
- {isSetup: false, itemName: 'fetchWithRespBody'},
- ])(
- 'should render the `query params` & `setup` sections when isSetup is false, no matter the item. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['Query String Parameters'],
- isShowingSetup: true,
- isShowingUnsupported: false,
- });
- }
- );
- it.each([
- {isSetup: true, itemName: 'fetchNoDataObj'},
- {isSetup: true, itemName: 'fetchUrlSkipped'},
- {isSetup: true, itemName: 'fetchBodySkipped'},
- {isSetup: true, itemName: 'fetchWithHeaders'},
- ])(
- 'should render the `query params` & `setup` sections when the item has no data. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['Query String Parameters'],
- isShowingSetup: true,
- isShowingUnsupported: false,
- });
- }
- );
- it.each([{isSetup: true, itemName: 'fetchWithRespBody'}])(
- 'should render the `query params` & `request payload` sections when things are setup and the item has some data. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['Query String Parameters', 'Request BodySize: 0 B'],
- isShowingUnsupported: false,
- isShowingSetup: false,
- });
- }
- );
- });
- });
- describe('Response Tab', () => {
- const visibleTab = 'response' as TabKey;
- describe('Unsupported Operation', () => {
- it.each([
- {isSetup: false, itemName: 'img'},
- {isSetup: true, itemName: 'img'},
- ])(
- 'should render the `unsupported` section when the span is not FETCH or XHR and isSetup=$isSetup. [$itemName]',
- ({isSetup}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems.img}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: [],
- isShowingSetup: false,
- isShowingUnsupported: true,
- });
- }
- );
- });
- describe('Supported Operation', () => {
- it.each([
- {isSetup: false, itemName: 'fetchNoDataObj'},
- {isSetup: false, itemName: 'fetchUrlSkipped'},
- {isSetup: false, itemName: 'fetchBodySkipped'},
- {isSetup: false, itemName: 'fetchWithHeaders'},
- {isSetup: false, itemName: 'fetchWithRespBody'},
- ])(
- 'should render the `setup` section when isSetup is false, no matter the item. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: [],
- isShowingSetup: true,
- isShowingUnsupported: false,
- });
- }
- );
- it.each([
- {isSetup: true, itemName: 'fetchNoDataObj'},
- {isSetup: true, itemName: 'fetchUrlSkipped'},
- {isSetup: true, itemName: 'fetchBodySkipped'},
- {isSetup: true, itemName: 'fetchWithHeaders'},
- ])(
- 'should render the `setup` section when the item has no data. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: [],
- isShowingSetup: true,
- isShowingUnsupported: false,
- });
- }
- );
- it.each([{isSetup: true, itemName: 'fetchWithRespBody'}])(
- 'should render the `response body` section when things are setup and the item has some data. [$itemName]',
- ({isSetup, itemName}) => {
- render(
- <NetworkDetailsContent
- {...basicSectionProps()}
- isSetup={isSetup}
- item={mockItems[itemName]}
- visibleTab={visibleTab}
- />
- );
- expect(queryScreenState()).toStrictEqual({
- dataSectionHeaders: ['Response BodySize: 0 B'],
- isShowingUnsupported: false,
- isShowingSetup: false,
- });
- }
- );
- });
- });
- });
|