import {ProjectKeysFixture} from 'sentry-fixture/projectKeys'; import {initializeOrg} from 'sentry-test/initializeOrg'; import { render, screen, userEvent, waitForElementToBeRemoved, } from 'sentry-test/reactTestingLibrary'; import {t} from 'sentry/locale'; import type {Organization} from 'sentry/types/organization'; import type {Project, ProjectKey} from 'sentry/types/project'; import LoaderScript from 'sentry/views/settings/project/loaderScript'; function mockApi({ organization, project, projectKeys, }: { organization: Organization; project: Project; projectKeys: ProjectKey[]; }) { MockApiClient.clearMockResponses(); MockApiClient.addMockResponse({ url: `/projects/${organization.slug}/${project.slug}/keys/`, method: 'GET', body: projectKeys, }); } describe('LoaderScript', function () { it('renders error', async function () { const {organization, project} = initializeOrg(); MockApiClient.clearMockResponses(); MockApiClient.addMockResponse({ url: `/projects/${organization.slug}/${project.slug}/keys/`, method: 'GET', statusCode: 400, }); render(); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); expect(screen.getByTestId('loading-error')).toHaveTextContent( 'Failed to load project keys.' ); }); it('renders empty', async function () { const {organization, project} = initializeOrg(); mockApi({organization, project, projectKeys: []}); render(); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); expect( screen.getByText('There are no keys active for this project.') ).toBeInTheDocument(); }); it('renders for single project', async function () { const {organization, project} = initializeOrg(); const projectKey = ProjectKeysFixture()[0]; const projectKeys = [projectKey]; mockApi({organization, project, projectKeys}); render(); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); // Loader Script is rendered expect(screen.getByText(`Client Key: ${projectKey.name}`)).toBeInTheDocument(); const loaderScript = screen.getByRole('textbox', { name: 'Loader Script', }) as HTMLInputElement; const loaderScriptValue = loaderScript.value; expect(loaderScriptValue).toEqual(expect.stringContaining(projectKeys[0].dsn.cdn)); }); it('renders multiple keys', async function () { const {organization, project} = initializeOrg(); const projectKeys = ProjectKeysFixture([ { dsn: { secret: 'http://188ee45a58094d939428d8585aa6f662:a33bf9aba64c4bbdaf873bb9023b6d2c@dev.getsentry.net:8000/1', minidump: 'http://dev.getsentry.net:8000/api/1/minidump?sentry_key=188ee45a58094d939428d8585aa6f662', public: 'http://188ee45a58094d939428d8585aa6f662@dev.getsentry.net:8000/1', cdn: 'http://dev.getsentry.net:8000/js-sdk-loader/188ee45a58094d939428d8585aa6f662.min.js', csp: 'http://dev.getsentry.net:8000/api/1/csp-report/?sentry_key=188ee45a58094d939428d8585aa6f662', security: 'http://dev.getsentry.net:8000/api/1/security-report/?sentry_key=188ee45a58094d939428d8585aa6f662', unreal: '', crons: '', }, public: '188ee45a58094d939428d8585aa6f662', secret: 'a33bf9aba64c4bbdaf873bb9023b6d2c', name: 'Key 2', rateLimit: null, projectId: 1, dateCreated: '2018-02-28T07:13:51.087Z', id: '188ee45a58094d939428d8585aa6f662', isActive: true, label: 'Key 2', browserSdkVersion: 'latest', browserSdk: { choices: [ ['latest', 'latest'], ['7.x', '7.x'], ['6.x', '6.x'], ['5.x', '5.x'], ['4.x', '4.x'], ], }, dynamicSdkLoaderOptions: { hasPerformance: false, hasReplay: false, hasDebug: false, }, }, ]); mockApi({organization, project, projectKeys}); render(); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); expect(screen.getByText(`Client Key: ${projectKeys[0].name}`)).toBeInTheDocument(); expect(screen.getByText(`Client Key: ${projectKeys[1].name}`)).toBeInTheDocument(); const allLoaderScripts = screen.getAllByRole('textbox', { name: 'Loader Script', }) as HTMLInputElement[]; expect(allLoaderScripts).toHaveLength(2); }); it('allows to update key settings', async function () { const {organization, project} = initializeOrg(); const baseKey = ProjectKeysFixture()[0]; const projectKey = { ...baseKey, dynamicSdkLoaderOptions: { ...baseKey.dynamicSdkLoaderOptions, hasReplay: true, }, }; mockApi({organization, project, projectKeys: [projectKey]}); const mockPut = MockApiClient.addMockResponse({ url: `/projects/${organization.slug}/${project.slug}/keys/${projectKey.id}/`, method: 'PUT', body: { ...projectKey, dynamicSdkLoaderOptions: { ...projectKey.dynamicSdkLoaderOptions, hasPerformance: true, }, }, }); render(); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); expect(screen.getByText(t('Enable Performance Monitoring'))).toBeInTheDocument(); expect(screen.getByText(t('Enable Session Replay'))).toBeInTheDocument(); expect(screen.getByText(t('Enable Debug Bundles & Logging'))).toBeInTheDocument(); let performanceCheckbox = screen.getByRole('checkbox', { name: t('Enable Performance Monitoring'), }); expect(performanceCheckbox).toBeEnabled(); expect(performanceCheckbox).not.toBeChecked(); const replayCheckbox = screen.getByRole('checkbox', { name: t('Enable Session Replay'), }); expect(replayCheckbox).toBeEnabled(); expect(replayCheckbox).toBeChecked(); const debugCheckbox = screen.getByRole('checkbox', { name: t('Enable Debug Bundles & Logging'), }); expect(debugCheckbox).toBeEnabled(); expect(debugCheckbox).not.toBeChecked(); // Toggle performance option await userEvent.click( screen.getByRole('checkbox', { name: t('Enable Performance Monitoring'), }) ); performanceCheckbox = await screen.findByRole('checkbox', { name: t('Enable Performance Monitoring'), checked: true, }); expect(performanceCheckbox).toBeEnabled(); expect(performanceCheckbox).toBeChecked(); expect(mockPut).toHaveBeenCalledWith( `/projects/${organization.slug}/${project.slug}/keys/${projectKey.id}/`, expect.objectContaining({ data: expect.objectContaining({ dynamicSdkLoaderOptions: { ...projectKey.dynamicSdkLoaderOptions, hasPerformance: true, }, }), }) ); }); it('allows to update one of multiple keys', async function () { const {organization, project} = initializeOrg(); const projectKeys = ProjectKeysFixture([ { dsn: { secret: 'http://188ee45a58094d939428d8585aa6f662:a33bf9aba64c4bbdaf873bb9023b6d2c@dev.getsentry.net:8000/1', minidump: 'http://dev.getsentry.net:8000/api/1/minidump?sentry_key=188ee45a58094d939428d8585aa6f662', public: 'http://188ee45a58094d939428d8585aa6f662@dev.getsentry.net:8000/1', cdn: 'http://dev.getsentry.net:8000/js-sdk-loader/188ee45a58094d939428d8585aa6f662.min.js', csp: 'http://dev.getsentry.net:8000/api/1/csp-report/?sentry_key=188ee45a58094d939428d8585aa6f662', security: 'http://dev.getsentry.net:8000/api/1/security-report/?sentry_key=188ee45a58094d939428d8585aa6f662', unreal: '', crons: '', }, public: '188ee45a58094d939428d8585aa6f662', secret: 'a33bf9aba64c4bbdaf873bb9023b6d2c', name: 'Key 2', rateLimit: null, projectId: 1, dateCreated: '2018-02-28T07:13:51.087Z', id: '188ee45a58094d939428d8585aa6f662', isActive: true, label: 'Key 2', browserSdkVersion: 'latest', browserSdk: { choices: [ ['latest', 'latest'], ['7.x', '7.x'], ['6.x', '6.x'], ['5.x', '5.x'], ['4.x', '4.x'], ], }, dynamicSdkLoaderOptions: { hasPerformance: false, hasReplay: false, hasDebug: false, }, }, ]); const projectKey = projectKeys[1]; mockApi({organization, project, projectKeys}); const mockPut = MockApiClient.addMockResponse({ url: `/projects/${organization.slug}/${project.slug}/keys/${projectKey.id}/`, method: 'PUT', body: { ...projectKey, dynamicSdkLoaderOptions: { ...projectKey.dynamicSdkLoaderOptions, hasPerformance: true, }, }, }); render(); await waitForElementToBeRemoved(() => screen.queryByTestId('loading-indicator')); expect( screen.getAllByRole('checkbox', { name: t('Enable Performance Monitoring'), checked: false, }) ).toHaveLength(2); expect( screen.getAllByRole('checkbox', { name: t('Enable Session Replay'), checked: false, }) ).toHaveLength(2); expect( screen.getAllByRole('checkbox', { name: t('Enable Debug Bundles & Logging'), checked: false, }) ).toHaveLength(2); // Toggle performance option await userEvent.click( screen.getAllByRole('checkbox', { name: t('Enable Performance Monitoring'), })[1] ); expect( await screen.findByRole('checkbox', { name: t('Enable Performance Monitoring'), checked: true, }) ).toBeInTheDocument(); expect( screen.getByRole('checkbox', { name: t('Enable Performance Monitoring'), checked: false, }) ).toBeInTheDocument(); expect( screen.getAllByRole('checkbox', { name: t('Enable Session Replay'), checked: false, }) ).toHaveLength(2); expect( screen.getAllByRole('checkbox', { name: t('Enable Debug Bundles & Logging'), checked: false, }) ).toHaveLength(2); expect(mockPut).toHaveBeenCalledWith( `/projects/${organization.slug}/${project.slug}/keys/${projectKey.id}/`, expect.objectContaining({ data: expect.objectContaining({ dynamicSdkLoaderOptions: { ...projectKey.dynamicSdkLoaderOptions, hasPerformance: true, }, }), }) ); }); });