fixtures.py 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. from __future__ import annotations
  2. from datetime import datetime, timedelta
  3. from typing import Any, Mapping, Optional
  4. import pytest
  5. from django.utils.functional import cached_property
  6. from sentry.eventstore.models import Event
  7. from sentry.incidents.models import IncidentActivityType
  8. from sentry.models.activity import Activity
  9. from sentry.models.actor import Actor, get_actor_id_for_user
  10. from sentry.models.grouprelease import GroupRelease
  11. from sentry.models.identity import Identity, IdentityProvider
  12. from sentry.models.integrations.integration import Integration
  13. from sentry.models.integrations.organization_integration import OrganizationIntegration
  14. from sentry.models.organization import Organization
  15. from sentry.models.organizationmember import OrganizationMember
  16. from sentry.models.organizationmemberteam import OrganizationMemberTeam
  17. from sentry.models.project import Project
  18. from sentry.models.user import User
  19. from sentry.services.hybrid_cloud.organization import RpcOrganization
  20. from sentry.services.hybrid_cloud.user import RpcUser
  21. from sentry.silo import SiloMode
  22. from sentry.testutils.factories import Factories
  23. from sentry.testutils.helpers.datetime import before_now, iso_format
  24. from sentry.testutils.silo import assume_test_silo_mode
  25. # XXX(dcramer): this is a compatibility layer to transition to pytest-based fixtures
  26. # all of the memoized fixtures are copypasta due to our inability to use pytest fixtures
  27. # on a per-class method basis
  28. from sentry.types.activity import ActivityType
  29. class Fixtures:
  30. @cached_property
  31. def session(self):
  32. return Factories.create_session()
  33. @cached_property
  34. def projectkey(self):
  35. return self.create_project_key(project=self.project)
  36. @cached_property
  37. def user(self):
  38. return self.create_user("admin@localhost", is_superuser=True)
  39. @cached_property
  40. def organization(self):
  41. # XXX(dcramer): ensure that your org slug doesnt match your team slug
  42. # and the same for your project slug
  43. return self.create_organization(name="baz", slug="baz", owner=self.user)
  44. @cached_property
  45. @assume_test_silo_mode(SiloMode.REGION)
  46. def team(self):
  47. team = self.create_team(organization=self.organization, name="foo", slug="foo")
  48. # XXX: handle legacy team fixture
  49. queryset = OrganizationMember.objects.filter(organization=self.organization)
  50. for om in queryset:
  51. OrganizationMemberTeam.objects.create(team=team, organizationmember=om, is_active=True)
  52. return team
  53. @cached_property
  54. def project(self):
  55. return self.create_project(
  56. name="Bar", slug="bar", teams=[self.team], fire_project_created=True
  57. )
  58. @cached_property
  59. def release(self):
  60. return self.create_release(project=self.project, version="foo-1.0")
  61. @cached_property
  62. def environment(self):
  63. return self.create_environment(name="development", project=self.project)
  64. @cached_property
  65. def group(self):
  66. return self.create_group(message="\u3053\u3093\u306b\u3061\u306f")
  67. @cached_property
  68. def event(self):
  69. return self.store_event(
  70. data={
  71. "event_id": "a" * 32,
  72. "message": "\u3053\u3093\u306b\u3061\u306f",
  73. "timestamp": iso_format(before_now(seconds=1)),
  74. },
  75. project_id=self.project.id,
  76. )
  77. @cached_property
  78. @assume_test_silo_mode(SiloMode.REGION)
  79. def activity(self):
  80. return Activity.objects.create(
  81. group=self.group,
  82. project=self.project,
  83. type=ActivityType.NOTE.value,
  84. user_id=self.user.id,
  85. data={},
  86. )
  87. @cached_property
  88. @assume_test_silo_mode(SiloMode.CONTROL)
  89. def integration(self):
  90. integration = Integration.objects.create(
  91. provider="github",
  92. name="GitHub",
  93. external_id="github:1",
  94. metadata={
  95. "access_token": "xxxxx-xxxxxxxxx-xxxxxxxxxx-xxxxxxxxxxxx",
  96. "expires_at": iso_format(datetime.utcnow() + timedelta(days=14)),
  97. },
  98. )
  99. integration.add_organization(self.organization, self.user)
  100. return integration
  101. @cached_property
  102. @assume_test_silo_mode(SiloMode.CONTROL)
  103. def organization_integration(self):
  104. return self.integration.add_organization(self.organization, self.user)
  105. def create_organization(self, *args, **kwargs):
  106. return Factories.create_organization(*args, **kwargs)
  107. def create_member(self, *args, **kwargs):
  108. return Factories.create_member(*args, **kwargs)
  109. def create_api_key(self, *args, **kwargs):
  110. return Factories.create_api_key(*args, **kwargs)
  111. def create_auth_provider(self, *args, **kwargs):
  112. return Factories.create_auth_provider(*args, **kwargs)
  113. def create_auth_identity(self, *args, **kwargs):
  114. return Factories.create_auth_identity(*args, **kwargs)
  115. def create_user_auth_token(self, *args, **kwargs):
  116. return Factories.create_user_auth_token(*args, **kwargs)
  117. def create_team_membership(self, *args, **kwargs):
  118. return Factories.create_team_membership(*args, **kwargs)
  119. def create_team(self, organization=None, **kwargs):
  120. if organization is None:
  121. organization = self.organization
  122. return Factories.create_team(organization=organization, **kwargs)
  123. def create_environment(self, project=None, **kwargs):
  124. if project is None:
  125. project = self.project
  126. return Factories.create_environment(project=project, **kwargs)
  127. def create_project(self, **kwargs):
  128. if "teams" not in kwargs:
  129. kwargs["teams"] = [self.team]
  130. return Factories.create_project(**kwargs)
  131. def create_project_bookmark(self, project=None, *args, **kwargs):
  132. if project is None:
  133. project = self.project
  134. return Factories.create_project_bookmark(project=project, *args, **kwargs)
  135. def create_project_key(self, project=None, *args, **kwargs):
  136. if project is None:
  137. project = self.project
  138. return Factories.create_project_key(project=project, *args, **kwargs)
  139. def create_project_rule(
  140. self, project=None, action_match=None, condition_match=None, *args, **kwargs
  141. ):
  142. if project is None:
  143. project = self.project
  144. return Factories.create_project_rule(
  145. project=project,
  146. action_data=action_match,
  147. condition_data=condition_match,
  148. *args,
  149. **kwargs,
  150. )
  151. def create_slack_project_rule(
  152. self, project=None, integration_id=None, channel_id=None, channel_name=None, *args, **kwargs
  153. ):
  154. if project is None:
  155. project = self.project
  156. return Factories.create_slack_project_rule(
  157. project,
  158. integration_id=integration_id,
  159. channel_id=channel_id,
  160. channel_name=channel_name,
  161. *args,
  162. **kwargs,
  163. )
  164. def create_release(self, project=None, user=None, *args, **kwargs):
  165. if project is None:
  166. project = self.project
  167. return Factories.create_release(project=project, user=user, *args, **kwargs)
  168. def create_group_release(self, project: Project = None, *args, **kwargs) -> GroupRelease:
  169. if project is None:
  170. project = self.project
  171. return Factories.create_group_release(project, *args, **kwargs)
  172. def create_release_file(self, release_id=None, file=None, name=None, dist_id=None):
  173. if release_id is None:
  174. release_id = self.release.id
  175. return Factories.create_release_file(release_id, file, name, dist_id)
  176. def create_artifact_bundle_zip(self, org=None, release=None, *args, **kwargs):
  177. return Factories.create_artifact_bundle_zip(org, release, *args, **kwargs)
  178. def create_release_archive(self, org=None, release=None, *args, **kwargs):
  179. if org is None:
  180. org = self.organization.slug
  181. if release is None:
  182. release = self.release.version
  183. return Factories.create_release_archive(org, release, *args, **kwargs)
  184. def create_artifact_bundle(self, org=None, *args, **kwargs):
  185. if org is None:
  186. org = self.organization
  187. return Factories.create_artifact_bundle(org, *args, **kwargs)
  188. def create_code_mapping(self, project=None, repo=None, organization_integration=None, **kwargs):
  189. if project is None:
  190. project = self.project
  191. if organization_integration is None:
  192. organization_integration = self.organization_integration
  193. return Factories.create_code_mapping(project, repo, organization_integration, **kwargs)
  194. def create_repo(self, project=None, *args, **kwargs):
  195. if project is None:
  196. project = self.project
  197. return Factories.create_repo(project=project, *args, **kwargs)
  198. def create_commit(self, *args, **kwargs):
  199. return Factories.create_commit(*args, **kwargs)
  200. def create_commit_author(self, *args, **kwargs):
  201. return Factories.create_commit_author(*args, **kwargs)
  202. def create_commit_file_change(self, *args, **kwargs):
  203. return Factories.create_commit_file_change(*args, **kwargs)
  204. def create_user(self, *args, **kwargs):
  205. return Factories.create_user(*args, **kwargs)
  206. def create_useremail(self, *args, **kwargs):
  207. return Factories.create_useremail(*args, **kwargs)
  208. def create_usersocialauth(
  209. self,
  210. user: User | None = None,
  211. provider: str | None = None,
  212. uid: str | None = None,
  213. extra_data: Mapping[str, Any] | None = None,
  214. ):
  215. if not user:
  216. user = self.user
  217. return Factories.create_usersocialauth(
  218. user=user, provider=provider, uid=uid, extra_data=extra_data
  219. )
  220. def store_event(self, *args, **kwargs) -> Event:
  221. return Factories.store_event(*args, **kwargs)
  222. def create_group(self, project=None, *args, **kwargs):
  223. if project is None:
  224. project = self.project
  225. return Factories.create_group(project=project, *args, **kwargs)
  226. def create_file(self, **kwargs):
  227. return Factories.create_file(**kwargs)
  228. def create_file_from_path(self, *args, **kwargs):
  229. return Factories.create_file_from_path(*args, **kwargs)
  230. def create_event_attachment(self, event=None, *args, **kwargs):
  231. if event is None:
  232. event = self.event
  233. return Factories.create_event_attachment(event=event, *args, **kwargs)
  234. def create_dif_file(self, project=None, *args, **kwargs):
  235. if project is None:
  236. project = self.project
  237. return Factories.create_dif_file(project=project, *args, **kwargs)
  238. def create_dif_from_path(self, project=None, *args, **kwargs):
  239. if project is None:
  240. project = self.project
  241. return Factories.create_dif_from_path(project=project, *args, **kwargs)
  242. def add_user_permission(self, *args, **kwargs):
  243. return Factories.add_user_permission(*args, **kwargs)
  244. def create_sentry_app(self, *args, **kwargs):
  245. return Factories.create_sentry_app(*args, **kwargs)
  246. def create_internal_integration(self, *args, **kwargs):
  247. return Factories.create_internal_integration(*args, **kwargs)
  248. def create_internal_integration_token(self, *args, **kwargs):
  249. return Factories.create_internal_integration_token(*args, **kwargs)
  250. def create_sentry_app_installation(self, *args, **kwargs):
  251. return Factories.create_sentry_app_installation(*args, **kwargs)
  252. def create_sentry_app_installation_for_provider(self, *args, **kwargs):
  253. return Factories.create_sentry_app_installation_for_provider(*args, **kwargs)
  254. def create_stacktrace_link_schema(self, *args, **kwargs):
  255. return Factories.create_stacktrace_link_schema(*args, **kwargs)
  256. def create_issue_link_schema(self, *args, **kwargs):
  257. return Factories.create_issue_link_schema(*args, **kwargs)
  258. def create_alert_rule_action_schema(self, *args, **kwargs):
  259. return Factories.create_alert_rule_action_schema(*args, **kwargs)
  260. def create_sentry_app_feature(self, *args, **kwargs):
  261. return Factories.create_sentry_app_feature(*args, **kwargs)
  262. def create_doc_integration(self, *args, **kwargs):
  263. return Factories.create_doc_integration(*args, **kwargs)
  264. def create_doc_integration_features(self, *args, **kwargs):
  265. return Factories.create_doc_integration_features(*args, **kwargs)
  266. def create_doc_integration_avatar(self, *args, **kwargs):
  267. return Factories.create_doc_integration_avatar(*args, **kwargs)
  268. def create_service_hook(self, *args, **kwargs):
  269. return Factories.create_service_hook(*args, **kwargs)
  270. def create_userreport(self, *args, **kwargs):
  271. return Factories.create_userreport(*args, **kwargs)
  272. def create_platform_external_issue(self, *args, **kwargs):
  273. return Factories.create_platform_external_issue(*args, **kwargs)
  274. def create_integration_external_issue(self, *args, **kwargs):
  275. return Factories.create_integration_external_issue(*args, **kwargs)
  276. def create_incident(self, organization=None, projects=None, *args, **kwargs):
  277. if not organization:
  278. organization = self.organization
  279. if projects is None:
  280. projects = [self.project]
  281. return Factories.create_incident(
  282. organization=organization, projects=projects, *args, **kwargs
  283. )
  284. def create_incident_activity(self, incident, *args, **kwargs):
  285. return Factories.create_incident_activity(incident=incident, *args, **kwargs)
  286. def create_incident_comment(self, incident, *args, **kwargs):
  287. return self.create_incident_activity(
  288. incident, type=IncidentActivityType.COMMENT.value, *args, **kwargs
  289. )
  290. def create_incident_trigger(self, incident, alert_rule_trigger, status):
  291. return Factories.create_incident_trigger(incident, alert_rule_trigger, status=status)
  292. def create_alert_rule(self, organization=None, projects=None, *args, **kwargs):
  293. if not organization:
  294. organization = self.organization
  295. if projects is None:
  296. projects = [self.project]
  297. return Factories.create_alert_rule(organization, projects, *args, **kwargs)
  298. def create_alert_rule_trigger(self, alert_rule=None, *args, **kwargs):
  299. if not alert_rule:
  300. alert_rule = self.create_alert_rule()
  301. return Factories.create_alert_rule_trigger(alert_rule, *args, **kwargs)
  302. def create_alert_rule_trigger_action(
  303. self,
  304. alert_rule_trigger=None,
  305. target_identifier=None,
  306. triggered_for_incident=None,
  307. *args,
  308. **kwargs,
  309. ):
  310. if not alert_rule_trigger:
  311. alert_rule_trigger = self.create_alert_rule_trigger()
  312. if not target_identifier:
  313. target_identifier = str(self.user.id)
  314. if triggered_for_incident is not None:
  315. Factories.create_incident_trigger(triggered_for_incident, alert_rule_trigger)
  316. return Factories.create_alert_rule_trigger_action(
  317. alert_rule_trigger, target_identifier=target_identifier, **kwargs
  318. )
  319. def create_notification_action(self, organization=None, projects=None, **kwargs):
  320. return Factories.create_notification_action(
  321. organization=organization, projects=projects, **kwargs
  322. )
  323. def create_notification_settings_provider(self, *args, **kwargs):
  324. return Factories.create_notification_settings_provider(*args, **kwargs)
  325. def create_external_user(self, user=None, organization=None, integration=None, **kwargs):
  326. if not user:
  327. user = self.user
  328. if not organization:
  329. organization = self.organization # Force creation.
  330. if not integration:
  331. integration = self.integration
  332. return Factories.create_external_user(
  333. user=user, organization=organization, integration_id=integration.id, **kwargs
  334. )
  335. def create_external_team(self, team=None, integration=None, **kwargs):
  336. if not team:
  337. team = self.team
  338. if not integration:
  339. integration = self.integration
  340. return Factories.create_external_team(
  341. team=team, organization=team.organization, integration_id=integration.id, **kwargs
  342. )
  343. def create_codeowners(self, project=None, code_mapping=None, **kwargs):
  344. if not project:
  345. project = self.project
  346. if not code_mapping:
  347. self.repo = self.create_repo(self.project)
  348. code_mapping = self.create_code_mapping(self.project, self.repo)
  349. return Factories.create_codeowners(project=project, code_mapping=code_mapping, **kwargs)
  350. def create_slack_integration(
  351. self,
  352. organization: Organization,
  353. external_id: str = "TXXXXXXX1",
  354. user: Optional[RpcUser] = None,
  355. identity_external_id: str = "UXXXXXXX1",
  356. **kwargs: Any,
  357. ):
  358. if user is None:
  359. with assume_test_silo_mode(SiloMode.REGION):
  360. user = organization.get_default_owner()
  361. integration = Factories.create_slack_integration(
  362. organization=organization, external_id=external_id, **kwargs
  363. )
  364. idp = Factories.create_identity_provider(integration=integration)
  365. Factories.create_identity(user, idp, identity_external_id)
  366. return integration
  367. def create_integration(
  368. self,
  369. organization: Organization,
  370. external_id: str,
  371. oi_params: Mapping[str, Any] | None = None,
  372. **kwargs: Any,
  373. ) -> Integration:
  374. """Create an integration and add an organization."""
  375. return Factories.create_integration(organization, external_id, oi_params, **kwargs)
  376. def create_provider_integration(self, **integration_params: Any) -> Integration:
  377. """Create an integration tied to a provider but no particular organization."""
  378. return Factories.create_provider_integration(**integration_params)
  379. def create_provider_integration_for(
  380. self,
  381. organization: Organization | RpcOrganization,
  382. user: User | RpcUser | None,
  383. **integration_params: Any,
  384. ) -> tuple[Integration, OrganizationIntegration]:
  385. """Create an integration tied to a provider, then add an organization."""
  386. return Factories.create_provider_integration_for(organization, user, **integration_params)
  387. def create_identity_integration(
  388. self,
  389. user: User | RpcUser,
  390. organization: Organization | RpcOrganization,
  391. integration_params: Mapping[Any, Any],
  392. identity_params: Mapping[Any, Any],
  393. ) -> tuple[Integration, OrganizationIntegration, Identity, IdentityProvider]:
  394. return Factories.create_identity_integration(
  395. user, organization, integration_params, identity_params
  396. )
  397. def create_organization_integration(self, **integration_params: Any) -> OrganizationIntegration:
  398. """Create an OrganizationIntegration entity."""
  399. return Factories.create_organization_integration(**integration_params)
  400. def create_identity(self, *args, **kwargs):
  401. return Factories.create_identity(*args, **kwargs)
  402. def create_identity_provider(
  403. self,
  404. integration: Integration | None = None,
  405. config: Mapping[str, Any] | None = None,
  406. **kwargs: Any,
  407. ) -> IdentityProvider:
  408. return Factories.create_identity_provider(integration=integration, config=config, **kwargs)
  409. def create_group_history(self, *args, **kwargs):
  410. if "actor" not in kwargs:
  411. kwargs["actor"] = Actor.objects.get(id=get_actor_id_for_user(self.user))
  412. return Factories.create_group_history(*args, **kwargs)
  413. def create_comment(self, *args, **kwargs):
  414. return Factories.create_comment(*args, **kwargs)
  415. def create_sentry_function(self, *args, **kwargs):
  416. return Factories.create_sentry_function(*args, **kwargs)
  417. def create_saved_search(self, *args, **kwargs):
  418. return Factories.create_saved_search(*args, **kwargs)
  419. def create_organization_mapping(self, *args, **kwargs):
  420. return Factories.create_org_mapping(*args, **kwargs)
  421. def create_basic_auth_header(self, *args, **kwargs):
  422. return Factories.create_basic_auth_header(*args, **kwargs)
  423. def snooze_rule(self, *args, **kwargs):
  424. return Factories.snooze_rule(*args, **kwargs)
  425. @pytest.fixture(autouse=True)
  426. def _init_insta_snapshot(self, insta_snapshot):
  427. self.insta_snapshot = insta_snapshot