def setUp(self):
        super().setUp()
        self.url = reverse("sentry-api-0-organization-key-transactions-list",
                           args=[self.org.slug])

        self.team1 = self.create_team(organization=self.org, name="Team A")
        self.team2 = self.create_team(organization=self.org, name="Team B")
        self.team3 = self.create_team(organization=self.org, name="Team C")
        self.team4 = self.create_team(organization=self.org, name="Team D")
        self.team5 = self.create_team(organization=self.org, name="Team E")

        for team in [
                self.team1, self.team2, self.team3, self.team4, self.team5
        ]:
            self.project.add_team(team)

        # only join teams 1,2,3
        for team in [self.team1, self.team2, self.team3]:
            self.create_team_membership(team, user=self.user)

        TeamKeyTransaction.objects.bulk_create([
            TeamKeyTransaction(
                organization=self.org,
                project_team=project_team,
                transaction=self.event_data["transaction"],
            ) for project_team in ProjectTeam.objects.filter(
                project=self.project, team__in=[self.team2, self.team3])
        ] + [
            TeamKeyTransaction(
                organization=self.org,
                project_team=project_team,
                transaction="other-transaction",
            ) for project_team in ProjectTeam.objects.filter(
                project=self.project, team__in=[self.team3, self.team4])
        ])
    def test_get_key_transaction_my_teams(self):
        team1 = self.create_team(organization=self.org, name="Team A")
        team2 = self.create_team(organization=self.org, name="Team B")
        team3 = self.create_team(organization=self.org, name="Team C")
        # should not be in response because we never joined this team
        self.create_team(organization=self.org, name="Team D")

        # only join teams 1,2,3
        for team in [team1, team2, team3]:
            self.create_team_membership(team, user=self.user)
            self.project.add_team(team)

        TeamKeyTransaction.objects.bulk_create(
            [
                TeamKeyTransaction(
                    organization=self.org,
                    project_team=project_team,
                    transaction=self.event_data["transaction"],
                )
                for project_team in ProjectTeam.objects.filter(
                    project=self.project, team__in=[team1, team2]
                )
            ]
            + [
                TeamKeyTransaction(
                    organization=self.org,
                    project_team=project_team,
                    transaction="other-transaction",
                )
                for project_team in ProjectTeam.objects.filter(
                    project=self.project, team__in=[team2, team3]
                )
            ]
        )

        with self.feature(self.features):
            response = self.client.get(
                self.url,
                data={
                    "project": [self.project.id],
                    "transaction": self.event_data["transaction"],
                    "team": "myteams",
                },
                format="json",
            )

        assert response.status_code == 200, response.content
        assert response.data == [
            {
                "team": str(team1.id),
            },
            {
                "team": str(team2.id),
            },
        ]
    def test_post_key_transaction_limit_is_per_team(self):
        team1 = self.create_team(organization=self.org, name="Team Foo")
        self.create_team_membership(team1, user=self.user)
        self.project.add_team(team1)

        team2 = self.create_team(organization=self.org, name="Team Bar")
        self.create_team_membership(team2, user=self.user)
        self.project.add_team(team2)

        TeamKeyTransaction.objects.bulk_create([
            TeamKeyTransaction(
                team=team,
                organization=self.org,
                transaction=f"{self.event_data['transaction']}-{i}",
                project=self.project,
            ) for team in [team1, team2]
            for i in range(MAX_TEAM_KEY_TRANSACTIONS - 1)
        ])

        with self.feature(self.features):
            response = self.client.post(
                self.url,
                data={
                    "project": [self.project.id],
                    "transaction": self.event_data["transaction"],
                    "team": [team1.id, team2.id],
                },
                format="json",
            )

        assert response.status_code == 201
        key_transactions = TeamKeyTransaction.objects.filter(
            team__in=[team1, team2])
        assert len(key_transactions) == 2 * MAX_TEAM_KEY_TRANSACTIONS
    def test_post_key_transactions_exceed_limit(self):
        team = self.create_team(organization=self.org, name="Team Foo")
        self.create_team_membership(team, user=self.user)
        self.project.add_team(team)

        TeamKeyTransaction.objects.bulk_create([
            TeamKeyTransaction(
                team=team,
                organization=self.org,
                transaction=f"{self.event_data['transaction']}-{i}",
                project=self.project,
            ) for i in range(MAX_TEAM_KEY_TRANSACTIONS)
        ])

        with self.feature(self.features):
            response = self.client.post(
                self.url,
                data={
                    "project": [self.project.id],
                    "transaction": self.event_data["transaction"],
                    "team": [team.id],
                },
                format="json",
            )

        assert response.status_code == 400
        assert response.data == {
            "non_field_errors": [
                f"At most {MAX_TEAM_KEY_TRANSACTIONS} Key Transactions can be added for a team"
            ]
        }
예제 #5
0
    def post(self, request: Request, organization) -> Response:
        """Create a Key Transaction"""
        if not self.has_feature(organization, request):
            return Response(status=404)

        project = self.get_project(request, organization)

        with transaction.atomic():
            serializer = serializers.TeamKeyTransactionSerializer(
                data=request.data,
                context={
                    "mode": "create",
                    "request": request,
                    "organization": organization,
                },
            )

            if serializer.is_valid():
                data = serializer.validated_data
                base_filter = {
                    "organization": organization,
                    "transaction": data["transaction"],
                }

                project_teams = ProjectTeam.objects.filter(
                    project=project, team__in=data["team"])
                if len(project_teams) < len(data["team"]):
                    # some teams do not have access to the specified project
                    return Response(
                        {"detail": "Team does not have access to project"},
                        status=400)

                keyed_transaction_team_ids = set(
                    TeamKeyTransaction.objects.values_list(
                        "project_team__team_id",
                        flat=True).filter(**base_filter,
                                          project_team__in=project_teams))
                if len(keyed_transaction_team_ids) == len(data["team"]):
                    # all teams already have the specified transaction marked as key
                    return Response(status=204)

                try:
                    unkeyed_project_teams = project_teams.exclude(
                        team_id__in=keyed_transaction_team_ids)
                    TeamKeyTransaction.objects.bulk_create([
                        TeamKeyTransaction(**base_filter,
                                           project_team=project_team)
                        for project_team in unkeyed_project_teams
                    ])
                    return Response(status=201)
                # Even though we tried to avoid it, the TeamKeyTransaction was created already
                except IntegrityError:
                    return Response(status=409)

        return Response(serializer.errors, status=400)
예제 #6
0
    def post(self, request, organization):
        """ Create a Key Transaction """
        if not self.has_feature(request, organization):
            return Response(status=404)

        project = self.get_project(request, organization)

        if not self.has_team_feature(request, organization):
            base_filter = {"organization": organization, "owner": request.user}

            with transaction.atomic():
                serializer = serializers.KeyTransactionSerializer(
                    data=request.data, context=base_filter)
                if serializer.is_valid():
                    data = serializer.validated_data
                    base_filter["transaction"] = data["transaction"]
                    base_filter["project"] = project

                    if KeyTransaction.objects.filter(**base_filter).exists():
                        return Response(status=204)

                    try:
                        KeyTransaction.objects.create(**base_filter)
                        return Response(status=201)
                    # Even though we tried to avoid it, this KeyTransaction was created already
                    except IntegrityError:
                        return Response(status=204)
                return Response(serializer.errors, status=400)

        with transaction.atomic():
            serializer = serializers.TeamKeyTransactionSerializer(
                data=request.data,
                context={
                    "mode": "create",
                    "request": request,
                    "organization": organization,
                },
            )

            if serializer.is_valid():
                data = serializer.validated_data
                base_filter = {
                    "organization": organization,
                    "project": project,
                    "transaction": data["transaction"],
                }

                keyed_transaction_team_ids = set(
                    TeamKeyTransaction.objects.values_list(
                        "team_id", flat=True).filter(**base_filter,
                                                     team__in=data["team"]))
                if len(keyed_transaction_team_ids) == len(data["team"]):
                    return Response(status=204)

                try:
                    # TeamKeyTransaction.objects.create(**base_filter)
                    TeamKeyTransaction.objects.bulk_create([
                        TeamKeyTransaction(**base_filter, team=team)
                        for team in data["team"]
                        if team.id not in keyed_transaction_team_ids
                    ])
                    return Response(status=201)
                # Even though we tried to avoid it, the TeamKeyTransaction was created already
                except IntegrityError:
                    return Response(status=409)

        return Response(serializer.errors, status=400)