subscription.ts 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. import {MetricHistoryFixture} from 'getsentry-test/fixtures/metricHistory';
  2. import {PlanDetailsLookupFixture} from 'getsentry-test/fixtures/planDetailsLookup';
  3. import {DATA_CATEGORY_INFO} from 'sentry/constants';
  4. import {DataCategory} from 'sentry/types/core';
  5. import type {Organization} from 'sentry/types/organization';
  6. import type {Subscription as TSubscription} from 'getsentry/types';
  7. import {BillingType} from 'getsentry/types';
  8. import {RESERVED_BUDGET_QUOTA} from 'getsentry/constants';
  9. import {ReservedBudgetFixture} from 'getsentry-test/fixtures/reservedBudget';
  10. import {ReservedBudgetMetricHistoryFixture} from 'getsentry-test/fixtures/reservedBudget';
  11. type Props = Partial<TSubscription> & {organization: Organization};
  12. export function SubscriptionFixture(props: Props): TSubscription {
  13. const {organization, ...params} = props;
  14. const planData = {plan: 'am1_f', ...params};
  15. const planDetails = PlanDetailsLookupFixture(planData.plan);
  16. const hasPerformance = planDetails?.categories?.includes(
  17. DATA_CATEGORY_INFO.transaction.plural
  18. );
  19. const hasReplays = planDetails?.categories?.includes(DATA_CATEGORY_INFO.replay.plural);
  20. const hasMonitors = planDetails?.categories?.includes(
  21. DATA_CATEGORY_INFO.monitorSeat.plural
  22. );
  23. const hasUptime = planDetails?.categories?.includes(DATA_CATEGORY_INFO.uptime.plural);
  24. const hasSpans = planDetails?.categories?.includes(DATA_CATEGORY_INFO.span.plural);
  25. const hasSpansIndexed = planDetails?.categories?.includes(
  26. DATA_CATEGORY_INFO.spanIndexed.plural
  27. );
  28. const hasProfileDuration = planDetails?.categories?.includes(
  29. DataCategory.PROFILE_DURATION
  30. );
  31. const hasAttachments = planDetails?.categories?.includes(
  32. DATA_CATEGORY_INFO.attachment.plural
  33. );
  34. return {
  35. customPrice: null,
  36. customPriceAttachments: null,
  37. customPriceErrors: null,
  38. customPricePcss: null,
  39. customPriceTransactions: null,
  40. hasDismissedForcedTrialNotice: false,
  41. hasDismissedTrialEndingNotice: false,
  42. hasOverageNotificationsDisabled: false,
  43. hasRestrictedIntegration: false,
  44. hadCustomDynamicSampling: false,
  45. id: '',
  46. isBundleEligible: false,
  47. isEnterpriseTrial: false,
  48. isExemptFromForcedTrial: false,
  49. isForcedTrial: false,
  50. isOverMemberLimit: false,
  51. isPartner: false,
  52. isSelfServePartner: false,
  53. isPerformancePlanTrial: false,
  54. lastTrialEnd: null,
  55. spendAllocationEnabled: false,
  56. status: 'active',
  57. totalProjects: 0,
  58. trialPlan: null,
  59. trialTier: null,
  60. onDemandPeriodStart: '2018-09-25',
  61. gracePeriodStart: null,
  62. trialEnd: null,
  63. countryCode: null,
  64. cancelAtPeriodEnd: false,
  65. isTrial: false,
  66. paymentSource: {
  67. last4: '4242',
  68. countryCode: 'US',
  69. zipCode: '94242',
  70. expMonth: 12,
  71. expYear: 2077,
  72. },
  73. billingPeriodEnd: '2018-10-24',
  74. onDemandSpendUsed: 0,
  75. renewalDate: '2018-10-25',
  76. partner: null,
  77. planDetails: planDetails!,
  78. totalMembers: 1,
  79. contractInterval: 'monthly',
  80. canGracePeriod: true,
  81. totalLicenses: 1,
  82. billingPeriodStart: '2018-09-25',
  83. suspensionReason: null,
  84. planTier: 'am1',
  85. accountBalance: -10000,
  86. companyName: null,
  87. isSuspended: false,
  88. isSponsored: false,
  89. sponsoredType: null,
  90. isFree: true,
  91. billingEmail: null,
  92. gdprDetails: null,
  93. canCancel: false,
  94. canSelfServe: true,
  95. supportsOnDemand: true,
  96. usedLicenses: 1,
  97. membersDeactivatedFromLimit: 0,
  98. type: BillingType.CREDIT_CARD,
  99. reservedEvents: planDetails!.planCategories.errors![0]!.events,
  100. hasSoftCap: false,
  101. isPastDue: false,
  102. onDemandDisabled: false,
  103. onDemandInvoiced: false,
  104. gracePeriodEnd: null,
  105. contractPeriodStart: '2018-09-25',
  106. prepaidEventsAllowed: 5000,
  107. onDemandMaxSpend: 0,
  108. productTrials: [],
  109. isManaged: false,
  110. contractPeriodEnd: '2018-10-24',
  111. canTrial: true,
  112. slug: organization.slug,
  113. pendingChanges: null,
  114. usageExceeded: false,
  115. isHeroku: false,
  116. name: organization.name,
  117. billingInterval: 'monthly',
  118. contactInfo: null,
  119. dateJoined: '2018-09-10T23:58:10.167Z',
  120. vatStatus: null,
  121. isGracePeriod: false,
  122. onDemandPeriodEnd: '2018-10-24',
  123. vatID: null,
  124. reservedErrors: 5_000,
  125. reservedTransactions: 10_000,
  126. reservedAttachments: 1,
  127. msaUpdatedForDataConsent: false,
  128. dataRetention: null,
  129. hasReservedBudgets: false,
  130. reservedBudgetCategories: [],
  131. categories: {
  132. errors: MetricHistoryFixture({
  133. category: DATA_CATEGORY_INFO.error.plural,
  134. reserved: planDetails!.planCategories.errors![0]!.events,
  135. prepaid: planDetails!.planCategories.errors![0]!.events,
  136. order: 1,
  137. }),
  138. ...(hasPerformance && {
  139. transactions: MetricHistoryFixture({
  140. category: DATA_CATEGORY_INFO.transaction.plural,
  141. reserved: planDetails!.planCategories.transactions![0]!.events,
  142. prepaid: planDetails!.planCategories.transactions![0]!.events,
  143. order: 2,
  144. }),
  145. }),
  146. ...(hasReplays && {
  147. replays: MetricHistoryFixture({
  148. category: DATA_CATEGORY_INFO.replay.plural,
  149. reserved: planDetails!.planCategories.replays![0]!.events,
  150. prepaid: planDetails!.planCategories.replays![0]!.events,
  151. order: 4,
  152. }),
  153. }),
  154. ...(hasSpans && {
  155. spans: MetricHistoryFixture({
  156. category: DATA_CATEGORY_INFO.span.plural,
  157. reserved: planDetails!.planCategories.spans![0]!.events,
  158. prepaid: planDetails!.planCategories.spans![0]!.events,
  159. order: 5,
  160. }),
  161. }),
  162. ...(hasSpansIndexed && {
  163. spansIndexed: MetricHistoryFixture({
  164. category: DATA_CATEGORY_INFO.spanIndexed.plural,
  165. reserved: planDetails!.planCategories.spans![0]!.events,
  166. prepaid: planDetails!.planCategories.spans![0]!.events,
  167. order: 6,
  168. }),
  169. }),
  170. ...(hasMonitors && {
  171. monitorSeats: MetricHistoryFixture({
  172. category: DATA_CATEGORY_INFO.monitorSeat.plural,
  173. reserved: planDetails!.planCategories.monitorSeats![0]!.events,
  174. prepaid: planDetails!.planCategories.monitorSeats![0]!.events,
  175. order: 7,
  176. }),
  177. }),
  178. ...(hasUptime && {
  179. uptime: MetricHistoryFixture({
  180. category: DATA_CATEGORY_INFO.uptime.plural,
  181. reserved: planDetails!.planCategories.uptime![0]!.events,
  182. prepaid: planDetails!.planCategories.uptime![0]!.events,
  183. order: 8,
  184. }),
  185. }),
  186. ...(hasAttachments && {
  187. attachments: MetricHistoryFixture({
  188. category: DATA_CATEGORY_INFO.attachment.plural,
  189. reserved: planDetails!.planCategories.attachments![0]!.events,
  190. prepaid: planDetails!.planCategories.attachments![0]!.events,
  191. order: 9,
  192. }),
  193. }),
  194. ...(hasProfileDuration && {
  195. profileDuration: MetricHistoryFixture({
  196. category: DataCategory.PROFILE_DURATION,
  197. reserved: planDetails!.planCategories.profileDuration![0]!.events,
  198. prepaid: planDetails!.planCategories.profileDuration![0]!.events,
  199. order: 10,
  200. }),
  201. }),
  202. },
  203. ...planData,
  204. };
  205. }
  206. export function InvoicedSubscriptionFixture(props: Props): TSubscription {
  207. const {organization, ...params} = props;
  208. const planData = {plan: 'am2_business_ent_auf', ...params};
  209. const planDetails = PlanDetailsLookupFixture(planData.plan);
  210. const hasErrors = planDetails?.categories?.includes(DATA_CATEGORY_INFO.error.plural);
  211. const hasPerformance = planDetails?.categories?.includes(
  212. DATA_CATEGORY_INFO.transaction.plural
  213. );
  214. const hasReplays = planDetails?.categories?.includes(DATA_CATEGORY_INFO.replay.plural);
  215. const hasMonitors = planDetails?.categories?.includes(
  216. DATA_CATEGORY_INFO.monitorSeat.plural
  217. );
  218. const hasSpans = planDetails?.categories?.includes(DATA_CATEGORY_INFO.span.plural);
  219. const hasAttachments = planDetails?.categories?.includes(
  220. DATA_CATEGORY_INFO.attachment.plural
  221. );
  222. return {
  223. customPrice: null,
  224. customPriceAttachments: null,
  225. customPriceErrors: null,
  226. customPricePcss: null,
  227. customPriceTransactions: null,
  228. hasDismissedForcedTrialNotice: false,
  229. hasDismissedTrialEndingNotice: false,
  230. hasOverageNotificationsDisabled: false,
  231. hasRestrictedIntegration: false,
  232. hadCustomDynamicSampling: false,
  233. id: '',
  234. isBundleEligible: false,
  235. isEnterpriseTrial: false,
  236. isExemptFromForcedTrial: false,
  237. isForcedTrial: false,
  238. isOverMemberLimit: false,
  239. isPartner: false,
  240. isSelfServePartner: false,
  241. isPerformancePlanTrial: false,
  242. lastTrialEnd: null,
  243. spendAllocationEnabled: false,
  244. status: 'active',
  245. totalProjects: 0,
  246. trialPlan: null,
  247. trialTier: null,
  248. onDemandPeriodStart: '2024-04-03',
  249. gracePeriodStart: null,
  250. trialEnd: null,
  251. countryCode: null,
  252. cancelAtPeriodEnd: false,
  253. isTrial: false,
  254. paymentSource: {
  255. last4: '4242',
  256. countryCode: 'US',
  257. zipCode: '94242',
  258. expMonth: 12,
  259. expYear: 2077,
  260. },
  261. billingPeriodEnd: '2025-04-02',
  262. onDemandSpendUsed: 0,
  263. renewalDate: '2025-04-03',
  264. partner: null,
  265. planDetails: planDetails!,
  266. totalMembers: 1,
  267. contractInterval: 'annual',
  268. canGracePeriod: true,
  269. totalLicenses: 1,
  270. billingPeriodStart: '2024-04-03',
  271. suspensionReason: null,
  272. planTier: 'am2',
  273. accountBalance: 0,
  274. companyName: null,
  275. isSuspended: false,
  276. isSponsored: false,
  277. sponsoredType: null,
  278. isFree: true,
  279. billingEmail: null,
  280. gdprDetails: null,
  281. canCancel: false,
  282. canSelfServe: false,
  283. supportsOnDemand: false,
  284. usedLicenses: 1,
  285. membersDeactivatedFromLimit: 0,
  286. type: BillingType.INVOICED,
  287. reservedEvents: 50_000,
  288. hasSoftCap: false,
  289. isPastDue: false,
  290. onDemandDisabled: false,
  291. onDemandInvoiced: false,
  292. onDemandInvoicedManual: false,
  293. gracePeriodEnd: null,
  294. contractPeriodStart: '2024-04-03',
  295. prepaidEventsAllowed: 50_000,
  296. onDemandMaxSpend: 0,
  297. isManaged: false,
  298. contractPeriodEnd: '2025-04-02',
  299. canTrial: true,
  300. slug: organization.slug,
  301. pendingChanges: null,
  302. usageExceeded: false,
  303. isHeroku: false,
  304. name: organization.name,
  305. billingInterval: 'annual',
  306. contactInfo: null,
  307. dateJoined: '2018-09-10T23:58:10.167Z',
  308. vatStatus: null,
  309. isGracePeriod: false,
  310. onDemandPeriodEnd: '2024-05-02',
  311. vatID: null,
  312. reservedErrors: 50_000,
  313. reservedTransactions: 100_000,
  314. reservedAttachments: 1,
  315. dataRetention: null,
  316. hasReservedBudgets: false,
  317. reservedBudgetCategories: [],
  318. categories: {
  319. ...(hasErrors && {
  320. errors: MetricHistoryFixture({
  321. category: DATA_CATEGORY_INFO.error.plural,
  322. reserved: planDetails!.planCategories.errors![0]!.events,
  323. prepaid: planDetails!.planCategories.errors![0]!.events,
  324. order: 1,
  325. }),
  326. }),
  327. ...(hasPerformance && {
  328. transactions: MetricHistoryFixture({
  329. category: DATA_CATEGORY_INFO.transaction.plural,
  330. reserved: planDetails!.planCategories.transactions![0]!.events,
  331. prepaid: planDetails!.planCategories.transactions![0]!.events,
  332. order: 2,
  333. }),
  334. }),
  335. ...(hasReplays && {
  336. replays: MetricHistoryFixture({
  337. category: DATA_CATEGORY_INFO.replay.plural,
  338. reserved: planDetails!.planCategories.replays![0]!.events,
  339. prepaid: planDetails!.planCategories.replays![0]!.events,
  340. order: 4,
  341. }),
  342. }),
  343. ...(hasSpans && {
  344. spans: MetricHistoryFixture({
  345. category: DATA_CATEGORY_INFO.span.plural,
  346. reserved: planDetails!.planCategories.spans![0]!.events,
  347. prepaid: planDetails!.planCategories.spans![0]!.events,
  348. order: 5,
  349. }),
  350. spansIndexed: MetricHistoryFixture({
  351. category: DATA_CATEGORY_INFO.spanIndexed.plural,
  352. reserved: planDetails!.planCategories.spans![0]!.events,
  353. prepaid: planDetails!.planCategories.spans![0]!.events,
  354. order: 6,
  355. }),
  356. }),
  357. ...(hasMonitors && {
  358. monitorSeats: MetricHistoryFixture({
  359. category: DATA_CATEGORY_INFO.monitorSeat.plural,
  360. reserved: planDetails!.planCategories.monitorSeats![0]!.events,
  361. prepaid: planDetails!.planCategories.monitorSeats![0]!.events,
  362. order: 7,
  363. }),
  364. }),
  365. ...(hasAttachments && {
  366. attachments: MetricHistoryFixture({
  367. category: DATA_CATEGORY_INFO.attachment.plural,
  368. reserved: planDetails!.planCategories.attachments![0]!.events,
  369. prepaid: planDetails!.planCategories.attachments![0]!.events,
  370. order: 8,
  371. }),
  372. }),
  373. },
  374. ...planData,
  375. };
  376. }
  377. export function Am3DsEnterpriseSubscriptionFixture(props: Props): TSubscription {
  378. const {organization, ...params} = props;
  379. const planData = {plan: 'am3_business_ent_ds_auf', ...params};
  380. const subscription = SubscriptionFixture({
  381. ...props,
  382. plan: planData.plan,
  383. planTier: planData.planTier,
  384. });
  385. subscription.hasReservedBudgets = true;
  386. subscription.reservedBudgetCategories = ['spans', 'spansIndexed'];
  387. subscription.reservedBudgets = [
  388. ReservedBudgetFixture({
  389. id: '11',
  390. reservedBudget: 100_000_00,
  391. totalReservedSpend: 60_000_00,
  392. freeBudget: 0,
  393. percentUsed: 0.6,
  394. categories: {
  395. spans: ReservedBudgetMetricHistoryFixture({
  396. reservedCpe: 1,
  397. reservedSpend: 40_000_00,
  398. }),
  399. spansIndexed: ReservedBudgetMetricHistoryFixture({
  400. reservedCpe: 2,
  401. reservedSpend: 20_000_00,
  402. }),
  403. },
  404. }),
  405. ];
  406. subscription.categories.spans!.reserved = RESERVED_BUDGET_QUOTA;
  407. subscription.categories.spansIndexed!.reserved = RESERVED_BUDGET_QUOTA;
  408. return subscription;
  409. }