Browse Source

feat(quick-start): Add acceptance tests - receivers (#82226)

Priscila Oliveira 2 months ago
parent
commit
c5735db962
1 changed files with 350 additions and 1 deletions
  1. 350 1
      tests/sentry/receivers/test_onboarding.py

+ 350 - 1
tests/sentry/receivers/test_onboarding.py

@@ -27,10 +27,11 @@ from sentry.signals import (
     member_joined,
     plugin_enabled,
     project_created,
+    transaction_processed,
 )
 from sentry.silo.base import SiloMode
 from sentry.testutils.cases import TestCase
-from sentry.testutils.helpers.datetime import before_now
+from sentry.testutils.helpers.datetime import before_now, iso_format
 from sentry.testutils.outbox import outbox_runner
 from sentry.testutils.silo import assume_test_silo_mode
 from sentry.testutils.skips import requires_snuba
@@ -1010,3 +1011,351 @@ class OrganizationOnboardingTaskTest(TestCase):
                 task=OnboardingTask.ALERT_RULE,
                 status=OnboardingTaskStatus.COMPLETE,
             ).exists()
+
+    # New quick start
+    @patch("sentry.analytics.record")
+    def test_new_onboarding_complete(self, record_analytics):
+        """
+        Test the new quick start happy path
+        """
+        with self.feature("organizations:quick-start-updates"):
+            # Create first project
+            project = self.create_project()
+            project_created.send(
+                project=project, user=self.user, default_rules=False, sender=type(project)
+            )
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.FIRST_PROJECT,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "project.created",
+                user_id=self.user.id,
+                default_user_id=self.organization.default_owner_id,
+                organization_id=self.organization.id,
+                project_id=project.id,
+                platform=project.platform,
+                updated_empty_state=False,
+            )
+
+            # Set up tracing
+            transaction_event = load_data("transaction")
+            transaction_event.update({"user": None})
+            event = self.store_event(data=transaction_event, project_id=project.id)
+            transaction_processed.send(project=project, event=event, sender=type(project))
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.FIRST_TRANSACTION,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "first_transaction.sent",
+                default_user_id=self.organization.default_owner_id,
+                organization_id=self.organization.id,
+                project_id=project.id,
+                platform=project.platform,
+            )
+
+            #  Capture first error
+            error_event = self.store_event(
+                data={
+                    "event_id": "c" * 32,
+                    "message": "this is bad.",
+                    "timestamp": iso_format(timezone.now()),
+                    "type": "error",
+                },
+                project_id=project.id,
+            )
+            event_processed.send(project=project, event=error_event, sender=type(project))
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.FIRST_EVENT,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "first_event.sent",
+                user_id=self.user.id,
+                organization_id=project.organization_id,
+                project_id=project.id,
+                platform=error_event.platform,
+                project_platform=project.platform,
+            )
+
+            # Configure an issue alert
+            alert_rule_created.send(
+                rule_id=Rule(id=1).id,
+                project=project,
+                user=self.user,
+                rule_type="issue",
+                sender=type(Rule),
+                is_api_token=False,
+            )
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.ALERT_RULE,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "alert.created",
+                user_id=self.user.id,
+                default_user_id=self.organization.default_owner_id,
+                organization_id=self.organization.id,
+                project_id=project.id,
+                rule_id=Rule(id=1).id,
+                rule_type="issue",
+                referrer=None,
+                session_id=None,
+                is_api_token=False,
+                alert_rule_ui_component=None,
+                duplicate_rule=None,
+                wizard_v3=None,
+                query_type=None,
+            )
+
+            # Unminify your code
+            sourcemap_event = load_data("javascript")
+            sourcemap_event.update(
+                {
+                    "exception": {
+                        "values": [
+                            {
+                                "stacktrace": {
+                                    "frames": [
+                                        {
+                                            "data": {
+                                                "sourcemap": "https://media.sentry.io/_static/29e365f8b0d923bc123e8afa38d890c3/sentry/dist/vendor.js.map"
+                                            }
+                                        }
+                                    ]
+                                },
+                                "type": "TypeError",
+                            }
+                        ]
+                    },
+                }
+            )
+            event_with_sourcemap = self.store_event(data=sourcemap_event, project_id=project.id)
+            event_processed.send(project=project, event=event_with_sourcemap, sender=type(project))
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.SOURCEMAPS,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.call_args_list[
+                len(record_analytics.call_args_list) - 2
+            ].assert_called_with(
+                "first_sourcemaps.sent",
+                user_id=self.user.id,
+                organization_id=self.organization.id,
+                project_id=project.id,
+                platform=event_with_sourcemap.platform,
+                project_platform=project.platform,
+                url=dict(event_with_sourcemap.tags).get("url", None),
+            )
+            record_analytics.assert_called_with(
+                "first_sourcemaps_for_project.sent",
+                user_id=self.user.id,
+                organization_id=self.organization.id,
+                project_id=project.id,
+                platform=event_with_sourcemap.platform,
+                project_platform=project.platform,
+                url=dict(event_with_sourcemap.tags).get("url", None),
+            )
+
+            # Track releases
+            transaction_event = load_data("transaction")
+            transaction_event.update({"release": "my-first-release", "tags": []})
+            event = self.store_event(data=transaction_event, project_id=project.id)
+            transaction_processed.send(project=project, event=event, sender=type(project))
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.RELEASE_TRACKING,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.call_args_list[
+                len(record_analytics.call_args_list) - 2
+            ].assert_called_with(
+                "first_release_tag.sent",
+                user_id=self.user.id,
+                project_id=project.id,
+                organization_id=self.organization.id,
+            )
+
+            # Link Sentry to source code
+            github_integration = self.create_integration("github", 1234)
+            integration_added.send(
+                integration_id=github_integration.id,
+                organization_id=self.organization.id,
+                user_id=self.user.id,
+                sender=None,
+            )
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.LINK_SENTRY_TO_SOURCE_CODE,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "integration.added",
+                user_id=self.user.id,
+                default_user_id=self.organization.default_owner_id,
+                organization_id=self.organization.id,
+                provider=github_integration.provider,
+                id=github_integration.id,
+            )
+
+            # Invite your team
+            user = self.create_user(email="test@example.org")
+            member = self.create_member(
+                organization=self.organization, teams=[self.team], email=user.email
+            )
+            member_invited.send(member=member, user=user, sender=type(member))
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.INVITE_MEMBER,
+                    status=OnboardingTaskStatus.PENDING,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "member.invited",
+                invited_member_id=member.id,
+                inviter_user_id=user.id,
+                organization_id=self.organization.id,
+                referrer=None,
+            )
+
+            # Member accepted the invite
+            member_joined.send(
+                organization_member_id=member.id,
+                organization_id=self.organization.id,
+                user_id=member.user_id,
+                sender=None,
+            )
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.INVITE_MEMBER,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "organization.joined",
+                user_id=None,
+                organization_id=self.organization.id,
+            )
+
+            # The first group is complete but the beyond the basics is not
+            assert (
+                OrganizationOption.objects.filter(
+                    organization=self.organization, key="onboarding:complete"
+                ).count()
+                == 0
+            )
+
+            # Set up session replay
+            first_replay_received.send(project=project, sender=type(project))
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.SESSION_REPLAY,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "first_replay.sent",
+                user_id=self.user.id,
+                organization_id=project.organization_id,
+                project_id=project.id,
+                platform=project.platform,
+            )
+
+            # Get real time notifications
+            slack_integration = self.create_integration("slack", 4321)
+            integration_added.send(
+                integration_id=slack_integration.id,
+                organization_id=self.organization.id,
+                user_id=self.user.id,
+                sender=None,
+            )
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.REAL_TIME_NOTIFICATIONS,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.assert_called_with(
+                "integration.added",
+                user_id=self.user.id,
+                default_user_id=self.organization.default_owner_id,
+                organization_id=self.organization.id,
+                provider=slack_integration.provider,
+                id=slack_integration.id,
+            )
+
+            # Add Sentry to other parts app
+            second_project = self.create_project(
+                first_event=timezone.now(), organization=self.organization
+            )
+            project_created.send(
+                project=second_project,
+                user=self.user,
+                sender=type(second_project),
+                default_rules=False,
+            )
+            assert (
+                OrganizationOnboardingTask.objects.get(
+                    organization=self.organization,
+                    task=OnboardingTask.SECOND_PLATFORM,
+                    status=OnboardingTaskStatus.COMPLETE,
+                )
+                is not None
+            )
+            record_analytics.call_args_list[
+                len(record_analytics.call_args_list) - 2
+            ].assert_called_with(
+                "second_platform.added",
+                user_id=self.user.id,
+                organization_id=self.organization.id,
+                project_id=second_project.id,
+            )
+
+            # Onboarding is complete
+            assert (
+                OrganizationOption.objects.filter(
+                    organization=self.organization, key="onboarding:complete"
+                ).count()
+                == 1
+            )
+            record_analytics.assert_called_with(
+                "onboarding.complete",
+                user_id=self.user.id,
+                organization_id=self.organization.id,
+                referrer="onboarding_tasks",
+            )