1
1
import { ConfigFixture } from 'sentry-fixture/config' ;
2
2
import { EnvironmentsFixture } from 'sentry-fixture/environments' ;
3
3
import { EventFixture } from 'sentry-fixture/event' ;
4
+ import { EventsStatsFixture } from 'sentry-fixture/events' ;
4
5
import { GroupFixture } from 'sentry-fixture/group' ;
5
6
import { LocationFixture } from 'sentry-fixture/locationFixture' ;
6
7
import { ProjectFixture } from 'sentry-fixture/project' ;
@@ -16,12 +17,18 @@ import OrganizationStore from 'sentry/stores/organizationStore';
16
17
import PageFiltersStore from 'sentry/stores/pageFiltersStore' ;
17
18
import ProjectsStore from 'sentry/stores/projectsStore' ;
18
19
import { IssueCategory } from 'sentry/types/group' ;
20
+ import { useNavigate } from 'sentry/utils/useNavigate' ;
19
21
import GroupDetails from 'sentry/views/issueDetails/groupDetails' ;
20
22
21
23
const SAMPLE_EVENT_ALERT_TEXT =
22
24
'You are viewing a sample error. Configure Sentry to start viewing real errors.' ;
23
25
26
+ jest . mock ( 'sentry/utils/useNavigate' , ( ) => ( {
27
+ useNavigate : jest . fn ( ) ,
28
+ } ) ) ;
29
+
24
30
describe ( 'groupDetails' , ( ) => {
31
+ let mockNavigate : jest . Mock ;
25
32
const group = GroupFixture ( { issueCategory : IssueCategory . ERROR } ) ;
26
33
const event = EventFixture ( ) ;
27
34
const project = ProjectFixture ( { teams : [ TeamFixture ( ) ] } ) ;
@@ -86,9 +93,11 @@ describe('groupDetails', () => {
86
93
} ;
87
94
88
95
beforeEach ( ( ) => {
96
+ mockNavigate = jest . fn ( ) ;
89
97
MockApiClient . clearMockResponses ( ) ;
90
98
OrganizationStore . onUpdate ( defaultInit . organization ) ;
91
99
act ( ( ) => ProjectsStore . loadInitialData ( defaultInit . projects ) ) ;
100
+ jest . mocked ( useNavigate ) . mockReturnValue ( mockNavigate ) ;
92
101
93
102
MockApiClient . addMockResponse ( {
94
103
url : `/organizations/${ defaultInit . organization . slug } /issues/${ group . id } /` ,
@@ -297,6 +306,118 @@ describe('groupDetails', () => {
297
306
await waitFor ( ( ) => expect ( recommendedMock ) . toHaveBeenCalledTimes ( 1 ) ) ;
298
307
} ) ;
299
308
309
+ it ( "refires request when recommended endpoint doesn't return an event" , async function ( ) {
310
+ const recommendedWithSearchMock = MockApiClient . addMockResponse ( {
311
+ url : `/organizations/${ defaultInit . organization . slug } /issues/${ group . id } /events/recommended/` ,
312
+ query : {
313
+ query : 'foo:bar' ,
314
+ statsPeriod : '14d' ,
315
+ } ,
316
+ statusCode : 404 ,
317
+ body : {
318
+ detail : 'No matching event' ,
319
+ } ,
320
+ } ) ;
321
+
322
+ createWrapper ( {
323
+ ...defaultInit ,
324
+ router : {
325
+ ...defaultInit . router ,
326
+ location : LocationFixture ( {
327
+ query : {
328
+ query : 'foo:bar' ,
329
+ statsPeriod : '14d' ,
330
+ } ,
331
+ } ) ,
332
+ } ,
333
+ } ) ;
334
+
335
+ await waitFor ( ( ) => expect ( recommendedWithSearchMock ) . toHaveBeenCalledTimes ( 1 ) ) ;
336
+
337
+ await waitFor ( ( ) =>
338
+ expect ( mockNavigate ) . toHaveBeenCalledWith (
339
+ expect . objectContaining (
340
+ // query and period should be removed
341
+ { query : { } }
342
+ ) ,
343
+ {
344
+ replace : true ,
345
+ }
346
+ )
347
+ ) ;
348
+ } ) ;
349
+
350
+ it ( 'does not refire for request with streamlined UI' , async function ( ) {
351
+ // Bunch of mocks to load streamlined UI
352
+ MockApiClient . addMockResponse ( {
353
+ url : '/organizations/org-slug/flags/logs/' ,
354
+ body : { data : [ ] } ,
355
+ } ) ;
356
+ MockApiClient . addMockResponse ( {
357
+ url : `/organizations/${ defaultInit . organization . slug } /users/` ,
358
+ body : [ ] ,
359
+ } ) ;
360
+ MockApiClient . addMockResponse ( {
361
+ url : `/organizations/${ defaultInit . organization . slug } /issues/${ group . id } /attachments/` ,
362
+ body : [ ] ,
363
+ } ) ;
364
+ MockApiClient . addMockResponse ( {
365
+ url : `/organizations/${ defaultInit . organization . slug } /issues/${ group . id } /tags/` ,
366
+ body : [ ] ,
367
+ } ) ;
368
+ MockApiClient . addMockResponse ( {
369
+ url : `/organizations/${ defaultInit . organization . slug } /releases/stats/` ,
370
+ body : [ ] ,
371
+ } ) ;
372
+ MockApiClient . addMockResponse ( {
373
+ url : `/organizations/${ defaultInit . organization . slug } /events-stats/` ,
374
+ body : { 'count()' : EventsStatsFixture ( ) , 'count_unique(user)' : EventsStatsFixture ( ) } ,
375
+ method : 'GET' ,
376
+ } ) ;
377
+ MockApiClient . addMockResponse ( {
378
+ url : `/organizations/${ defaultInit . organization . slug } /events/` ,
379
+ body : { data : [ { 'count_unique(user)' : 21 } ] } ,
380
+ } ) ;
381
+ MockApiClient . addMockResponse ( {
382
+ url : `/organizations/${ defaultInit . organization . slug } /sentry-app-installations/` ,
383
+ body : [ ] ,
384
+ } ) ;
385
+ MockApiClient . addMockResponse ( {
386
+ url : `/organizations/${ defaultInit . organization . slug } /sentry-app-components/` ,
387
+ body : [ ] ,
388
+ } ) ;
389
+
390
+ const recommendedWithSearchMock = MockApiClient . addMockResponse ( {
391
+ url : `/organizations/${ defaultInit . organization . slug } /issues/${ group . id } /events/recommended/` ,
392
+ query : {
393
+ query : 'foo:bar' ,
394
+ statsPeriod : '14d' ,
395
+ } ,
396
+ statusCode : 404 ,
397
+ body : {
398
+ detail : 'No matching event' ,
399
+ } ,
400
+ } ) ;
401
+
402
+ createWrapper ( {
403
+ ...defaultInit ,
404
+ router : {
405
+ ...defaultInit . router ,
406
+ location : LocationFixture ( {
407
+ query : {
408
+ query : 'foo:bar' ,
409
+ statsPeriod : '14d' ,
410
+ streamline : '1' ,
411
+ } ,
412
+ } ) ,
413
+ } ,
414
+ } ) ;
415
+
416
+ await waitFor ( ( ) => expect ( recommendedWithSearchMock ) . toHaveBeenCalledTimes ( 1 ) ) ;
417
+
418
+ await waitFor ( ( ) => expect ( mockNavigate ) . not . toHaveBeenCalled ( ) ) ;
419
+ } ) ;
420
+
300
421
it ( 'uses /latest endpoint when default is set to latest' , async function ( ) {
301
422
ConfigStore . loadInitialData ( ConfigFixture ( { user : latestUser } ) ) ;
302
423
const latestMock = MockApiClient . addMockResponse ( {
0 commit comments