import {RouteComponentProps} from 'react-router'; import * as Sentry from '@sentry/react'; import {initializeOrg} from 'sentry-test/initializeOrg'; import {render, screen} from 'sentry-test/reactTestingLibrary'; import withDomainRedirect from 'sentry/utils/withDomainRedirect'; import {OrganizationContext} from 'sentry/views/organizationContext'; jest.unmock('sentry/utils/recreateRoute'); const originalLocation = window.location; // /settings/:orgId/:projectId/(searches/:searchId/)alerts/ const projectRoutes = [ {path: '/', childRoutes: []}, {childRoutes: []}, {path: '/settings/', name: 'Settings', indexRoute: {}, childRoutes: []}, {name: 'Organizations', path: ':orgId/', childRoutes: []}, {name: 'Projects', path: ':projectId/(searches/:searchId/)', childRoutes: []}, {name: 'Alerts', path: 'alerts/'}, ]; describe('withDomainRedirect', function () { type Props = RouteComponentProps<{orgId: string}, {}>; const MyComponent = (props: Props) => { const {params} = props; return
Org slug: {params.orgId ?? 'no org slug'}
; }; let spyWithScope; beforeEach(function () { spyWithScope = jest.spyOn(Sentry, 'withScope').mockImplementation(() => {}); Object.defineProperty(window, 'location', { writable: true, value: { replace: jest.fn(), pathname: '/organizations/albertos-apples/issues/', search: '?q=123', hash: '#hash', }, }); window.__initialData = { customerDomain: { subdomain: 'albertos-apples', organizationUrl: 'https://albertos-apples.sentry.io', sentryUrl: 'https://sentry.io', }, links: { organizationUrl: null, regionUrl: null, sentryUrl: 'https://sentry.io', }, } as any; }); afterEach(function () { jest.resetAllMocks(); window.location = originalLocation; }); it('renders MyComponent in non-customer domain world', function () { window.__initialData = { customerDomain: null, links: { organizationUrl: null, regionUrl: null, sentryUrl: 'https://sentry.io', }, } as any; const params = { orgId: 'albertos-apples', }; const {router, route, routerContext} = initializeOrg({ ...initializeOrg(), router: { params, }, }); const WrappedComponent = withDomainRedirect(MyComponent); render( , {context: routerContext} ); expect(screen.getByText('Org slug: albertos-apples')).toBeInTheDocument(); }); it('redirects to sentryUrl on org slug mistmatch', function () { const organization = TestStubs.Organization({ slug: 'bobs-bagels', features: ['customer-domains'], }); const params = { orgId: 'albertos-apples', }; const {router, route, routerContext} = initializeOrg({ ...initializeOrg(), organization, router: { params, }, }); const WrappedComponent = withDomainRedirect(MyComponent); const {container} = render( , {context: routerContext} ); expect(container).toBeEmptyDOMElement(); expect(window.location.replace).toHaveBeenCalledTimes(1); expect(window.location.replace).toHaveBeenCalledWith( 'https://sentry.io/organizations/albertos-apples/issues/?q=123#hash' ); expect(spyWithScope).not.toHaveBeenCalled(); }); it('redirects to sentryUrl on missing customer domain feature', function () { const organization = TestStubs.Organization({slug: 'albertos-apples', features: []}); const params = { orgId: organization.slug, }; const {router, route, routerContext} = initializeOrg({ ...initializeOrg(), organization, router: { params, }, }); const WrappedComponent = withDomainRedirect(MyComponent); const {container} = render( , {context: routerContext} ); expect(container).toBeEmptyDOMElement(); expect(window.location.replace).toHaveBeenCalledTimes(1); expect(window.location.replace).toHaveBeenCalledWith( 'https://sentry.io/organizations/albertos-apples/issues/?q=123#hash' ); expect(spyWithScope).not.toHaveBeenCalled(); }); it('redirect when :orgId is present in the routes', function () { const organization = TestStubs.Organization({ slug: 'albertos-apples', features: ['customer-domains'], }); const params = { orgId: organization.slug, projectId: 'react', }; const {router, route, routerContext} = initializeOrg({ ...initializeOrg(), organization, router: { params, routes: projectRoutes, }, }); const WrappedComponent = withDomainRedirect(MyComponent); const {container} = render( , {context: routerContext} ); expect(container).toBeEmptyDOMElement(); expect(router.replace).toHaveBeenCalledTimes(1); expect(router.replace).toHaveBeenCalledWith('/settings/react/alerts/?q=123#hash'); expect(spyWithScope).toHaveBeenCalledTimes(1); }); it('does not redirect when :orgId is not present in the routes', function () { const organization = TestStubs.Organization({ slug: 'albertos-apples', features: ['customer-domains'], }); const params = {}; const {router, route, routerContext} = initializeOrg({ ...initializeOrg(), organization, router: { params, // /settings/account/notifications/reports/ routes: [ {path: '/', childRoutes: []}, {childRoutes: []}, {path: '/settings/', name: 'Settings', indexRoute: {}, childRoutes: []}, {name: 'Account', path: 'account/', childRoutes: []}, {name: 'Notifications', path: 'notifications/', childRoutes: []}, {name: 'Reports', path: 'reports/'}, ], }, }); const WrappedComponent = withDomainRedirect(MyComponent); render( , {context: routerContext} ); expect(screen.getByText('Org slug: no org slug')).toBeInTheDocument(); expect(router.replace).not.toHaveBeenCalled(); expect(spyWithScope).not.toHaveBeenCalled(); }); });