Skip to content

Board Permissions #650

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Feb 8, 2024
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ You can find the changelog of the Retrospective Extension below.

_PS: Unfortunately, changelog before v1.0.46 is not available_ 🤦‍♂️

## v1.XX.X
* Boards can now restrict access down to specific teams or individuals. From [Github PR #650](https://github.com/microsoft/vsts-extension-retrospectives/pull/650)

## v1.92.1

* Team Assessment form: Background colors for each number on the spectrum now more
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { IFeedbackBoardDocument, IFeedbackColumn } from "../../../interfaces/feedback";

export const testTeamId: string = 'mocked-team-uuid';
export const testUserId: string = 'mocked-user-uuid';
export const testTitle: string = 'Test Title';

export const testColumns: IFeedbackColumn[] = [
Expand Down Expand Up @@ -32,5 +33,7 @@ export const testExistingBoard: IFeedbackBoardDocument = {
isIncludeTeamEffectivenessMeasurement: true,
shouldShowFeedbackAfterCollect: false,
displayPrimeDirective: true,
isAnonymous: false
isAnonymous: false,
isPublic: false,
permissions: null
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { shallow } from 'enzyme';
import { mockUuid } from '../__mocks__/uuid/v4';
import FeedbackBoardMetadataForm, { IFeedbackBoardMetadataFormProps, IFeedbackColumnCard } from '../feedbackBoardMetadataForm';
import { testColumns, testExistingBoard, testTeamId, testTitle } from '../__mocks__/mocked_components/mockedBoardMetadataForm';
import { testColumns, testExistingBoard, testTeamId } from '../__mocks__/mocked_components/mockedBoardMetadataForm';
import { Checkbox, List, TextField } from 'office-ui-fabric-react';

const mockedProps: IFeedbackBoardMetadataFormProps = {
Expand All @@ -12,6 +12,7 @@ const mockedProps: IFeedbackBoardMetadataFormProps = {
teamId: testTeamId,
placeholderText: '',
maxvotesPerUser: 5,
availablePermissionOptions: [],
onFormSubmit: () => null,
onFormCancel: () => null
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
import React from 'react';
import { mount, shallow } from 'enzyme';
import { mockUuid } from '../__mocks__/uuid/v4';
import FeedbackBoardMetadataForm, { IFeedbackBoardMetadataFormProps, IFeedbackColumnCard } from '../feedbackBoardMetadataForm';
import { testColumns, testExistingBoard, testTeamId, testUserId } from '../__mocks__/mocked_components/mockedBoardMetadataForm';
import { Checkbox, List, TextField } from 'office-ui-fabric-react';
import FeedbackBoardMetadataFormPermissions, { IFeedbackBoardMetadataFormPermissionsProps } from '../feedbackBoardMetadataFormPermissions';

const mockedProps: IFeedbackBoardMetadataFormPermissionsProps = {
permissions: {
Teams: [],
Members: []
},
permissionOptions: [],
onPermissionChanged: jest.fn()
};

jest.mock('uuid', () => ({ v4: () => mockUuid}));

describe('Board Metadata Form Permissions', () => {

beforeEach(() => {
jest.resetAllMocks();
});

it('can be rendered', () => {
const wrapper = shallow(<FeedbackBoardMetadataFormPermissions {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'retrospective-permission-search-input').find(TextField);

expect(textField).toBeDefined();
expect(textField.prop('value')).toEqual('');
});

describe('Public Banner', () => {
const publicBannerText: string = 'This board is visible to every member in the organization.';

it('should show when there are not team or member permissions', () => {
const wrapper = shallow(<FeedbackBoardMetadataFormPermissions {...mockedProps} />);
const component = wrapper.children().dive();
const element = component.findWhere(c => c.text() === publicBannerText);

expect(element).toBeDefined();
});

it('should hide when there are team permissions', () => {
const props = {
...mockedProps,
permissions: {
Teams: [testTeamId],
Members: [] as string[]
}
};
const wrapper = shallow(<FeedbackBoardMetadataFormPermissions {...props} />);
const component = wrapper.children().dive();
const element = component.findWhere(c => c.text() === publicBannerText);

expect(element).toHaveLength(0);
})

it('should hide when there are member permissions', () => {
const props = {
...mockedProps,
permissions: {
Teams: [] as string[],
Members: [testUserId]
}
};
const wrapper = shallow(<FeedbackBoardMetadataFormPermissions {...props} />);
const component = wrapper.children().dive();
const element = component.findWhere(c => c.text() === publicBannerText);

expect(element).toHaveLength(0);
})
});

describe('Permission Table', () => {

it('should show team permissions', () => {
const props: IFeedbackBoardMetadataFormPermissionsProps = {
...mockedProps,
permissionOptions: [
{
id: '1',
name: 'Team 1',
uniqueName: 'Team 1',
type: 'team',
thumbnailUrl: ''
},
{
id: '2',
name: 'Team 2',
uniqueName: 'Team 2',
type: 'team',
thumbnailUrl: ''
}
]
};
const wrapper = shallow(<FeedbackBoardMetadataFormPermissions {...props} />);
const component = wrapper.children().dive();
const tableBody = component.find('tbody');
const tableRows = tableBody.find('tr');

expect(tableRows).toHaveLength(2);

const everyRowHasTeamIcon = tableRows.find('i').everyWhere(c => c.hasClass('fa-users'));
expect(everyRowHasTeamIcon).toBeTruthy();
});

it('should show member permissions', () => {
const props: IFeedbackBoardMetadataFormPermissionsProps = {
...mockedProps,
permissionOptions: [
{
id: '1',
name: 'User 1',
uniqueName: 'User 1',
type: 'member',
thumbnailUrl: ''
},
{
id: '2',
name: 'User 2',
uniqueName: 'User 2',
type: 'member',
thumbnailUrl: ''
}
]
};
const wrapper = shallow(<FeedbackBoardMetadataFormPermissions {...props} />);
const component = wrapper.children().dive();
const tableBody = component.find('tbody');
const tableRows = tableBody.find('tr');

expect(tableRows).toHaveLength(2);

const everyRowHasUserImage = tableRows.find('img').everyWhere(c => c.hasClass('permission-image'));
expect(everyRowHasUserImage).toBeTruthy();
})

it('should order alpha by name', () => {
const props: IFeedbackBoardMetadataFormPermissionsProps = {
...mockedProps,
permissionOptions: [
{
id: '1',
name: 'Alpha',
uniqueName: 'User 1',
type: 'member',
thumbnailUrl: ''
},
{
id: '2',
name: 'Charlie',
uniqueName: 'User 2',
type: 'member',
thumbnailUrl: ''
},
{
id: '3',
name: 'Bravo',
uniqueName: 'Team 3',
type: 'team',
thumbnailUrl: ''
},
]
};
const wrapper = mount(<FeedbackBoardMetadataFormPermissions {...props} />);
const tableBody = wrapper.find('tbody');
const tableRows = tableBody.find('tr');

expect(tableRows).toHaveLength(3);

const first = tableRows.first().find('span').first();
expect(first.text()).toEqual('Alpha');

const last = tableRows.last().find('span').first();
expect(last.text()).toEqual('Charlie');
})

it('should order options that have permission then by name', () => {
const props: IFeedbackBoardMetadataFormPermissionsProps = {
...mockedProps,
permissions: {
Teams: ['4'],
Members: []
},
permissionOptions: [
{
id: '1',
name: 'Alpha',
uniqueName: 'User 1',
type: 'member',
thumbnailUrl: ''
},
{
id: '2',
name: 'Charlie',
uniqueName: 'User 2',
type: 'member',
thumbnailUrl: ''
},
{
id: '3',
name: 'Bravo',
uniqueName: 'Team 3',
type: 'team',
thumbnailUrl: ''
},
{
id: '4',
name: 'Zebra',
uniqueName: 'Team Z',
type: 'team',
thumbnailUrl: ''
},
]
};
const wrapper = mount(<FeedbackBoardMetadataFormPermissions {...props} />);
const tableBody = wrapper.find('tbody');
const tableRows = tableBody.find('tr');

expect(tableRows).toHaveLength(4);

const first = tableRows.first().find('span').first();
expect(first.text()).toEqual('Zebra');

const last = tableRows.last().find('span').first();
expect(last.text()).toEqual('Charlie');
})
});
});
Loading