dataCategory.spec.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. import {OrganizationFixture} from 'sentry-fixture/organization';
  2. import {MetricHistoryFixture} from 'getsentry-test/fixtures/metricHistory';
  3. import {PlanDetailsLookupFixture} from 'getsentry-test/fixtures/planDetailsLookup';
  4. import {SubscriptionFixture} from 'getsentry-test/fixtures/subscription';
  5. import {DataCategory} from 'sentry/types/core';
  6. import {
  7. getPlanCategoryName,
  8. getReservedBudgetDisplayName,
  9. hasCategoryFeature,
  10. listDisplayNames,
  11. sortCategories,
  12. sortCategoriesWithKeys,
  13. } from 'getsentry/utils/dataCategory';
  14. describe('hasCategoryFeature', function () {
  15. const organization = OrganizationFixture();
  16. const subscription = SubscriptionFixture({organization, plan: 'mm2_b_100k'});
  17. it('returns am1 plan categories', function () {
  18. const sub = SubscriptionFixture({organization, plan: 'am1_team'});
  19. expect(hasCategoryFeature(DataCategory.ERRORS, sub, organization)).toBe(true);
  20. expect(hasCategoryFeature(DataCategory.TRANSACTIONS, sub, organization)).toBe(true);
  21. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, sub, organization)).toBe(true);
  22. expect(hasCategoryFeature(DataCategory.REPLAYS, sub, organization)).toBe(true);
  23. expect(hasCategoryFeature(DataCategory.MONITOR_SEATS, sub, organization)).toBe(true);
  24. });
  25. it('returns mm2 plan categories', function () {
  26. expect(hasCategoryFeature(DataCategory.ERRORS, subscription, organization)).toBe(
  27. true
  28. );
  29. expect(
  30. hasCategoryFeature(DataCategory.TRANSACTIONS, subscription, organization)
  31. ).toBe(false);
  32. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, subscription, organization)).toBe(
  33. false
  34. );
  35. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, organization)).toBe(
  36. false
  37. );
  38. expect(
  39. hasCategoryFeature(DataCategory.MONITOR_SEATS, subscription, organization)
  40. ).toBe(false);
  41. });
  42. it('returns mm1 plan categories', function () {
  43. const sub = SubscriptionFixture({organization, plan: 's1'});
  44. expect(hasCategoryFeature(DataCategory.ERRORS, sub, organization)).toBe(true);
  45. expect(hasCategoryFeature(DataCategory.TRANSACTIONS, sub, organization)).toBe(false);
  46. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, sub, organization)).toBe(false);
  47. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, organization)).toBe(
  48. false
  49. );
  50. expect(
  51. hasCategoryFeature(DataCategory.MONITOR_SEATS, subscription, organization)
  52. ).toBe(false);
  53. });
  54. it('returns org has transactions feature', function () {
  55. const org = {...organization, features: ['performance-view']};
  56. expect(hasCategoryFeature(DataCategory.ERRORS, subscription, org)).toBe(true);
  57. expect(hasCategoryFeature(DataCategory.TRANSACTIONS, subscription, org)).toBe(true);
  58. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, subscription, org)).toBe(false);
  59. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, org)).toBe(false);
  60. expect(hasCategoryFeature(DataCategory.MONITOR_SEATS, subscription, org)).toBe(false);
  61. });
  62. it('returns org has attachments feature', function () {
  63. const org = {...organization, features: ['event-attachments']};
  64. expect(hasCategoryFeature(DataCategory.ERRORS, subscription, org)).toBe(true);
  65. expect(hasCategoryFeature(DataCategory.TRANSACTIONS, subscription, org)).toBe(false);
  66. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, subscription, org)).toBe(true);
  67. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, org)).toBe(false);
  68. expect(hasCategoryFeature(DataCategory.MONITOR_SEATS, subscription, org)).toBe(false);
  69. });
  70. it('returns org has replays feature', function () {
  71. const org = {...organization, features: ['session-replay']};
  72. expect(hasCategoryFeature(DataCategory.ERRORS, subscription, org)).toBe(true);
  73. expect(hasCategoryFeature(DataCategory.TRANSACTIONS, subscription, org)).toBe(false);
  74. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, subscription, org)).toBe(false);
  75. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, org)).toBe(true);
  76. expect(hasCategoryFeature(DataCategory.MONITOR_SEATS, subscription, org)).toBe(false);
  77. });
  78. it('returns org has transactions and attachments features', function () {
  79. const org = {...organization, features: ['performance-view', 'event-attachments']};
  80. expect(hasCategoryFeature(DataCategory.ERRORS, subscription, org)).toBe(true);
  81. expect(hasCategoryFeature(DataCategory.TRANSACTIONS, subscription, org)).toBe(true);
  82. expect(hasCategoryFeature(DataCategory.ATTACHMENTS, subscription, org)).toBe(true);
  83. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, org)).toBe(false);
  84. expect(hasCategoryFeature(DataCategory.REPLAYS, subscription, org)).toBe(false);
  85. });
  86. it('returns org does not have unknown feature', function () {
  87. const org = {...organization, features: []};
  88. expect(hasCategoryFeature('unknown', subscription, org)).toBe(false);
  89. });
  90. it('returns sorted categories', function () {
  91. const sub = SubscriptionFixture({organization, plan: 'am1_team'});
  92. expect(sortCategories(sub.categories)).toStrictEqual([
  93. MetricHistoryFixture({
  94. category: DataCategory.ERRORS,
  95. reserved: 50_000,
  96. prepaid: 50_000,
  97. order: 1,
  98. }),
  99. MetricHistoryFixture({
  100. category: DataCategory.TRANSACTIONS,
  101. reserved: 100_000,
  102. prepaid: 100_000,
  103. order: 2,
  104. }),
  105. MetricHistoryFixture({
  106. category: DataCategory.REPLAYS,
  107. reserved: 500,
  108. prepaid: 500,
  109. order: 4,
  110. }),
  111. MetricHistoryFixture({
  112. category: DataCategory.MONITOR_SEATS,
  113. reserved: 1,
  114. prepaid: 1,
  115. order: 7,
  116. }),
  117. MetricHistoryFixture({
  118. category: DataCategory.UPTIME,
  119. reserved: 1,
  120. prepaid: 1,
  121. order: 8,
  122. }),
  123. MetricHistoryFixture({
  124. category: DataCategory.ATTACHMENTS,
  125. reserved: 1,
  126. prepaid: 1,
  127. order: 9,
  128. }),
  129. ]);
  130. });
  131. it('returns sorted categories with keys', function () {
  132. const sub = SubscriptionFixture({organization, plan: 'am1_team'});
  133. expect(sortCategoriesWithKeys(sub.categories)).toStrictEqual([
  134. [
  135. 'errors',
  136. MetricHistoryFixture({
  137. category: DataCategory.ERRORS,
  138. reserved: 50_000,
  139. prepaid: 50_000,
  140. order: 1,
  141. }),
  142. ],
  143. [
  144. 'transactions',
  145. MetricHistoryFixture({
  146. category: DataCategory.TRANSACTIONS,
  147. reserved: 100_000,
  148. prepaid: 100_000,
  149. order: 2,
  150. }),
  151. ],
  152. [
  153. 'replays',
  154. MetricHistoryFixture({
  155. category: DataCategory.REPLAYS,
  156. reserved: 500,
  157. prepaid: 500,
  158. order: 4,
  159. }),
  160. ],
  161. [
  162. 'monitorSeats',
  163. MetricHistoryFixture({
  164. category: DataCategory.MONITOR_SEATS,
  165. reserved: 1,
  166. prepaid: 1,
  167. order: 7,
  168. }),
  169. ],
  170. [
  171. 'uptime',
  172. MetricHistoryFixture({
  173. category: DataCategory.UPTIME,
  174. reserved: 1,
  175. prepaid: 1,
  176. order: 8,
  177. }),
  178. ],
  179. [
  180. 'attachments',
  181. MetricHistoryFixture({
  182. category: DataCategory.ATTACHMENTS,
  183. reserved: 1,
  184. prepaid: 1,
  185. order: 9,
  186. }),
  187. ],
  188. ]);
  189. });
  190. });
  191. describe('getPlanCategoryName', function () {
  192. const plan = PlanDetailsLookupFixture('am3_team');
  193. it('should capitalize category', function () {
  194. expect(getPlanCategoryName({plan, category: 'transactions'})).toBe('Transactions');
  195. expect(getPlanCategoryName({plan, category: 'errors'})).toBe('Errors');
  196. expect(getPlanCategoryName({plan, category: 'replays'})).toBe('Replays');
  197. expect(getPlanCategoryName({plan, category: 'spans'})).toBe('Spans');
  198. expect(getPlanCategoryName({plan, category: 'profiles'})).toBe('Profiles');
  199. expect(getPlanCategoryName({plan, category: 'monitorSeats'})).toBe('Cron monitors');
  200. });
  201. it('should display spans as accepted spans for DS', function () {
  202. expect(
  203. getPlanCategoryName({plan, category: 'spans', hadCustomDynamicSampling: true})
  204. ).toBe('Accepted spans');
  205. });
  206. });
  207. describe('getReservedBudgetDisplayName', function () {
  208. const am1Plan = PlanDetailsLookupFixture('am1_team');
  209. const am2Plan = PlanDetailsLookupFixture('am2_business');
  210. const am3Plan = PlanDetailsLookupFixture('am3_business');
  211. const am3DsPlan = PlanDetailsLookupFixture('am3_business_ent_ds_auf');
  212. it('should oxfordize categories alphabetically for am1', function () {
  213. expect(
  214. getReservedBudgetDisplayName({
  215. plan: am1Plan,
  216. categories: am1Plan?.categories ?? [],
  217. hadCustomDynamicSampling: false,
  218. })
  219. ).toBe(
  220. 'attachments, cron monitors, errors, replays, transactions, and uptime monitors'
  221. );
  222. });
  223. it('should oxfordize categories alphabetically for am2', function () {
  224. expect(
  225. getReservedBudgetDisplayName({
  226. plan: am2Plan,
  227. categories: am2Plan?.categories ?? [],
  228. hadCustomDynamicSampling: false,
  229. })
  230. ).toBe(
  231. 'attachments, cron monitors, errors, performance units, profile hours, replays, and uptime monitors'
  232. );
  233. });
  234. it('should oxfordize categories alphabetically for am3', function () {
  235. expect(
  236. getReservedBudgetDisplayName({
  237. plan: am3Plan,
  238. categories: am3Plan?.categories ?? [],
  239. hadCustomDynamicSampling: false,
  240. })
  241. ).toBe(
  242. 'attachments, cron monitors, errors, profile hours, replays, spans, and uptime monitors'
  243. );
  244. });
  245. it('should use accepted spans for DS', function () {
  246. expect(
  247. getReservedBudgetDisplayName({
  248. plan: am3DsPlan,
  249. categories: ['spans', 'spansIndexed'],
  250. hadCustomDynamicSampling: true,
  251. })
  252. ).toBe('accepted spans and stored spans');
  253. expect(
  254. getReservedBudgetDisplayName({
  255. plan: am3DsPlan,
  256. categories: ['spans', 'spansIndexed'],
  257. hadCustomDynamicSampling: false,
  258. })
  259. ).toBe('spans and stored spans');
  260. });
  261. it('should title case categories only', function () {
  262. expect(
  263. getReservedBudgetDisplayName({
  264. plan: am3Plan,
  265. categories: am3Plan?.categories ?? [],
  266. shouldTitleCase: true,
  267. })
  268. ).toBe(
  269. 'Attachments, Cron Monitors, Errors, Profile Hours, Replays, Spans, and Uptime Monitors'
  270. );
  271. });
  272. });
  273. describe('listDisplayNames', function () {
  274. const plan = PlanDetailsLookupFixture('am3_business_ent_ds_auf');
  275. it('should list categories in order given', function () {
  276. expect(
  277. listDisplayNames({
  278. plan: plan!,
  279. categories: [
  280. 'spans',
  281. 'transactions',
  282. 'errors',
  283. 'replays',
  284. 'monitorSeats',
  285. 'attachments',
  286. ],
  287. })
  288. ).toBe('spans, transactions, errors, replays, cron monitors, and attachments');
  289. });
  290. it('should hide stored spans for no DS', function () {
  291. expect(
  292. listDisplayNames({
  293. plan: plan!,
  294. categories: plan!.checkoutCategories,
  295. hadCustomDynamicSampling: false,
  296. })
  297. ).toBe(
  298. 'errors, replays, attachments, cron monitors, spans, profile hours, and uptime monitors'
  299. );
  300. });
  301. it('should include stored spans and use accepted spans for DS', function () {
  302. expect(
  303. listDisplayNames({
  304. plan: plan!,
  305. categories: plan!.checkoutCategories,
  306. hadCustomDynamicSampling: true,
  307. })
  308. ).toBe(
  309. 'errors, replays, attachments, cron monitors, accepted spans, profile hours, uptime monitors, and stored spans'
  310. );
  311. });
  312. });