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();
});
});