import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
import {
openInviteMembersModal,
openTeamAccessRequestModal,
} from 'sentry/actionCreators/modal';
import {Client} from 'sentry/api';
import TeamMembers from 'sentry/views/settings/organizationTeams/teamMembers';
jest.mock('sentry/actionCreators/modal', () => ({
openInviteMembersModal: jest.fn(),
openTeamAccessRequestModal: jest.fn(),
}));
describe('TeamMembers', function () {
let createMock;
const organization = TestStubs.Organization();
const team = TestStubs.Team();
const members = TestStubs.Members();
const member = TestStubs.Member({
id: '9',
email: 'sentry9@test.com',
name: 'Sentry 9 Name',
});
beforeEach(function () {
Client.clearMockResponses();
Client.addMockResponse({
url: `/organizations/${organization.slug}/members/`,
method: 'GET',
body: [member],
});
Client.addMockResponse({
url: `/teams/${organization.slug}/${team.slug}/members/`,
method: 'GET',
body: members,
});
createMock = Client.addMockResponse({
url: `/organizations/${organization.slug}/members/${member.id}/teams/${team.slug}/`,
method: 'POST',
});
});
it('can add member to team with open membership', async function () {
const org = TestStubs.Organization({access: [], openMembership: true});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getAllByTestId('letter_avatar-avatar')[0]);
expect(createMock).toHaveBeenCalled();
});
it('can add member to team with team:admin permission', async function () {
const org = TestStubs.Organization({access: ['team:admin'], openMembership: false});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getAllByTestId('letter_avatar-avatar')[0]);
expect(createMock).toHaveBeenCalled();
});
it('can add member to team with org:write permission', async function () {
const org = TestStubs.Organization({access: ['org:write'], openMembership: false});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getAllByTestId('letter_avatar-avatar')[0]);
expect(createMock).toHaveBeenCalled();
});
it('can request access to add member to team without permission', async function () {
const org = TestStubs.Organization({access: [], openMembership: false});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getAllByTestId('letter_avatar-avatar')[0]);
expect(openTeamAccessRequestModal).toHaveBeenCalled();
});
it('can invite member from team dropdown with access', async function () {
const org = TestStubs.Organization({access: ['team:admin'], openMembership: false});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getByTestId('invite-member'));
expect(openInviteMembersModal).toHaveBeenCalled();
});
it('can invite member from team dropdown with access and `Open Membership` enabled', async function () {
const org = TestStubs.Organization({access: ['team:admin'], openMembership: true});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getByTestId('invite-member'));
expect(openInviteMembersModal).toHaveBeenCalled();
});
it('can invite member from team dropdown without access and `Open Membership` enabled', async function () {
const org = TestStubs.Organization({access: [], openMembership: true});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getByTestId('invite-member'));
expect(openInviteMembersModal).toHaveBeenCalled();
});
it('can invite member from team dropdown without access and `Open Membership` disabled', async function () {
const org = TestStubs.Organization({access: [], openMembership: false});
render(
);
userEvent.click((await screen.findAllByRole('button', {name: 'Add Member'}))[0]);
userEvent.click(screen.getByTestId('invite-member'));
expect(openInviteMembersModal).toHaveBeenCalled();
});
it('can remove member from team', async function () {
const deleteMock = Client.addMockResponse({
url: `/organizations/${organization.slug}/members/${members[0].id}/teams/${team.slug}/`,
method: 'DELETE',
});
render(
);
await screen.findAllByRole('button', {name: 'Add Member'});
expect(deleteMock).not.toHaveBeenCalled();
userEvent.click(screen.getAllByRole('button', {name: 'Remove'})[0]);
expect(deleteMock).toHaveBeenCalled();
});
it('can only remove self from team', async function () {
const me = TestStubs.Member({
id: '123',
email: 'foo@example.com',
});
Client.addMockResponse({
url: `/teams/${organization.slug}/${team.slug}/members/`,
method: 'GET',
body: [...members, me],
});
const deleteMock = Client.addMockResponse({
url: `/organizations/${organization.slug}/members/${me.id}/teams/${team.slug}/`,
method: 'DELETE',
});
const organizationMember = TestStubs.Organization({access: []});
render(
);
await screen.findAllByRole('button', {name: 'Add Member'});
expect(deleteMock).not.toHaveBeenCalled();
expect(screen.getAllByTestId('letter_avatar-avatar')).toHaveLength(
members.length + 1
);
// Can only remove self
expect(screen.getByRole('button', {name: 'Remove'})).toBeInTheDocument();
userEvent.click(screen.getByRole('button', {name: 'Remove'}));
expect(deleteMock).toHaveBeenCalled();
});
it('does not renders team-level roles', async function () {
const me = TestStubs.Member({
id: '123',
email: 'foo@example.com',
role: 'owner',
});
Client.addMockResponse({
url: `/teams/${organization.slug}/${team.slug}/members/`,
method: 'GET',
body: [...members, me],
});
await render(
);
const admins = screen.queryByText('Team Admin');
expect(admins).not.toBeInTheDocument();
const contributors = screen.queryByText('Team Contributor');
expect(contributors).not.toBeInTheDocument();
});
it('renders team-level roles with flag', async function () {
const manager = TestStubs.Member({
id: '123',
email: 'foo@example.com',
orgRole: 'manager',
});
Client.addMockResponse({
url: `/teams/${organization.slug}/${team.slug}/members/`,
method: 'GET',
body: [...members, manager],
});
const orgWithTeamRoles = TestStubs.Organization({features: ['team-roles']});
await render(
);
const admins = screen.queryAllByText('Team Admin');
expect(admins).toHaveLength(3);
const contributors = screen.queryAllByText('Contributor');
expect(contributors).toHaveLength(2);
});
});