123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401 |
- import React from 'react';
- import {browserHistory} from 'react-router';
- import {Client} from 'app/api';
- import {mount} from 'enzyme';
- import ConfigStore from 'app/stores/configStore';
- import OrganizationMembers from 'app/views/settings/organizationMembers';
- import OrganizationsStore from 'app/stores/organizationsStore';
- import {addSuccessMessage, addErrorMessage} from 'app/actionCreators/indicator';
- jest.mock('app/api');
- jest.mock('app/actionCreators/indicator');
- describe('OrganizationMembers', function() {
- let members = TestStubs.Members();
- let currentUser = members[1];
- let defaultProps = {
- orgId: 'org-slug',
- orgName: 'Organization Name',
- status: '',
- routes: [],
- requireLink: false,
- memberCanLeave: false,
- canAddMembers: false,
- canRemoveMembers: false,
- currentUser,
- onSendInvite: () => {},
- onRemove: () => {},
- onLeave: () => {},
- };
- let organization = TestStubs.Organization({
- access: ['member:admin', 'org:admin'],
- status: {
- id: 'active',
- },
- });
- let getStub;
- beforeAll(function() {
- getStub = sinon
- .stub(ConfigStore, 'get')
- .withArgs('user')
- .returns(currentUser);
- });
- afterAll(function() {
- getStub.restore();
- });
- beforeEach(function() {
- Client.clearMockResponses();
- Client.addMockResponse({
- url: '/organizations/org-id/members/',
- method: 'GET',
- body: TestStubs.Members(),
- });
- Client.addMockResponse({
- url: '/organizations/org-id/access-requests/',
- method: 'GET',
- body: [
- {
- id: 'pending-id',
- member: {
- id: 'pending-member-id',
- email: '',
- name: '',
- role: '',
- roleName: '',
- user: {
- id: '',
- name: 'sentry@test.com',
- },
- },
- team: TestStubs.Team(),
- },
- ],
- });
- Client.addMockResponse({
- url: '/organizations/org-id/auth-provider/',
- method: 'GET',
- body: {
- ...TestStubs.AuthProvider(),
- require_link: true,
- },
- });
- browserHistory.push.mockReset();
- OrganizationsStore.load([organization]);
- });
- it('can remove a member', async function() {
- let deleteMock = Client.addMockResponse({
- url: `/organizations/org-id/members/${members[0].id}/`,
- method: 'DELETE',
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext([{organization}])
- );
- wrapper
- .find('Button[icon="icon-circle-subtract"]')
- .at(0)
- .simulate('click');
- await tick();
- // Confirm modal
- wrapper.find('ModalDialog Button[priority="primary"]').simulate('click');
- await tick();
- expect(deleteMock).toHaveBeenCalled();
- expect(addSuccessMessage).toHaveBeenCalled();
- expect(browserHistory.push).not.toHaveBeenCalled();
- expect(OrganizationsStore.getAll()).toEqual([organization]);
- });
- it('displays error message when failing to remove member', async function() {
- let deleteMock = Client.addMockResponse({
- url: `/organizations/org-id/members/${members[0].id}/`,
- method: 'DELETE',
- statusCode: 500,
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext([{organization}])
- );
- wrapper
- .find('Button[icon="icon-circle-subtract"]')
- .at(0)
- .simulate('click');
- await tick();
- // Confirm modal
- wrapper.find('ModalDialog Button[priority="primary"]').simulate('click');
- await tick();
- expect(deleteMock).toHaveBeenCalled();
- await tick();
- expect(addErrorMessage).toHaveBeenCalled();
- expect(browserHistory.push).not.toHaveBeenCalled();
- expect(OrganizationsStore.getAll()).toEqual([organization]);
- });
- it('can leave org', async function() {
- let deleteMock = Client.addMockResponse({
- url: `/organizations/org-id/members/${members[1].id}/`,
- method: 'DELETE',
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext([{organization}])
- );
- wrapper
- .find('Button[priority="danger"]')
- .at(0)
- .simulate('click');
- await tick();
- // Confirm modal
- wrapper.find('ModalDialog Button[priority="primary"]').simulate('click');
- await tick();
- expect(deleteMock).toHaveBeenCalled();
- expect(addSuccessMessage).toHaveBeenCalled();
- expect(browserHistory.push).toHaveBeenCalledTimes(1);
- expect(browserHistory.push).toHaveBeenCalledWith('/organizations/new/');
- });
- it('can redirect to remaining org after leaving', async function() {
- let deleteMock = Client.addMockResponse({
- url: `/organizations/org-id/members/${members[1].id}/`,
- method: 'DELETE',
- });
- let secondOrg = TestStubs.Organization({
- slug: 'org-two',
- status: {
- id: 'active',
- },
- });
- OrganizationsStore.add(secondOrg);
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext([{organization}])
- );
- wrapper
- .find('Button[priority="danger"]')
- .at(0)
- .simulate('click');
- await tick();
- // Confirm modal
- wrapper.find('ModalDialog Button[priority="primary"]').simulate('click');
- await tick();
- expect(deleteMock).toHaveBeenCalled();
- expect(addSuccessMessage).toHaveBeenCalled();
- expect(browserHistory.push).toHaveBeenCalledTimes(1);
- expect(browserHistory.push).toHaveBeenCalledWith(`/${secondOrg.slug}/`);
- expect(OrganizationsStore.getAll()).toEqual([secondOrg]);
- });
- it('displays error message when failing to leave org', async function() {
- let deleteMock = Client.addMockResponse({
- url: `/organizations/org-id/members/${members[1].id}/`,
- method: 'DELETE',
- statusCode: 500,
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext([{organization}])
- );
- wrapper
- .find('Button[priority="danger"]')
- .at(0)
- .simulate('click');
- await tick();
- // Confirm modal
- wrapper.find('ModalDialog Button[priority="primary"]').simulate('click');
- await tick();
- expect(deleteMock).toHaveBeenCalled();
- await tick();
- expect(addErrorMessage).toHaveBeenCalled();
- expect(browserHistory.push).not.toHaveBeenCalled();
- expect(OrganizationsStore.getAll()).toEqual([organization]);
- });
- it('can re-send invite to member', async function() {
- let inviteMock = MockApiClient.addMockResponse({
- url: `/organizations/org-id/members/${members[0].id}/`,
- method: 'PUT',
- body: {
- id: '1234',
- },
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext()
- );
- expect(inviteMock).not.toHaveBeenCalled();
- wrapper
- .find('ResendInviteButton')
- .first()
- .simulate('click');
- await tick();
- expect(inviteMock).toHaveBeenCalled();
- });
- it('can approve pending access request', async function() {
- let approveMock = MockApiClient.addMockResponse({
- url: '/organizations/org-id/access-requests/pending-id/',
- method: 'PUT',
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext()
- );
- expect(approveMock).not.toHaveBeenCalled();
- wrapper
- .find('OrganizationAccessRequests Button[priority="primary"]')
- .simulate('click');
- await tick();
- expect(approveMock).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({
- data: {
- isApproved: true,
- },
- })
- );
- });
- it('can deny pending access request', async function() {
- let denyMock = MockApiClient.addMockResponse({
- url: '/organizations/org-id/access-requests/pending-id/',
- method: 'PUT',
- });
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- params={{
- orgId: 'org-id',
- }}
- />,
- TestStubs.routerContext()
- );
- expect(denyMock).not.toHaveBeenCalled();
- wrapper
- .find('OrganizationAccessRequests Button')
- .at(1)
- .simulate('click');
- await tick();
- expect(denyMock).toHaveBeenCalledWith(
- expect.anything(),
- expect.objectContaining({
- data: {
- isApproved: false,
- },
- })
- );
- });
- it('can search organization members', async function() {
- let searchMock = MockApiClient.addMockResponse({
- url: '/organizations/org-id/members/',
- body: [],
- });
- let routerContext = TestStubs.routerContext();
- let wrapper = mount(
- <OrganizationMembers
- {...defaultProps}
- location={{}}
- params={{
- orgId: 'org-id',
- }}
- />,
- routerContext
- );
- wrapper
- .find('AsyncComponentSearchInput input')
- .simulate('change', {target: {value: 'member'}});
- expect(searchMock).toHaveBeenLastCalledWith(
- '/organizations/org-id/members/',
- expect.objectContaining({
- method: 'GET',
- query: {
- query: 'member',
- },
- })
- );
- wrapper.find('PanelHeader form').simulate('submit');
- expect(routerContext.context.router.push).toHaveBeenCalledTimes(1);
- });
- });
|