123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- import {OrganizationFixture} from 'sentry-fixture/organization';
- import {PlanDetailsLookupFixture} from 'getsentry-test/fixtures/planDetailsLookup';
- import {PlanMigrationFixture} from 'getsentry-test/fixtures/planMigration';
- import {
- Am3DsEnterpriseSubscriptionFixture,
- SubscriptionFixture,
- } from 'getsentry-test/fixtures/subscription';
- import {render} from 'sentry-test/reactTestingLibrary';
- import PendingChanges from 'admin/components/customers/pendingChanges';
- import {PendingChangesFixture} from 'getsentry/__fixtures__/pendingChanges';
- import {PlanFixture} from 'getsentry/__fixtures__/plan';
- import {ANNUAL, RESERVED_BUDGET_QUOTA} from 'getsentry/constants';
- import * as usePlanMigrations from 'getsentry/hooks/usePlanMigrations';
- import {CohortId, OnDemandBudgetMode} from 'getsentry/types';
- describe('PendingChanges', function () {
- it('renders null pendingChanges)', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- expect(container).toBeEmptyDOMElement();
- });
- it('renders empty pendingChanges', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- pendingChanges: null,
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- expect(container).toBeEmptyDOMElement();
- });
- it('renders pending changes', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- customPrice: 0,
- customPricePcss: 0,
- pendingChanges: PendingChangesFixture({
- planDetails: PlanFixture({
- name: 'Team (Enterprise)',
- contractInterval: 'annual',
- billingInterval: 'annual',
- }),
- plan: 'am1_team_ent',
- planName: 'Team (Enterprise)',
- reservedEvents: 15000000,
- reservedErrors: 15000000,
- reservedTransactions: 20000000,
- reservedAttachments: 25,
- reserved: {errors: 15000000, transactions: 20000000, attachments: 25},
- customPrice: 5000000,
- customPriceErrors: 2000000,
- customPriceTransactions: 2900000,
- customPriceAttachments: 50000,
- customPrices: {errors: 2000000, transactions: 2900000, attachments: 50000},
- customPricePcss: 50000,
- onDemandMaxSpend: 50000,
- effectiveDate: '2022-03-16',
- onDemandEffectiveDate: '2022-02-16',
- }),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- // expected copy for plan changes
- expect(container).toHaveTextContent(
- 'This account has pending changes to the subscription'
- );
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Mar 16, 2022'
- );
- expect(container).toHaveTextContent('Plan changes — Developer → Team (Enterprise)');
- expect(container).toHaveTextContent('Contract period — monthly → annual');
- expect(container).toHaveTextContent('Billing period — monthly → annual');
- expect(container).toHaveTextContent('Reserved errors — 5,000 → 15,000,000 errors');
- expect(container).toHaveTextContent(
- 'Reserved transactions — 10,000 → 20,000,000 transactions'
- );
- expect(container).toHaveTextContent('Reserved attachments — 1 GB → 25 GB');
- expect(container).toHaveTextContent('Custom price (ACV) — $0.00 → $50,000.00');
- expect(container).toHaveTextContent('Custom price for errors — $0.00 → $20,000.00');
- expect(container).toHaveTextContent(
- 'Custom price for transactions — $0.00 → $29,000.00'
- );
- expect(container).toHaveTextContent('Custom price for attachments — $0.00 → $500.00');
- expect(container).toHaveTextContent('Custom price for PCSS — $0.00 → $500.00');
- // expected copy for on-demand changes
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Feb 16, 2022'
- );
- expect(container).toHaveTextContent('On-demand maximum — $0.00 → $500.00');
- });
- it('renders pending changes with all categories', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- customPrice: 0,
- customPricePcss: 0,
- pendingChanges: PendingChangesFixture({
- planDetails: PlanFixture({
- name: 'Team (Enterprise)',
- contractInterval: 'annual',
- billingInterval: 'annual',
- }),
- plan: 'am3_team_ent',
- planName: 'Team (Enterprise)',
- reservedEvents: 15000000,
- reservedErrors: 15000000,
- reservedTransactions: 0,
- reservedAttachments: 25,
- reserved: {errors: 15000000, spans: 20000000, attachments: 25},
- customPrice: 5000000,
- customPriceErrors: 2000000,
- customPriceTransactions: 0,
- customPriceAttachments: 50000,
- customPrices: {errors: 2000000, spans: 200000, attachments: 50000},
- customPricePcss: 50000,
- onDemandMaxSpend: 50000,
- effectiveDate: '2024-10-09',
- onDemandEffectiveDate: '2024-02-20',
- }),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- // expected copy for plan changes
- expect(container).toHaveTextContent(
- 'This account has pending changes to the subscription'
- );
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Oct 9, 2024'
- );
- expect(container).toHaveTextContent('Plan changes — Developer → Team (Enterprise)');
- expect(container).toHaveTextContent('Contract period — monthly → annual');
- expect(container).toHaveTextContent('Billing period — monthly → annual');
- expect(container).toHaveTextContent('Reserved errors — 5,000 → 15,000,000 errors');
- expect(container).toHaveTextContent(
- 'Reserved transactions — 10,000 → 0 transactions'
- );
- expect(container).toHaveTextContent('Reserved spans — 0 → 20,000,000 spans');
- expect(container).toHaveTextContent('Reserved attachments — 1 GB → 25 GB');
- expect(container).toHaveTextContent('Custom price (ACV) — $0.00 → $50,000.00');
- expect(container).toHaveTextContent('Custom price for errors — $0.00 → $20,000.00');
- expect(container).toHaveTextContent('Custom price for spans — $0.00 → $2,000.00');
- expect(container).toHaveTextContent('Custom price for attachments — $0.00 → $500.00');
- expect(container).toHaveTextContent('Custom price for PCSS — $0.00 → $500.00');
- // expected copy for on-demand changes
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Feb 20, 2024'
- );
- expect(container).toHaveTextContent('On-demand maximum — $0.00 → $500.00');
- });
- it('renders on-demand budgets', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- onDemandBudgets: {
- enabled: true,
- budgetMode: OnDemandBudgetMode.SHARED,
- sharedMaxBudget: 10000,
- onDemandSpendUsed: 0,
- },
- pendingChanges: PendingChangesFixture({
- planDetails: PlanFixture({
- name: 'Team (Enterprise)',
- contractInterval: 'annual',
- billingInterval: 'annual',
- onDemandCategories: ['errors', 'transactions', 'attachments'],
- }),
- onDemandBudgets: {
- enabled: true,
- budgetMode: OnDemandBudgetMode.PER_CATEGORY,
- errorsBudget: 300,
- transactionsBudget: 200,
- replaysBudget: 0,
- attachmentsBudget: 100,
- budgets: {errors: 300, transactions: 200, replays: 0, attachments: 100},
- },
- onDemandMaxSpend: 50000,
- effectiveDate: '2022-03-16',
- onDemandEffectiveDate: '2022-02-16',
- }),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- // expected copy for plan changes
- expect(container).toHaveTextContent(
- 'This account has pending changes to the subscription'
- );
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Mar 16, 2022'
- );
- // expected copy for on-demand changes
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Feb 16, 2022'
- );
- expect(container).toHaveTextContent(
- 'On-demand budget — shared on-demand of $100 → per-category on-demand (errors at $3, transactions at $2, and attachments at $1)'
- );
- });
- it('renders pending changes for plan migration', function () {
- const organization = OrganizationFixture();
- const am2BusinessPlan = PlanDetailsLookupFixture('am2_business_auf');
- const subscription = SubscriptionFixture({
- planDetails: am2BusinessPlan,
- plan: 'am2_business_auf',
- contractInterval: ANNUAL,
- organization,
- onDemandPeriodEnd: '2018-10-24',
- contractPeriodEnd: '2019-09-24',
- pendingChanges: PendingChangesFixture({
- planDetails: PlanFixture({
- id: 'am3_business_auf',
- name: 'Business',
- contractInterval: 'annual',
- billingInterval: 'annual',
- onDemandCategories: [
- 'errors',
- 'attachments',
- 'spans',
- 'replays',
- 'monitorSeats',
- ],
- }),
- reservedEvents: 50_000,
- reserved: {
- errors: 50_000,
- spans: 10_000_000,
- replays: 50,
- monitorSeats: 1,
- attachments: 1,
- },
- effectiveDate: '2019-09-25',
- onDemandEffectiveDate: '2018-10-25',
- }),
- });
- const migrationDate = '2018-10-25';
- const migration = PlanMigrationFixture({
- cohortId: CohortId.TENTH,
- effectiveAt: migrationDate,
- });
- jest
- .spyOn(usePlanMigrations, 'usePlanMigrations')
- .mockReturnValue({planMigrations: [migration], isLoading: false});
- const {container} = render(<PendingChanges subscription={subscription} />);
- // expected copy for plan changes
- expect(container).toHaveTextContent(
- 'This account has pending changes to the subscription'
- );
- expect(container).toHaveTextContent(
- 'The following changes will take effect on Oct 25, 2018'
- );
- expect(container).toHaveTextContent('Plan changes — Business → Business');
- expect(container).toHaveTextContent(
- 'Reserved performance units — 100,000 → 0 transactions'
- );
- expect(container).toHaveTextContent('Reserved replays — 500 → 50 replays');
- expect(container).toHaveTextContent('Reserved spans — 0 → 10,000,000 spans');
- // no actual changes
- expect(container).not.toHaveTextContent('Reserved errors — 50,000 → 50,000 errors');
- expect(container).not.toHaveTextContent(
- 'Reserved attachments — 1 GB → 1 GB attachments'
- );
- expect(container).not.toHaveTextContent(
- 'Reserved cron monitors — 1 → 1 cron monitor'
- );
- });
- it('renders reserved budgets with existing budgets', function () {
- const subscription = Am3DsEnterpriseSubscriptionFixture({
- organization: OrganizationFixture(),
- pendingChanges: PendingChangesFixture({
- planDetails: PlanDetailsLookupFixture('am3_business_ent_ds_auf'),
- plan: 'am3_business_ent_ds_auf',
- planName: 'Business',
- reserved: {
- spans: RESERVED_BUDGET_QUOTA,
- spansIndexed: RESERVED_BUDGET_QUOTA,
- },
- reservedCpe: {
- spans: 12.345678,
- spansIndexed: 87.654321,
- },
- reservedBudgets: [
- {
- reservedBudget: 50_000_00,
- categories: {spans: true, spansIndexed: true},
- },
- ],
- }),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- expect(container).not.toHaveTextContent('Plan changes —');
- expect(container).not.toHaveTextContent('Reserved spans —');
- expect(container).not.toHaveTextContent('Reserved accepted spans —');
- expect(container).not.toHaveTextContent('Reserved spansIndexed —');
- expect(container).not.toHaveTextContent('Reserved stored spans —');
- expect(container).toHaveTextContent(
- 'Reserved cost-per-event for accepted spans — $0.01000000 → $0.12345678'
- );
- expect(container).toHaveTextContent(
- 'Reserved cost-per-event for stored spans — $0.02000000 → $0.87654321'
- );
- expect(container).toHaveTextContent(
- 'Reserved budgets — $100,000.00 for accepted spans and stored spans → $50,000.00 for accepted spans and stored spans'
- );
- });
- it('renders reserved budgets without existing budgets', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- plan: 'am3_business',
- pendingChanges: PendingChangesFixture({
- planDetails: PlanDetailsLookupFixture('am3_business_ent_ds_auf'),
- plan: 'am3_business_ent_ds_auf',
- planName: 'Business',
- reserved: {
- spans: RESERVED_BUDGET_QUOTA,
- spansIndexed: RESERVED_BUDGET_QUOTA,
- },
- reservedCpe: {
- spans: 12.345678,
- spansIndexed: 87.654321,
- },
- reservedBudgets: [
- {
- reservedBudget: 50_000_00,
- categories: {spans: true, spansIndexed: true},
- },
- ],
- }),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- expect(container).toHaveTextContent('Plan changes — Business → Business');
- expect(container).toHaveTextContent(
- 'Reserved accepted spans — 10,000,000 → reserved budget'
- );
- expect(container).toHaveTextContent('Reserved stored spans — 0 → reserved budget');
- expect(container).not.toHaveTextContent('Reserved spans —');
- expect(container).not.toHaveTextContent('Reserved spansIndexed —');
- expect(container).toHaveTextContent(
- 'Reserved cost-per-event for accepted spans — None → $0.12345678'
- );
- expect(container).toHaveTextContent(
- 'Reserved cost-per-event for stored spans — None → $0.87654321'
- );
- expect(container).toHaveTextContent(
- 'Reserved budgets — None → $50,000.00 for accepted spans and stored spans'
- );
- });
- it('renders reserved budgets to reserved volume', function () {
- const subscription = Am3DsEnterpriseSubscriptionFixture({
- organization: OrganizationFixture(),
- pendingChanges: PendingChangesFixture({
- planDetails: PlanDetailsLookupFixture('am3_business_ent_auf'),
- plan: 'am3_business_ent_auf',
- planName: 'Business',
- reserved: {
- spans: 10_000_000,
- },
- }),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- expect(container).toHaveTextContent('Plan changes — Business → Business');
- expect(container).toHaveTextContent(
- 'Reserved accepted spans — reserved budget → 10,000,000 spans'
- );
- expect(container).toHaveTextContent(
- 'Reserved stored spans — reserved budget → 0 spansIndexed'
- );
- expect(container).not.toHaveTextContent('Reserved spans —');
- expect(container).not.toHaveTextContent('Reserved spansIndexed —');
- expect(container).toHaveTextContent(
- 'Reserved cost-per-event for spans — $0.01000000 → None'
- );
- expect(container).toHaveTextContent(
- 'Reserved cost-per-event for spansIndexed — $0.02000000 → None'
- );
- expect(container).toHaveTextContent(
- 'Reserved budgets — $100,000.00 for accepted spans and stored spans → None'
- );
- });
- it('does not render reserved budgets if there are no changes', function () {
- const subscription = SubscriptionFixture({
- organization: OrganizationFixture(),
- });
- const {container} = render(<PendingChanges subscription={subscription} />);
- expect(container).not.toHaveTextContent('Reserved budgets —');
- });
- });
|