mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
414 lines
12 KiB
TypeScript
414 lines
12 KiB
TypeScript
import {OrganizationFixture} from 'sentry-fixture/organization';
|
|
import {ProjectFixture} from 'sentry-fixture/project';
|
|
import {TeamFixture} from 'sentry-fixture/team';
|
|
import {UserFixture} from 'sentry-fixture/user';
|
|
|
|
import {act, render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
|
|
|
|
import ProjectsStore from 'sentry/stores/projectsStore';
|
|
import TeamStore from 'sentry/stores/teamStore';
|
|
import EventView from 'sentry/utils/discover/eventView';
|
|
import {MAX_TEAM_KEY_TRANSACTIONS} from 'sentry/utils/performance/constants';
|
|
import TeamKeyTransactionButton from 'sentry/views/performance/transactionSummary/teamKeyTransactionButton';
|
|
|
|
async function clickTeamKeyTransactionDropdown() {
|
|
await waitFor(() =>
|
|
expect(screen.getByRole('button', {expanded: false})).toBeEnabled()
|
|
);
|
|
await userEvent.click(screen.getByRole('button', {expanded: false}));
|
|
}
|
|
|
|
describe('TeamKeyTransactionButton', function () {
|
|
const organization = OrganizationFixture({features: ['performance-view']});
|
|
const teams = [
|
|
TeamFixture({id: '1', slug: 'team1', name: 'Team 1'}),
|
|
TeamFixture({id: '2', slug: 'team2', name: 'Team 2'}),
|
|
];
|
|
const project = ProjectFixture({teams});
|
|
const eventView = new EventView({
|
|
id: '1',
|
|
name: 'my query',
|
|
fields: [{field: 'count()'}],
|
|
sorts: [{field: 'count', kind: 'desc'}],
|
|
query: '',
|
|
project: [parseInt(project.id, 10)],
|
|
start: '2019-10-01T00:00:00',
|
|
end: '2019-10-02T00:00:00',
|
|
statsPeriod: '14d',
|
|
environment: [],
|
|
createdBy: UserFixture(),
|
|
display: 'line',
|
|
team: ['myteams'],
|
|
topEvents: '5',
|
|
});
|
|
|
|
beforeEach(function () {
|
|
MockApiClient.clearMockResponses();
|
|
act(() => ProjectsStore.loadInitialData([project]));
|
|
act(() => void TeamStore.loadInitialData(teams, false, null));
|
|
});
|
|
|
|
it('fetches key transactions with project param', function () {
|
|
const getTeamKeyTransactionsMock = MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 1,
|
|
keyed: [{project_id: String(project.id), transaction: 'transaction'}],
|
|
})),
|
|
match: [MockApiClient.matchQuery({project: [project.id], team: ['myteams']})],
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
expect(getTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('renders with all teams checked', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 1,
|
|
keyed: [{project_id: String(project.id), transaction: 'transaction'}],
|
|
})),
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
// all teams should be checked
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
});
|
|
|
|
it('renders with some teams checked', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: id === teams[0].id ? 1 : 0,
|
|
keyed:
|
|
id === teams[0].id
|
|
? [{project_id: String(project.id), transaction: 'transaction'}]
|
|
: [],
|
|
})),
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
// only team 1 should be checked
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'false'
|
|
);
|
|
});
|
|
|
|
it('renders with no teams checked', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 0,
|
|
keyed: [],
|
|
})),
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
// all teams should be unchecked
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'false'
|
|
);
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'false'
|
|
);
|
|
});
|
|
|
|
it('should be able to check one team', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 0,
|
|
keyed: [],
|
|
})),
|
|
});
|
|
|
|
const postTeamKeyTransactionsMock = MockApiClient.addMockResponse({
|
|
method: 'POST',
|
|
url: '/organizations/org-slug/key-transactions/',
|
|
body: [],
|
|
match: [
|
|
MockApiClient.matchQuery({project: [project.id]}),
|
|
MockApiClient.matchData({team: [teams[0].id], transaction: 'transaction'}),
|
|
],
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
await userEvent.click(screen.getByRole('option', {name: `#${teams[0].slug}`}));
|
|
expect(postTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should be able to uncheck one team', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 1,
|
|
keyed: [{project_id: String(project.id), transaction: 'transaction'}],
|
|
})),
|
|
});
|
|
|
|
const deleteTeamKeyTransactionsMock = MockApiClient.addMockResponse({
|
|
method: 'DELETE',
|
|
url: '/organizations/org-slug/key-transactions/',
|
|
body: [],
|
|
match: [
|
|
MockApiClient.matchQuery({project: [project.id]}),
|
|
MockApiClient.matchData({team: [teams[0].id], transaction: 'transaction'}),
|
|
],
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
await userEvent.click(screen.getByRole('option', {name: `#${teams[0].slug}`}));
|
|
expect(deleteTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should be able to check all with my teams', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 0,
|
|
keyed: [],
|
|
})),
|
|
});
|
|
|
|
const postTeamKeyTransactionsMock = MockApiClient.addMockResponse({
|
|
method: 'POST',
|
|
url: '/organizations/org-slug/key-transactions/',
|
|
body: [],
|
|
match: [
|
|
MockApiClient.matchQuery({project: [project.id]}),
|
|
MockApiClient.matchData({
|
|
team: [teams[0].id, teams[1].id],
|
|
transaction: 'transaction',
|
|
}),
|
|
],
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
await userEvent.click(screen.getByRole('button', {name: 'Select All in My Teams'}));
|
|
|
|
// all teams should be checked now
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
|
|
expect(postTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('should be able to uncheck all with my teams', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: 1,
|
|
keyed: [{project_id: String(project.id), transaction: 'transaction'}],
|
|
})),
|
|
});
|
|
|
|
const deleteTeamKeyTransactionsMock = MockApiClient.addMockResponse({
|
|
method: 'DELETE',
|
|
url: '/organizations/org-slug/key-transactions/',
|
|
body: [],
|
|
match: [
|
|
MockApiClient.matchQuery({project: [project.id]}),
|
|
MockApiClient.matchData({
|
|
team: [teams[0].id, teams[1].id],
|
|
transaction: 'transaction',
|
|
}),
|
|
],
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
await userEvent.click(screen.getByRole('button', {name: 'Unselect All in My Teams'}));
|
|
|
|
// all teams should be checked now
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'false'
|
|
);
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'false'
|
|
);
|
|
|
|
expect(deleteTeamKeyTransactionsMock).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it('renders unkeyed as disabled if count exceeds max', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: MAX_TEAM_KEY_TRANSACTIONS,
|
|
keyed: Array.from({length: MAX_TEAM_KEY_TRANSACTIONS}, (_, i) => ({
|
|
project_id: String(project.id),
|
|
transaction: `transaction-${i}`,
|
|
})),
|
|
})),
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-disabled',
|
|
'true'
|
|
);
|
|
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-disabled',
|
|
'true'
|
|
);
|
|
});
|
|
|
|
it('renders keyed as checked even if count is maxed', async function () {
|
|
MockApiClient.addMockResponse({
|
|
method: 'GET',
|
|
url: '/organizations/org-slug/key-transactions-list/',
|
|
body: teams.map(({id}) => ({
|
|
team: id,
|
|
count: MAX_TEAM_KEY_TRANSACTIONS,
|
|
keyed: [
|
|
{project_id: String(project.id), transaction: 'transaction'},
|
|
...Array.from({length: MAX_TEAM_KEY_TRANSACTIONS - 1}, (_, i) => ({
|
|
project_id: String(project.id),
|
|
transaction: `transaction-${i}`,
|
|
})),
|
|
],
|
|
})),
|
|
});
|
|
|
|
render(
|
|
<TeamKeyTransactionButton
|
|
eventView={eventView}
|
|
organization={organization}
|
|
transactionName="transaction"
|
|
/>
|
|
);
|
|
|
|
await clickTeamKeyTransactionDropdown();
|
|
|
|
expect(screen.getByRole('option', {name: `#${teams[0].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
|
|
expect(screen.getByRole('option', {name: `#${teams[1].slug}`})).toHaveAttribute(
|
|
'aria-selected',
|
|
'true'
|
|
);
|
|
});
|
|
});
|