Skip to content

Commit ead5d91

Browse files
committed
Merge branch 'master' into tkdodo/ref/projectTeams-to-apiOptions
2 parents 0f6b667 + 04eb17a commit ead5d91

File tree

12 files changed

+274
-238
lines changed

12 files changed

+274
-238
lines changed

src/sentry/incidents/endpoints/serializers/workflow_engine_incident.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ def get_attrs(
9393
results[open_period] = {"projects": [open_period.project.slug]}
9494
results[open_period]["alert_rule"] = alert_rules.get(str(alert_rule_id))
9595

96+
igops = IncidentGroupOpenPeriod.objects.filter(group_open_period__in=results.keys())
97+
igop_by_open_period_id = {igop.group_open_period_id: igop for igop in igops}
98+
99+
for open_period in results:
100+
if igop := igop_by_open_period_id.get(open_period.id):
101+
results[open_period]["incident_id"] = igop.incident_id
102+
results[open_period]["incident_identifier"] = igop.incident_identifier
103+
else:
104+
fake_id = get_fake_id_from_object_id(open_period.id)
105+
results[open_period]["incident_id"] = fake_id
106+
results[open_period]["incident_identifier"] = fake_id
107+
96108
if "activities" in self.expand:
97109
gopas = list(
98110
GroupOpenPeriodActivity.objects.filter(group_open_period__in=item_list).order_by(
@@ -169,13 +181,8 @@ def serialize(
169181
"""
170182
Temporary serializer to take a GroupOpenPeriod and serialize it for the old incident endpoint
171183
"""
172-
try:
173-
igop = IncidentGroupOpenPeriod.objects.get(group_open_period=obj)
174-
incident_id = igop.incident_id
175-
incident_identifier = igop.incident_identifier
176-
except IncidentGroupOpenPeriod.DoesNotExist:
177-
incident_id = get_fake_id_from_object_id(obj.id)
178-
incident_identifier = incident_id
184+
incident_id = attrs["incident_id"]
185+
incident_identifier = attrs["incident_identifier"]
179186

180187
date_closed = obj.date_ended.replace(second=0, microsecond=0) if obj.date_ended else None
181188
return {

static/app/constants/index.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -649,9 +649,9 @@ export const DATA_CATEGORY_INFO = {
649649
name: DataCategoryExact.TRACE_METRIC_BYTE,
650650
plural: DataCategory.TRACE_METRIC_BYTE,
651651
singular: 'traceMetricByte',
652-
displayName: 'metric byte',
653-
titleName: t('Metrics (Bytes)'),
654-
productName: t('Metrics'),
652+
displayName: 'application metric byte',
653+
titleName: t('Application Metrics'),
654+
productName: t('Application Metrics'),
655655
uid: 37,
656656
isBilledCategory: true,
657657
statsInfo: {

static/app/views/settings/organizationIntegrations/addIntegration.spec.tsx renamed to static/app/utils/integrations/useAddIntegration.spec.tsx

Lines changed: 66 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import * as indicators from 'sentry/actionCreators/indicator';
88
import * as pipelineModal from 'sentry/components/pipeline/modal';
99
import {ConfigStore} from 'sentry/stores/configStore';
1010
import type {Config} from 'sentry/types/system';
11-
import {useAddIntegration} from 'sentry/views/settings/organizationIntegrations/addIntegration';
11+
import {useAddIntegration} from 'sentry/utils/integrations/useAddIntegration';
1212

1313
describe('useAddIntegration', () => {
1414
const provider = GitHubIntegrationProviderFixture();
@@ -54,16 +54,16 @@ describe('useAddIntegration', () => {
5454
});
5555

5656
it('opens a popup window when startFlow is called', () => {
57-
const {result} = renderHookWithProviders(() =>
58-
useAddIntegration({
57+
const {result} = renderHookWithProviders(() => useAddIntegration());
58+
59+
act(() =>
60+
result.current.startFlow({
5961
provider,
6062
organization: OrganizationFixture(),
6163
onInstall: jest.fn(),
6264
})
6365
);
6466

65-
act(() => result.current.startFlow());
66-
6767
expect(window.open).toHaveBeenCalledTimes(1);
6868
expect(jest.mocked(window.open).mock.calls[0]![0]).toBe(
6969
'/github-integration-setup-uri/?'
@@ -72,8 +72,10 @@ describe('useAddIntegration', () => {
7272
});
7373

7474
it('includes account and modalParams in the popup URL', () => {
75-
const {result} = renderHookWithProviders(() =>
76-
useAddIntegration({
75+
const {result} = renderHookWithProviders(() => useAddIntegration());
76+
77+
act(() =>
78+
result.current.startFlow({
7779
provider,
7880
organization: OrganizationFixture(),
7981
onInstall: jest.fn(),
@@ -82,8 +84,6 @@ describe('useAddIntegration', () => {
8284
})
8385
);
8486

85-
act(() => result.current.startFlow());
86-
8787
const calls = jest.mocked(window.open).mock.calls[0]!;
8888
const url = calls[0] as string;
8989
expect(url).toContain('account=my-account');
@@ -92,33 +92,34 @@ describe('useAddIntegration', () => {
9292
});
9393

9494
it('includes urlParams passed to startFlow', () => {
95-
const {result} = renderHookWithProviders(() =>
96-
useAddIntegration({
95+
const {result} = renderHookWithProviders(() => useAddIntegration());
96+
97+
act(() =>
98+
result.current.startFlow({
9799
provider,
98100
organization: OrganizationFixture(),
99101
onInstall: jest.fn(),
102+
urlParams: {custom_param: 'value'},
100103
})
101104
);
102105

103-
act(() => result.current.startFlow({custom_param: 'value'}));
104-
105106
const url = jest.mocked(window.open).mock.calls[0]![0] as string;
106107
expect(url).toContain('custom_param=value');
107108
});
108109

109110
it('calls onInstall when a success message is received', async () => {
110111
const onInstall = jest.fn();
111112

112-
const {result} = renderHookWithProviders(() =>
113-
useAddIntegration({
113+
const {result} = renderHookWithProviders(() => useAddIntegration());
114+
115+
act(() =>
116+
result.current.startFlow({
114117
provider,
115118
organization: OrganizationFixture(),
116119
onInstall,
117120
})
118121
);
119122

120-
act(() => result.current.startFlow());
121-
122123
const newIntegration = {
123124
success: true,
124125
data: {
@@ -137,50 +138,50 @@ describe('useAddIntegration', () => {
137138
it('shows a success indicator on successful installation', async () => {
138139
const successSpy = jest.spyOn(indicators, 'addSuccessMessage');
139140

140-
const {result} = renderHookWithProviders(() =>
141-
useAddIntegration({
141+
const {result} = renderHookWithProviders(() => useAddIntegration());
142+
143+
act(() =>
144+
result.current.startFlow({
142145
provider,
143146
organization: OrganizationFixture(),
144147
onInstall: jest.fn(),
145148
})
146149
);
147150

148-
act(() => result.current.startFlow());
149-
150151
postMessageFromPopup(popup, {success: true, data: integration});
151152
await waitFor(() => expect(successSpy).toHaveBeenCalledWith('GitHub added'));
152153
});
153154

154155
it('shows an error indicator when the message has success: false', async () => {
155156
const errorSpy = jest.spyOn(indicators, 'addErrorMessage');
156157

157-
const {result} = renderHookWithProviders(() =>
158-
useAddIntegration({
158+
const {result} = renderHookWithProviders(() => useAddIntegration());
159+
160+
act(() =>
161+
result.current.startFlow({
159162
provider,
160163
organization: OrganizationFixture(),
161164
onInstall: jest.fn(),
162165
})
163166
);
164167

165-
act(() => result.current.startFlow());
166-
167168
postMessageFromPopup(popup, {success: false, data: {error: 'OAuth failed'}});
168169
await waitFor(() => expect(errorSpy).toHaveBeenCalledWith('OAuth failed'));
169170
});
170171

171172
it('shows a generic error when no error message is provided', async () => {
172173
const errorSpy = jest.spyOn(indicators, 'addErrorMessage');
173174

174-
const {result} = renderHookWithProviders(() =>
175-
useAddIntegration({
175+
const {result} = renderHookWithProviders(() => useAddIntegration());
176+
177+
act(() =>
178+
result.current.startFlow({
176179
provider,
177180
organization: OrganizationFixture(),
178181
onInstall: jest.fn(),
179182
})
180183
);
181184

182-
act(() => result.current.startFlow());
183-
184185
postMessageFromPopup(popup, {success: false, data: {}});
185186
await waitFor(() =>
186187
expect(errorSpy).toHaveBeenCalledWith('An unknown error occurred')
@@ -190,16 +191,23 @@ describe('useAddIntegration', () => {
190191
it('ignores messages from invalid origins', async () => {
191192
const onInstall = jest.fn();
192193

193-
renderHookWithProviders(() =>
194-
useAddIntegration({
194+
const {result} = renderHookWithProviders(() => useAddIntegration());
195+
196+
act(() =>
197+
result.current.startFlow({
195198
provider,
196199
organization: OrganizationFixture(),
197200
onInstall,
198201
})
199202
);
200203

201-
// jsdom's postMessage uses origin '' which won't match any valid origin
202-
window.postMessage({success: true, data: integration}, '*');
204+
const event = new MessageEvent('message', {
205+
data: {success: true, data: integration},
206+
origin: 'https://invalid.example.com',
207+
});
208+
Object.defineProperty(event, 'source', {value: popup});
209+
210+
window.dispatchEvent(event);
203211

204212
await act(async () => {
205213
await new Promise(resolve => setTimeout(resolve, 50));
@@ -210,16 +218,16 @@ describe('useAddIntegration', () => {
210218
it('does not call onInstall when data is empty on success', async () => {
211219
const onInstall = jest.fn();
212220

213-
const {result} = renderHookWithProviders(() =>
214-
useAddIntegration({
221+
const {result} = renderHookWithProviders(() => useAddIntegration());
222+
223+
act(() =>
224+
result.current.startFlow({
215225
provider,
216226
organization: OrganizationFixture(),
217227
onInstall,
218228
})
219229
);
220230

221-
act(() => result.current.startFlow());
222-
223231
postMessageFromPopup(popup, {success: true, data: null});
224232

225233
await act(async () => {
@@ -229,15 +237,15 @@ describe('useAddIntegration', () => {
229237
});
230238

231239
it('closes the dialog on unmount', () => {
232-
const {result, unmount} = renderHookWithProviders(() =>
233-
useAddIntegration({
240+
const {result, unmount} = renderHookWithProviders(() => useAddIntegration());
241+
242+
act(() =>
243+
result.current.startFlow({
234244
provider,
235245
organization: OrganizationFixture(),
236246
onInstall: jest.fn(),
237247
})
238248
);
239-
240-
act(() => result.current.startFlow());
241249
unmount();
242250

243251
expect(popup.close).toHaveBeenCalledTimes(1);
@@ -253,16 +261,16 @@ describe('useAddIntegration', () => {
253261
features: ['integration-api-pipeline-github'],
254262
});
255263

256-
const {result} = renderHookWithProviders(() =>
257-
useAddIntegration({
264+
const {result} = renderHookWithProviders(() => useAddIntegration());
265+
266+
act(() =>
267+
result.current.startFlow({
258268
provider,
259269
organization,
260270
onInstall,
261271
})
262272
);
263273

264-
act(() => result.current.startFlow());
265-
266274
expect(openPipelineModalSpy).toHaveBeenCalledWith({
267275
type: 'integration',
268276
provider: 'github',
@@ -278,16 +286,17 @@ describe('useAddIntegration', () => {
278286
features: ['integration-api-pipeline-github'],
279287
});
280288

281-
const {result} = renderHookWithProviders(() =>
282-
useAddIntegration({
289+
const {result} = renderHookWithProviders(() => useAddIntegration());
290+
291+
act(() =>
292+
result.current.startFlow({
283293
provider,
284294
organization,
285295
onInstall: jest.fn(),
296+
urlParams: {installation_id: '12345'},
286297
})
287298
);
288299

289-
act(() => result.current.startFlow({installation_id: '12345'}));
290-
291300
expect(openPipelineModalSpy).toHaveBeenCalledWith(
292301
expect.objectContaining({
293302
initialData: {installation_id: '12345'},
@@ -303,16 +312,16 @@ describe('useAddIntegration', () => {
303312
features: ['integration-api-pipeline-github'],
304313
});
305314

306-
const {result} = renderHookWithProviders(() =>
307-
useAddIntegration({
315+
const {result} = renderHookWithProviders(() => useAddIntegration());
316+
317+
act(() =>
318+
result.current.startFlow({
308319
provider,
309320
organization,
310321
onInstall: jest.fn(),
311322
})
312323
);
313324

314-
act(() => result.current.startFlow());
315-
316325
expect(window.open).not.toHaveBeenCalled();
317326
});
318327

@@ -324,16 +333,16 @@ describe('useAddIntegration', () => {
324333

325334
const organization = OrganizationFixture({features: []});
326335

327-
const {result} = renderHookWithProviders(() =>
328-
useAddIntegration({
336+
const {result} = renderHookWithProviders(() => useAddIntegration());
337+
338+
act(() =>
339+
result.current.startFlow({
329340
provider,
330341
organization,
331342
onInstall: jest.fn(),
332343
})
333344
);
334345

335-
act(() => result.current.startFlow());
336-
337346
expect(openPipelineModalSpy).not.toHaveBeenCalled();
338347
expect(window.open).toHaveBeenCalledTimes(1);
339348
});

0 commit comments

Comments
 (0)