Skip to content

Commit 0c64476

Browse files
authored
test(ui): Prepare for jest 30 (#94724)
Pulls just the testable window location changes out for Jest 30 #93303 window.location in the next version of jsdom is not configurable and cannot be changed via assignment. By using testableWindowLocation we can mock the entire module and do whatever we want instead of trying to overwrite the jsdom globals
1 parent a2664bf commit 0c64476

File tree

62 files changed

+245
-158
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+245
-158
lines changed

static/app/actionCreators/account.spec.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {waitFor} from 'sentry-test/reactTestingLibrary';
22

3+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
4+
35
import {logout} from './account';
46

57
describe('logout', () => {
@@ -13,6 +15,6 @@ describe('logout', () => {
1315
logout(mockApi);
1416

1517
await waitFor(() => expect(mockApiDelete).toHaveBeenCalled());
16-
expect(window.location.assign).toHaveBeenCalledWith('/auth/login/');
18+
expect(testableWindowLocation.assign).toHaveBeenCalledWith('/auth/login/');
1719
});
1820
});

static/app/actionCreators/account.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import ConfigStore from 'sentry/stores/configStore';
44
import type {UserIdentityConfig} from 'sentry/types/auth';
55
import type {User} from 'sentry/types/user';
66
import {isDemoModeActive} from 'sentry/utils/demoMode';
7+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
78
import type {ChangeAvatarUser} from 'sentry/views/settings/account/accountDetails';
89

910
export async function disconnectIdentity(
@@ -51,7 +52,7 @@ export async function logout(api: Client, redirectUrl?: string) {
5152
const data = await api.requestPromise('/auth/', {method: 'DELETE'});
5253

5354
// If there's a URL for SAML Single-logout, redirect back to IdP
54-
window.location.assign(data?.sloUrl || getRedirectUrl(redirectUrl));
55+
testableWindowLocation.assign(data?.sloUrl || getRedirectUrl(redirectUrl));
5556
}
5657

5758
function getRedirectUrl(redirectUrl = '/auth/login/') {

static/app/actionCreators/organizations.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {OrganizationFixture} from 'sentry-fixture/organization';
22

33
import {fetchOrganizations} from 'sentry/actionCreators/organizations';
44
import ConfigStore from 'sentry/stores/configStore';
5+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
56

67
describe('fetchOrganizations', function () {
78
const api = new MockApiClient();
@@ -74,6 +75,6 @@ describe('fetchOrganizations', function () {
7475
expect(organizations[0].slug).toEqual(usorg.slug);
7576
expect(usMock).toHaveBeenCalledTimes(1);
7677
expect(deMock).toHaveBeenCalledTimes(1);
77-
expect(window.location.reload).not.toHaveBeenCalled();
78+
expect(testableWindowLocation.reload).not.toHaveBeenCalled();
7879
});
7980
});

static/app/api.spec.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import {OrganizationFixture} from 'sentry-fixture/organization';
22

3+
import {setWindowLocation} from 'sentry-test/utils';
4+
35
import type {Client, ResponseMeta} from 'sentry/api';
46
import {isSimilarOrigin, Request, resolveHostname} from 'sentry/api';
57
import {PROJECT_MOVED} from 'sentry/constants/apiErrorCodes';
@@ -14,6 +16,7 @@ describe('api', function () {
1416

1517
beforeEach(function () {
1618
api = new MockApiClient();
19+
setWindowLocation('https://sentry.io/');
1720
});
1821

1922
describe('Client', function () {
@@ -143,11 +146,7 @@ describe('resolveHostname', function () {
143146
});
144147

145148
it('does not override region in _admin', function () {
146-
Object.defineProperty(window, 'location', {
147-
configurable: true,
148-
enumerable: true,
149-
value: new URL('https://sentry.io/_admin/'),
150-
});
149+
setWindowLocation('https://sentry.io/_admin/');
151150

152151
// Adds domain to control paths
153152
let result = resolveHostname(controlPath);
@@ -166,6 +165,7 @@ describe('resolveHostname', function () {
166165
});
167166

168167
it('adds domains when feature enabled', function () {
168+
setWindowLocation('https://us.sentry.io/');
169169
let result = resolveHostname(regionPath);
170170
expect(result).toBe('https://us.sentry.io/api/0/organizations/slug/issues/');
171171

static/app/components/modals/redirectToProject.spec.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {act, renderGlobalModal} from 'sentry-test/reactTestingLibrary';
33

44
import {openModal} from 'sentry/actionCreators/modal';
55
import {RedirectToProjectModal} from 'sentry/components/modals/redirectToProject';
6+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
67

78
jest.unmock('sentry/utils/recreateRoute');
89

@@ -29,10 +30,10 @@ describe('RedirectToProjectModal', function () {
2930
);
3031

3132
act(() => jest.advanceTimersByTime(4900));
32-
expect(window.location.assign).not.toHaveBeenCalled();
33+
expect(testableWindowLocation.assign).not.toHaveBeenCalled();
3334

3435
act(() => jest.advanceTimersByTime(200));
35-
expect(window.location.assign).toHaveBeenCalledTimes(1);
36-
expect(window.location.assign).toHaveBeenCalledWith('/org-slug/new-slug/');
36+
expect(testableWindowLocation.assign).toHaveBeenCalledTimes(1);
37+
expect(testableWindowLocation.assign).toHaveBeenCalledWith('/org-slug/new-slug/');
3738
});
3839
});

static/app/components/modals/redirectToProject.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Text from 'sentry/components/text';
77
import {t, tct} from 'sentry/locale';
88
import type {WithRouterProps} from 'sentry/types/legacyReactRouter';
99
import recreateRoute from 'sentry/utils/recreateRoute';
10+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
1011
// eslint-disable-next-line no-restricted-imports
1112
import withSentryRouter from 'sentry/utils/withSentryRouter';
1213

@@ -27,7 +28,7 @@ class RedirectToProjectModal extends Component<Props, State> {
2728
componentDidMount() {
2829
this.redirectInterval = window.setInterval(() => {
2930
if (this.state.timer <= 1) {
30-
window.location.assign(this.newPath);
31+
testableWindowLocation.assign(this.newPath);
3132
return;
3233
}
3334

static/app/components/modals/reprocessEventModal.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ModalFooter,
1212
} from 'sentry/components/globalModal/components';
1313
import {ReprocessingEventModal} from 'sentry/components/modals/reprocessEventModal';
14+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
1415

1516
const group = GroupFixture({
1617
id: '1337',
@@ -104,7 +105,7 @@ describe('ReprocessEventModal', function () {
104105

105106
await userEvent.click(screen.getByRole('button', {name: 'Reprocess Events'}));
106107

107-
await waitFor(() => expect(window.location.reload).toHaveBeenCalled());
108+
await waitFor(() => expect(testableWindowLocation.reload).toHaveBeenCalled());
108109
expect(handleCloseModal).toHaveBeenCalled();
109110
});
110111
});

static/app/components/modals/reprocessEventModal.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {t, tct} from 'sentry/locale';
1313
import {space} from 'sentry/styles/space';
1414
import type {Group} from 'sentry/types/group';
1515
import type {Organization} from 'sentry/types/organization';
16+
import {testableWindowLocation} from 'sentry/utils/testableWindowLocation';
1617

1718
export type ReprocessEventModalOptions = {
1819
groupId: Group['id'];
@@ -30,7 +31,7 @@ export function ReprocessingEventModal({
3031

3132
function handleSuccess() {
3233
closeModal();
33-
window.location.reload();
34+
testableWindowLocation.reload();
3435
}
3536

3637
return (

static/app/components/profiling/flamegraph/flamegraph.spec.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {ProjectFixture} from 'sentry-fixture/project';
22

33
import {initializeOrg} from 'sentry-test/initializeOrg';
44
import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
5+
import {setWindowLocation} from 'sentry-test/utils';
56

67
import ProjectsStore from 'sentry/stores/projectsStore';
78
import {FlamegraphRendererDOM as mockFlameGraphRenderer} from 'sentry/utils/profiling/renderers/testUtils';
@@ -109,6 +110,7 @@ describe('Flamegraph', function () {
109110
beforeEach(() => {
110111
const project = ProjectFixture({slug: 'foo-project'});
111112
act(() => void ProjectsStore.loadInitialData([project]));
113+
setWindowLocation('http://localhost/');
112114
});
113115
it('renders a missing profile', async function () {
114116
MockApiClient.addMockResponse({
@@ -185,8 +187,9 @@ describe('Flamegraph', function () {
185187
eventId: 'profile-id',
186188
});
187189

188-
window.location.search =
189-
'?colorCoding=by+library&query=&sorting=alphabetical&tid=0&view=bottom+up';
190+
setWindowLocation(
191+
'http://localhost/?colorCoding=by+library&query=&sorting=alphabetical&tid=0&view=bottom+up'
192+
);
190193

191194
render(
192195
<ProfilesAndTransactionProvider>
@@ -222,7 +225,7 @@ describe('Flamegraph', function () {
222225
eventId: 'profile-id',
223226
});
224227

225-
window.location.search = '?query=profiling+transaction';
228+
setWindowLocation('http://localhost/?query=profiling+transaction');
226229

227230
render(
228231
<ProfilesAndTransactionProvider>

static/app/components/sidebar/sidebarAccordion.spec.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import {render, screen} from 'sentry-test/reactTestingLibrary';
2+
import {setWindowLocation} from 'sentry-test/utils';
23

34
import {SidebarAccordion} from 'sentry/components/sidebar/sidebarAccordion';
45
import SidebarItem from 'sentry/components/sidebar/sidebarItem';
56
import {IconStar} from 'sentry/icons';
67

78
describe('SidebarAccordion', function () {
89
it('marks only the selected child as active', function () {
9-
window.location.pathname = '/performance/queries?sort=tpm()';
10+
setWindowLocation('http://localhost/performance/queries?sort=tpm()');
1011

1112
render(
1213
<SidebarAccordion

0 commit comments

Comments
 (0)