TeamMemberRow: Convert tests to RTL (#49875)

* TeamMemberRow: Remove legacy select

* TeamMemberRow: Update attributes

* TeamMemberRow: Refactor tests to RTL
This commit is contained in:
Alex Khomenko 2022-05-31 11:33:27 +03:00 committed by GitHub
parent 387267b30a
commit bfbe856319
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 363 deletions

View File

@ -170,9 +170,6 @@ exports[`no enzyme tests`] = {
"public/app/features/org/OrgProfile.test.tsx:623809345": [ "public/app/features/org/OrgProfile.test.tsx:623809345": [
[0, 19, 13, "RegExp match", "2409514259"] [0, 19, 13, "RegExp match", "2409514259"]
], ],
"public/app/features/teams/TeamMemberRow.test.tsx:1649328210": [
[0, 19, 13, "RegExp match", "2409514259"]
],
"public/app/features/teams/TeamMembers.test.tsx:4089428239": [ "public/app/features/teams/TeamMembers.test.tsx:4089428239": [
[0, 19, 13, "RegExp match", "2409514259"] [0, 19, 13, "RegExp match", "2409514259"]
], ],

View File

@ -1,9 +1,8 @@
import { shallow } from 'enzyme'; import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import React from 'react'; import React from 'react';
import { SelectableValue } from '@grafana/data'; import { TeamPermissionLevel } from '../../types';
import { TeamMember, TeamPermissionLevel } from '../../types';
import { TeamMemberRow, Props } from './TeamMemberRow'; import { TeamMemberRow, Props } from './TeamMemberRow';
import { getMockTeamMember } from './__mocks__/teamMocks'; import { getMockTeamMember } from './__mocks__/teamMocks';
@ -20,75 +19,60 @@ const setup = (propOverrides?: object) => {
Object.assign(props, propOverrides); Object.assign(props, propOverrides);
const wrapper = shallow(<TeamMemberRow {...props} />); render(
const instance = wrapper.instance() as TeamMemberRow; <table>
<tbody>
return { <TeamMemberRow {...props} />
wrapper, </tbody>
instance, </table>
}; );
}; };
describe('Render', () => { describe('Render', () => {
it('should render team members when sync enabled', () => { it('should render team member labels when sync enabled', () => {
const member = getMockTeamMember(); const member = getMockTeamMember();
member.labels = ['LDAP']; member.labels = ['LDAP'];
const { wrapper } = setup({ member, syncEnabled: true }); setup({ member, syncEnabled: true });
expect(screen.getByText('LDAP')).toBeInTheDocument();
expect(wrapper).toMatchSnapshot();
}); });
describe('when feature toggle editorsCanAdmin is turned on', () => { describe('when feature toggle editorsCanAdmin is turned on', () => {
it('should render permissions select if user is team admin', () => { it('should render permissions select if user is team admin', () => {
const { wrapper } = setup({ editorsCanAdmin: true, signedInUserIsTeamAdmin: true }); const member = getMockTeamMember();
setup({ editorsCanAdmin: true, signedInUserIsTeamAdmin: true, member });
expect(wrapper).toMatchSnapshot(); expect(screen.getByLabelText(`Select member's ${member.name} permission level`)).toBeInTheDocument();
});
it('should render span and disable buttons if user is team member', () => {
const { wrapper } = setup({ editorsCanAdmin: true, signedInUserIsTeamAdmin: false });
expect(wrapper).toMatchSnapshot();
}); });
}); });
describe('when feature toggle editorsCanAdmin is turned off', () => { describe('when feature toggle editorsCanAdmin is turned off', () => {
it('should not render permissions', () => { it('should not render permissions', () => {
const { wrapper } = setup({ editorsCanAdmin: false, signedInUserIsTeamAdmin: true }); const member = getMockTeamMember();
setup({ editorsCanAdmin: false, signedInUserIsTeamAdmin: true, member });
expect(wrapper).toMatchSnapshot(); expect(screen.queryByLabelText(`Select member's ${member.name} permission level`)).not.toBeInTheDocument();
}); });
}); });
}); });
describe('Functions', () => { describe('Functions', () => {
describe('on remove member', () => { it('should remove member on remove button click', async () => {
const member = getMockTeamMember(); const member = getMockTeamMember();
const { instance } = setup({ member }); const mockRemove = jest.fn();
setup({ member, removeTeamMember: mockRemove, editorsCanAdmin: true, signedInUserIsTeamAdmin: true });
await userEvent.click(screen.getByRole('button', { name: `Remove team member ${member.name}` }));
await userEvent.click(screen.getByRole('button', { name: 'Delete' }));
instance.onRemoveMember(member); expect(mockRemove).toHaveBeenCalledWith(member.userId);
expect(instance.props.removeTeamMember).toHaveBeenCalledWith(1);
}); });
describe('on update permision for user in team', () => { it('should update permission for user in team', async () => {
const member: TeamMember = { const member = getMockTeamMember();
userId: 3, const mockUpdate = jest.fn();
teamId: 2, setup({ member, editorsCanAdmin: true, signedInUserIsTeamAdmin: true, updateTeamMember: mockUpdate });
avatarUrl: '',
email: 'user@user.org',
login: 'member',
name: 'member',
labels: [],
permission: TeamPermissionLevel.Member,
};
const { instance } = setup({ member });
const permission = TeamPermissionLevel.Admin; const permission = TeamPermissionLevel.Admin;
const item: SelectableValue<TeamPermissionLevel> = { value: permission }; const expectedTeamMember = { ...member, permission };
const expectedTeamMemeber = { ...member, permission }; await userEvent.click(screen.getByLabelText(`Select member's ${member.name} permission level`));
await userEvent.click(screen.getByText('Admin'));
instance.onPermissionChange(item, member); expect(mockUpdate).toHaveBeenCalledWith(expectedTeamMember);
expect(instance.props.updateTeamMember).toHaveBeenCalledWith(expectedTeamMemeber);
}); });
}); });

View File

@ -2,15 +2,13 @@ import React, { PureComponent } from 'react';
import { connect, ConnectedProps } from 'react-redux'; import { connect, ConnectedProps } from 'react-redux';
import { SelectableValue } from '@grafana/data'; import { SelectableValue } from '@grafana/data';
import { LegacyForms, DeleteButton } from '@grafana/ui'; import { Select, DeleteButton } from '@grafana/ui';
import { TagBadge } from 'app/core/components/TagFilter/TagBadge'; import { TagBadge } from 'app/core/components/TagFilter/TagBadge';
import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle'; import { WithFeatureToggle } from 'app/core/components/WithFeatureToggle';
import { TeamMember, teamsPermissionLevels, TeamPermissionLevel } from 'app/types'; import { TeamMember, teamsPermissionLevels, TeamPermissionLevel } from 'app/types';
import { updateTeamMember, removeTeamMember } from './state/actions'; import { updateTeamMember, removeTeamMember } from './state/actions';
const { Select } = LegacyForms;
const mapDispatchToProps = { const mapDispatchToProps = {
removeTeamMember, removeTeamMember,
updateTeamMember, updateTeamMember,
@ -54,18 +52,18 @@ export class TeamMemberRow extends PureComponent<Props> {
return ( return (
<WithFeatureToggle featureToggle={editorsCanAdmin}> <WithFeatureToggle featureToggle={editorsCanAdmin}>
<td className="width-5 team-permissions"> <td className="width-5 team-permissions">
<div className="gf-form"> {signedInUserIsTeamAdmin ? (
{signedInUserIsTeamAdmin && ( <Select
<Select isSearchable={false}
isSearchable={false} options={teamsPermissionLevels}
options={teamsPermissionLevels} onChange={(item) => this.onPermissionChange(item, member)}
onChange={(item) => this.onPermissionChange(item, member)} value={value}
className="gf-form-select-box__control--menu-right" width={32}
value={value} aria-label={`Select member's ${member.name} permission level`}
/> />
)} ) : (
{!signedInUserIsTeamAdmin && <span>{value.label}</span>} <span>{value.label}</span>
</div> )}
</td> </td>
</WithFeatureToggle> </WithFeatureToggle>
); );
@ -91,7 +89,7 @@ export class TeamMemberRow extends PureComponent<Props> {
<tr key={member.userId}> <tr key={member.userId}>
<td className="width-4 text-center"> <td className="width-4 text-center">
<img <img
aria-label={`Avatar for team member "${member.name}"`} alt={`Avatar for team member "${member.name}"`}
className="filter-table__avatar" className="filter-table__avatar"
src={member.avatarUrl} src={member.avatarUrl}
/> />
@ -103,7 +101,7 @@ export class TeamMemberRow extends PureComponent<Props> {
{syncEnabled && this.renderLabels(member.labels)} {syncEnabled && this.renderLabels(member.labels)}
<td className="text-right"> <td className="text-right">
<DeleteButton <DeleteButton
aria-label="Remove team member" aria-label={`Remove team member ${member.name}`}
size="sm" size="sm"
disabled={!signedInUserIsTeamAdmin} disabled={!signedInUserIsTeamAdmin}
onConfirm={() => this.onRemoveMember(member)} onConfirm={() => this.onRemoveMember(member)}

View File

@ -1,294 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render team members when sync enabled 1`] = `
<tr
key="1"
>
<td
className="width-4 text-center"
>
<img
aria-label="Avatar for team member \\"testName\\""
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser
</td>
<td>
test@test.com
</td>
<td>
testName
</td>
<WithFeatureToggle
featureToggle={false}
>
<td
className="width-5 team-permissions"
>
<div
className="gf-form"
>
<span>
Member
</span>
</div>
</td>
</WithFeatureToggle>
<td>
<TagBadge
count={0}
key="LDAP"
label="LDAP"
onClick={[Function]}
removeIcon={false}
/>
</td>
<td
className="text-right"
>
<DeleteButton
aria-label="Remove team member"
disabled={true}
onConfirm={[Function]}
size="sm"
/>
</td>
</tr>
`;
exports[`Render when feature toggle editorsCanAdmin is turned off should not render permissions 1`] = `
<tr
key="1"
>
<td
className="width-4 text-center"
>
<img
aria-label="Avatar for team member \\"testName\\""
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser
</td>
<td>
test@test.com
</td>
<td>
testName
</td>
<WithFeatureToggle
featureToggle={false}
>
<td
className="width-5 team-permissions"
>
<div
className="gf-form"
>
<Select
allowCustomValue={false}
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
components={
Object {
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": [Function],
"SingleValue": [Function],
}
}
isClearable={false}
isDisabled={false}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions, members and delete team.",
"label": "Admin",
"value": 4,
},
]
}
tabSelectsValue={true}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
/>
</div>
</td>
</WithFeatureToggle>
<td
className="text-right"
>
<DeleteButton
aria-label="Remove team member"
disabled={false}
onConfirm={[Function]}
size="sm"
/>
</td>
</tr>
`;
exports[`Render when feature toggle editorsCanAdmin is turned on should render permissions select if user is team admin 1`] = `
<tr
key="1"
>
<td
className="width-4 text-center"
>
<img
aria-label="Avatar for team member \\"testName\\""
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser
</td>
<td>
test@test.com
</td>
<td>
testName
</td>
<WithFeatureToggle
featureToggle={true}
>
<td
className="width-5 team-permissions"
>
<div
className="gf-form"
>
<Select
allowCustomValue={false}
autoFocus={false}
backspaceRemovesValue={true}
className="gf-form-select-box__control--menu-right"
components={
Object {
"Group": [Function],
"IndicatorsContainer": [Function],
"MenuList": [Function],
"Option": [Function],
"SingleValue": [Function],
}
}
isClearable={false}
isDisabled={false}
isLoading={false}
isMulti={false}
isSearchable={false}
maxMenuHeight={300}
onChange={[Function]}
openMenuOnFocus={false}
options={
Array [
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
},
Object {
"description": "Can add/remove permissions, members and delete team.",
"label": "Admin",
"value": 4,
},
]
}
tabSelectsValue={true}
value={
Object {
"description": "Is team member",
"label": "Member",
"value": 0,
}
}
/>
</div>
</td>
</WithFeatureToggle>
<td
className="text-right"
>
<DeleteButton
aria-label="Remove team member"
disabled={false}
onConfirm={[Function]}
size="sm"
/>
</td>
</tr>
`;
exports[`Render when feature toggle editorsCanAdmin is turned on should render span and disable buttons if user is team member 1`] = `
<tr
key="1"
>
<td
className="width-4 text-center"
>
<img
aria-label="Avatar for team member \\"testName\\""
className="filter-table__avatar"
src="some/url/"
/>
</td>
<td>
testUser
</td>
<td>
test@test.com
</td>
<td>
testName
</td>
<WithFeatureToggle
featureToggle={true}
>
<td
className="width-5 team-permissions"
>
<div
className="gf-form"
>
<span>
Member
</span>
</div>
</td>
</WithFeatureToggle>
<td
className="text-right"
>
<DeleteButton
aria-label="Remove team member"
disabled={true}
onConfirm={[Function]}
size="sm"
/>
</td>
</tr>
`;