3
3
4
4
from sentry .api .serializers .base import serialize
5
5
from sentry .api .serializers .rest_framework .groupsearchview import GroupSearchViewValidatorResponse
6
+ from sentry .issues .endpoints .organization_group_search_views import DEFAULT_VIEWS
6
7
from sentry .models .groupsearchview import GroupSearchView
7
8
from sentry .testutils .cases import APITestCase , TransactionTestCase
8
9
from sentry .testutils .helpers .features import with_feature
@@ -366,7 +367,7 @@ def create_base_data_with_page_filters(self) -> list[GroupSearchView]:
366
367
query_sort = "date" ,
367
368
position = 0 ,
368
369
time_filters = {"period" : "14d" },
369
- environments = ["production" ],
370
+ environments = [],
370
371
)
371
372
first_custom_view_user_one .projects .set ([self .project1 ])
372
373
@@ -378,7 +379,7 @@ def create_base_data_with_page_filters(self) -> list[GroupSearchView]:
378
379
query_sort = "new" ,
379
380
position = 1 ,
380
381
time_filters = {"period" : "7d" },
381
- environments = ["staging" ],
382
+ environments = ["staging" , "production" ],
382
383
)
383
384
second_custom_view_user_one .projects .set ([self .project1 , self .project2 , self .project3 ])
384
385
@@ -413,7 +414,7 @@ def test_not_including_page_filters_does_not_reset_them_for_existing_views(self)
413
414
# Original Page filters
414
415
assert views [0 ]["timeFilters" ] == {"period" : "14d" }
415
416
assert views [0 ]["projects" ] == [self .project1 .id ]
416
- assert views [0 ]["environments" ] == ["production" ]
417
+ assert views [0 ]["environments" ] == []
417
418
418
419
view = views [0 ]
419
420
# Change nothing but the name
@@ -428,7 +429,7 @@ def test_not_including_page_filters_does_not_reset_them_for_existing_views(self)
428
429
# Ensure these have not been changed
429
430
assert views [0 ]["timeFilters" ] == {"period" : "14d" }
430
431
assert views [0 ]["projects" ] == [self .project1 .id ]
431
- assert views [0 ]["environments" ] == ["production" ]
432
+ assert views [0 ]["environments" ] == []
432
433
433
434
@with_feature ({"organizations:issue-stream-custom-views" : True })
434
435
@with_feature ({"organizations:global-views" : True })
@@ -584,6 +585,209 @@ def test_invalid_project_ids(self) -> None:
584
585
assert response .content == b'{"detail":"One or more projects do not exist"}'
585
586
586
587
588
+ class OrganizationGroupSearchViewsGetPageFiltersTest (APITestCase ):
589
+ def create_base_data_with_page_filters (self ) -> None :
590
+ self .team_1 = self .create_team (organization = self .organization , slug = "team-1" )
591
+ self .team_2 = self .create_team (organization = self .organization , slug = "team-2" )
592
+
593
+ # User 1 is on team 1 only
594
+ user_1 = self .user
595
+ self .create_team_membership (user = user_1 , team = self .team_1 )
596
+ # User 2 is on team 1 and team 2
597
+ self .user_2 = self .create_user ()
598
+ self .create_member (
599
+ organization = self .organization , user = self .user_2 , teams = [self .team_1 , self .team_2 ]
600
+ )
601
+ # User 3 has no views and should get the default views
602
+ self .user_3 = self .create_user ()
603
+ self .create_member (organization = self .organization , user = self .user_3 , teams = [self .team_1 ])
604
+ # User 4 is part of no teams, should error out
605
+ self .user_4 = self .create_user ()
606
+ self .create_member (organization = self .organization , user = self .user_4 )
607
+
608
+ # This project should NEVER get chosen as a default since it does not belong to any teams
609
+ self .project1 = self .create_project (
610
+ organization = self .organization , slug = "project-a" , teams = []
611
+ )
612
+ # This project should be User 2's default project since it's the alphabetically the first one
613
+ self .project2 = self .create_project (
614
+ organization = self .organization , slug = "project-b" , teams = [self .team_2 ]
615
+ )
616
+ # This should be User 1's default project since it's the only one that the user has access to
617
+ self .project3 = self .create_project (
618
+ organization = self .organization , slug = "project-c" , teams = [self .team_1 , self .team_2 ]
619
+ )
620
+
621
+ first_issue_view_user_one = GroupSearchView .objects .create (
622
+ name = "Issue View One" ,
623
+ organization = self .organization ,
624
+ user_id = user_1 .id ,
625
+ query = "is:unresolved" ,
626
+ query_sort = "date" ,
627
+ position = 0 ,
628
+ is_all_projects = False ,
629
+ time_filters = {"period" : "14d" },
630
+ environments = [],
631
+ )
632
+ first_issue_view_user_one .projects .set ([self .project3 ])
633
+
634
+ second_issue_view_user_one = GroupSearchView .objects .create (
635
+ name = "Issue View Two" ,
636
+ organization = self .organization ,
637
+ user_id = user_1 .id ,
638
+ query = "is:resolved" ,
639
+ query_sort = "new" ,
640
+ position = 1 ,
641
+ is_all_projects = False ,
642
+ time_filters = {"period" : "7d" },
643
+ environments = ["staging" , "production" ],
644
+ )
645
+ second_issue_view_user_one .projects .set ([])
646
+
647
+ third_issue_view_user_one = GroupSearchView .objects .create (
648
+ name = "Issue View Three" ,
649
+ organization = self .organization ,
650
+ user_id = user_1 .id ,
651
+ query = "is:ignored" ,
652
+ query_sort = "freq" ,
653
+ position = 2 ,
654
+ is_all_projects = True ,
655
+ time_filters = {"period" : "30d" },
656
+ environments = ["development" ],
657
+ )
658
+ third_issue_view_user_one .projects .set ([])
659
+
660
+ first_issue_view_user_two = GroupSearchView .objects .create (
661
+ name = "Issue View One" ,
662
+ organization = self .organization ,
663
+ user_id = self .user_2 .id ,
664
+ query = "is:unresolved" ,
665
+ query_sort = "date" ,
666
+ position = 0 ,
667
+ is_all_projects = False ,
668
+ time_filters = {"period" : "14d" },
669
+ environments = [],
670
+ )
671
+ first_issue_view_user_two .projects .set ([])
672
+
673
+ first_issue_view_user_four = GroupSearchView .objects .create (
674
+ name = "Issue View One" ,
675
+ organization = self .organization ,
676
+ user_id = self .user_4 .id ,
677
+ query = "is:unresolved" ,
678
+ query_sort = "date" ,
679
+ position = 0 ,
680
+ is_all_projects = False ,
681
+ time_filters = {"period" : "14d" },
682
+ environments = [],
683
+ )
684
+ first_issue_view_user_four .projects .set ([])
685
+
686
+ def setUp (self ) -> None :
687
+ self .create_base_data_with_page_filters ()
688
+ self .url = reverse (
689
+ "sentry-api-0-organization-group-search-views" ,
690
+ kwargs = {"organization_id_or_slug" : self .organization .slug },
691
+ )
692
+
693
+ @with_feature ({"organizations:issue-stream-custom-views" : True })
694
+ @with_feature ({"organizations:global-views" : True })
695
+ def test_basic_get_page_filters_with_global_filters (self ) -> None :
696
+ self .login_as (user = self .user )
697
+ response = self .client .get (self .url )
698
+
699
+ assert response .data [0 ]["timeFilters" ] == {"period" : "14d" }
700
+ assert response .data [0 ]["projects" ] == [self .project3 .id ]
701
+ assert response .data [0 ]["environments" ] == []
702
+ assert response .data [0 ]["isAllProjects" ] is False
703
+
704
+ assert response .data [1 ]["timeFilters" ] == {"period" : "7d" }
705
+ assert response .data [1 ]["projects" ] == []
706
+ assert response .data [1 ]["environments" ] == ["staging" , "production" ]
707
+ assert response .data [1 ]["isAllProjects" ] is False
708
+
709
+ assert response .data [2 ]["timeFilters" ] == {"period" : "30d" }
710
+ assert response .data [2 ]["projects" ] == []
711
+ assert response .data [2 ]["environments" ] == ["development" ]
712
+ assert response .data [2 ]["isAllProjects" ] is True
713
+
714
+ @with_feature ({"organizations:issue-stream-custom-views" : True })
715
+ @with_feature ({"organizations:global-views" : False })
716
+ def test_get_page_filters_without_global_filters (self ) -> None :
717
+ self .login_as (user = self .user )
718
+ response = self .client .get (self .url )
719
+
720
+ assert response .data [0 ]["timeFilters" ] == {"period" : "14d" }
721
+ assert response .data [0 ]["projects" ] == [self .project3 .id ]
722
+ assert response .data [0 ]["environments" ] == []
723
+ assert response .data [0 ]["isAllProjects" ] is False
724
+
725
+ assert response .data [1 ]["timeFilters" ] == {"period" : "7d" }
726
+ assert response .data [1 ]["projects" ] == [self .project3 .id ]
727
+ assert response .data [1 ]["environments" ] == ["staging" , "production" ]
728
+ assert response .data [1 ]["isAllProjects" ] is False
729
+
730
+ assert response .data [2 ]["timeFilters" ] == {"period" : "30d" }
731
+ assert response .data [2 ]["projects" ] == [self .project3 .id ]
732
+ assert response .data [2 ]["environments" ] == ["development" ]
733
+ assert response .data [2 ]["isAllProjects" ] is False
734
+
735
+ @with_feature ({"organizations:issue-stream-custom-views" : True })
736
+ @with_feature ({"organizations:global-views" : False })
737
+ def test_get_page_filters_without_global_filters_user_2 (self ) -> None :
738
+ self .login_as (user = self .user_2 )
739
+ response = self .client .get (self .url )
740
+
741
+ assert response .data [0 ]["timeFilters" ] == {"period" : "14d" }
742
+ assert response .data [0 ]["projects" ] == [self .project2 .id ]
743
+ assert response .data [0 ]["environments" ] == []
744
+ assert response .data [0 ]["isAllProjects" ] is False
745
+
746
+ @with_feature ({"organizations:issue-stream-custom-views" : True })
747
+ @with_feature ({"organizations:global-views" : True })
748
+ def test_default_page_filters_with_global_views (self ) -> None :
749
+ self .login_as (user = self .user_3 )
750
+ response = self .client .get (self .url )
751
+
752
+ default_view_queries = {view ["query" ] for view in DEFAULT_VIEWS }
753
+ received_queries = {view ["query" ] for view in response .data }
754
+
755
+ assert default_view_queries == received_queries
756
+
757
+ for view in response .data :
758
+ assert view ["timeFilters" ] == {"period" : "14d" }
759
+ # Global views means default project should be "My Projects"
760
+ assert view ["projects" ] == []
761
+ assert view ["environments" ] == []
762
+ assert view ["isAllProjects" ] is False
763
+
764
+ @with_feature ({"organizations:issue-stream-custom-views" : True })
765
+ @with_feature ({"organizations:global-views" : False })
766
+ def test_default_page_filters_without_global_views (self ) -> None :
767
+ self .login_as (user = self .user_3 )
768
+ response = self .client .get (self .url )
769
+
770
+ default_view_queries = {view ["query" ] for view in DEFAULT_VIEWS }
771
+ received_queries = {view ["query" ] for view in response .data }
772
+
773
+ assert default_view_queries == received_queries
774
+
775
+ for view in response .data :
776
+ assert view ["timeFilters" ] == {"period" : "14d" }
777
+ # No global views means default project should be a single project
778
+ assert view ["projects" ] == [self .project3 .id ]
779
+ assert view ["environments" ] == []
780
+ assert view ["isAllProjects" ] is False
781
+
782
+ @with_feature ({"organizations:issue-stream-custom-views" : True })
783
+ @with_feature ({"organizations:global-views" : False })
784
+ def test_error_when_no_projects_found (self ) -> None :
785
+ self .login_as (user = self .user_4 )
786
+ response = self .client .get (self .url )
787
+ assert response .status_code == 400
788
+ assert response .data == {"detail" : "You do not have access to any projects." }
789
+
790
+
587
791
class OrganizationGroupSearchViewsPutRegressionTest (APITestCase ):
588
792
endpoint = "sentry-api-0-organization-group-search-views"
589
793
method = "put"
0 commit comments