import {OrganizationFixture} from 'sentry-fixture/organization';
import {RouteComponentPropsFixture} from 'sentry-fixture/routeComponentPropsFixture';
import {SubscriptionFixture} from 'getsentry-test/fixtures/subscription';
import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import SubscriptionStore from 'getsentry/stores/subscriptionStore';
import Notifications from 'getsentry/views/subscriptionPage/notifications';
describe('Subscription > Notifications', function () {
const organization = OrganizationFixture({
slug: 'chum-bucket',
});
const subscription = SubscriptionFixture({organization});
beforeEach(function () {
MockApiClient.clearMockResponses();
MockApiClient.addMockResponse({
url: `/customers/${organization.slug}/spend-notifications/`,
method: 'GET',
body: {reservedPercent: [90], perProductOndemandPercent: [80, 50]},
});
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/promotions/trigger-check/`,
method: 'POST',
});
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/members/`,
method: 'GET',
body: [],
});
MockApiClient.addMockResponse({
url: `/organizations/org-slug/members/`,
method: 'GET',
body: [],
});
MockApiClient.addMockResponse({
url: `/organizations/${organization.slug}/prompts-activity/`,
body: {},
});
organization.access = ['org:billing'];
subscription.planDetails.allowOnDemand = false;
SubscriptionStore.set(organization.slug, subscription);
});
it('renders', async function () {
render(
);
expect(
await screen.findByText(
"Configure the thresholds for your organization's spend notifications."
)
).toBeInTheDocument();
expect(screen.getByText('Subscription Consumption')).toBeInTheDocument();
expect(screen.getByText('90%')).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', {name: '90%'}));
// 90% is selected so it is not one of the options
const expectedOptions = ['80%', '70%', '60%', '50%', '40%', '30%', '20%', '10%'];
const actualOptions = screen.getAllByTestId('menu-list-item-label');
expect(actualOptions).toHaveLength(expectedOptions.length);
actualOptions.forEach((element, idx) => {
expect(element).toHaveTextContent(expectedOptions[idx]!);
});
expect(screen.queryByText('On-Demand Consumption')).not.toBeInTheDocument();
expect(screen.getByRole('button', {name: 'Reset'})).toBeDisabled();
expect(screen.getByRole('button', {name: 'Save Changes'})).toBeDisabled();
});
it('renders an error for non-billing users', async function () {
organization.access = [];
render(
);
expect(await screen.findByTestId('permission-denied')).toBeInTheDocument();
expect(
screen.queryByText(
"Configure the thresholds for your organization's spend notifications."
)
).not.toBeInTheDocument();
});
it('renders On-Demand Consumption if on-demand is enabled', async function () {
subscription.planDetails.allowOnDemand = true;
SubscriptionStore.set(organization.slug, subscription);
render(
);
expect(
await screen.findByText(
"Configure the thresholds for your organization's spend notifications."
)
).toBeInTheDocument();
expect(screen.getByText('Subscription Consumption')).toBeInTheDocument();
expect(screen.getByText('90%')).toBeInTheDocument();
expect(screen.getByText('On-Demand Consumption')).toBeInTheDocument();
expect(screen.getByText('80%')).toBeInTheDocument();
expect(screen.getByText('50%')).toBeInTheDocument();
});
it('enables delete button if there is more than two thresholds for a section', async function () {
subscription.planDetails.allowOnDemand = true;
SubscriptionStore.set(organization.slug, subscription);
render(
);
expect(await screen.findByText('90%')).toBeInTheDocument();
const deleteButtons = screen.getAllByRole('button', {
name: 'Remove notification threshold',
});
expect(deleteButtons).toHaveLength(3);
expect(deleteButtons[0]).toBeDisabled();
expect(screen.getByText('80%')).toBeInTheDocument();
expect(screen.getByText('50%')).toBeInTheDocument();
expect(deleteButtons[1]).toBeEnabled();
expect(deleteButtons[2]).toBeEnabled();
});
it('allows 9 thresholds per section max', async function () {
render(
);
expect(await screen.findByText('90%')).toBeInTheDocument();
const clickOptions = {skipHover: true, delay: null};
for (const percentage of ['80%', '70%', '60%', '50%', '40%', '30%', '20%', '10%']) {
await userEvent.click(
screen.getByRole('button', {name: 'Add threshold'}),
clickOptions
);
await userEvent.click(screen.getByRole('option', {name: percentage}), clickOptions);
await userEvent.click(
screen.getByRole('button', {name: 'Add notification threshold'}),
clickOptions
);
expect(screen.getByText(percentage)).toBeInTheDocument();
}
expect(screen.queryByText('Add threshold')).not.toBeInTheDocument();
});
it('reverts to saved thresholds on reset', async function () {
render(
);
expect(await screen.findByText('90%')).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', {name: 'Add threshold'}));
await userEvent.click(screen.getByRole('option', {name: '70%'}));
await userEvent.click(
screen.getByRole('button', {name: 'Add notification threshold'})
);
expect(screen.getByText('70%')).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', {name: 'Add threshold'}));
await userEvent.click(screen.getByRole('option', {name: '50%'}));
await userEvent.click(
screen.getByRole('button', {name: 'Add notification threshold'})
);
expect(screen.getByText('50%')).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', {name: 'Reset'}));
expect(screen.getByText('90%')).toBeInTheDocument();
expect(screen.queryByText('70%')).not.toBeInTheDocument();
expect(screen.queryByText('50%')).not.toBeInTheDocument();
});
it('calls api with correct args', async () => {
const postMock = MockApiClient.addMockResponse({
url: `/customers/${organization.slug}/spend-notifications/`,
method: 'POST',
body: {reservedPercent: [90, 60], perProductOndemandPercent: [80, 50]},
});
render(
);
expect(await screen.findByText('90%')).toBeInTheDocument();
await userEvent.click(screen.getByRole('button', {name: 'Add threshold'}));
await userEvent.click(screen.getByRole('option', {name: '60%'}));
await userEvent.click(
screen.getByRole('button', {name: 'Add notification threshold'})
);
await userEvent.click(screen.getByRole('button', {name: 'Save Changes'}));
expect(postMock).toHaveBeenCalledWith(
`/customers/${organization.slug}/spend-notifications/`,
expect.objectContaining({
method: 'POST',
data: {
reservedPercent: [90, 60],
perProductOndemandPercent: [80, 50],
},
})
);
});
});