Skip to content

Commit

Permalink
Duplicate/Copy existing retrospective boards (#561)
Browse files Browse the repository at this point in the history
* Fixed carousel tests from merge.

* Added a flag for hiding and showing the duplicate option.

* Fixed carousel test

* Updated change log

---------

Co-authored-by: Engin Polat <[email protected]>
  • Loading branch information
JStuve and polatengin authored Oct 20, 2023
1 parent fecab8f commit 766564c
Show file tree
Hide file tree
Showing 6 changed files with 383 additions and 25 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Favorable (9-10). From [Github PR #531](https://github.com/microsoft/vsts-extens
* New tab in "Focus Mode", called "All", which contains every card on the current retrospective board so that
your team can prioritize the highest voted cards first. From [Github PR #531](https://github.com/microsoft/vsts-extension-retrospectives/pull/543).

* Duplicate an existing board with the new menu option "Create a copy of retrospective". [Github PR #561](https://github.com/microsoft/vsts-extension-retrospectives/pull/561)

* Package updates for SASS and ReactTable that enhances the developer experience to run `npm i` without the need of `--force` or `--legacy-peer-deps`. From [Github PR #553](https://github.com/microsoft/vsts-extension-retrospectives/pull/553)

## v1.91.1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { IFeedbackBoardDocument, IFeedbackColumn } from "../../../interfaces/feedback";

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

export const testColumns: IFeedbackColumn[] = [
{
id: 'mock-column-uuid-1',
title: 'Test Column 1',
iconClass: '',
accentColor: ''
},
{
id: 'mock-column-uuid-2',
title: 'Test Column 2',
iconClass: '',
accentColor: ''
}
]

export const testExistingBoard: IFeedbackBoardDocument = {
id: 'mock-board-uuid',
teamId: testTeamId,
title: 'Mock Title 1',
createdBy: null,
createdDate: new Date(),
columns: testColumns,
activePhase: 'Collect',
maxVotesPerUser: 10,
boardVoteCollection: {},
teamEffectivenessMeasurementVoteCollection: [],
isIncludeTeamEffectivenessMeasurement: true,
shouldShowFeedbackAfterCollect: false,
displayPrimeDirective: true,
isAnonymous: false
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
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';

Check warning on line 5 in RetrospectiveExtension.Frontend/components/__tests__/feedbackBoardMetadataForm.test.tsx

View workflow job for this annotation

GitHub Actions / Frontend - Build and Test

'testTitle' is defined but never used
import { Checkbox, List, TextField } from 'office-ui-fabric-react';

const mockedProps: IFeedbackBoardMetadataFormProps = {
isNewBoardCreation: true,
isDuplicatingBoard: false,
currentBoard: null,
teamId: testTeamId,
placeholderText: '',
maxvotesPerUser: 5,
onFormSubmit: () => null,
onFormCancel: () => null
};

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

describe('Board Metadata Form', () => {
it('can be rendered', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'retrospective-title-input').find(TextField);

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

describe('New Board', () => {

beforeEach(() => {
mockedProps.currentBoard = null;
})

it('should set the title to nothing', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'retrospective-title-input').find(TextField);

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

it('should properly set max votes settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'max-vote-counter').find(TextField);

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

it('should properly set include team assessment settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'include-team-assessment-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(true);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set obscure feedback settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'obscure-feedback-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(false);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set prime directive setting', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'display-prime-directive').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(true);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set display names settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'feedback-display-names-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(true);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set the column list', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const list = component.find(List).first();

expect(list).toBeDefined();

const columns: IFeedbackColumnCard[] = list.prop<IFeedbackColumnCard[]>('items');

expect(columns).toHaveLength(2);
expect(columns.every(c => c.markedForDeletion === false)).toBeTruthy();
});
})

describe('Existing Board', () => {

beforeEach(() => {
mockedProps.isNewBoardCreation = false;
mockedProps.currentBoard = testExistingBoard;
})

it('should set the title', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'retrospective-title-input').find(TextField);

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

it('should properly set max votes settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'max-vote-counter').find(TextField);

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

it('should properly set include team assessment settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'include-team-assessment-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.isIncludeTeamEffectivenessMeasurement);
expect(checkbox.prop('disabled')).toEqual(true);
});

it('should properly set obscure feedback settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'obscure-feedback-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.shouldShowFeedbackAfterCollect);
expect(checkbox.prop('disabled')).toEqual(true);
});

it('should properly set prime directive setting', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'display-prime-directive').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.displayPrimeDirective);
expect(checkbox.prop('disabled')).toEqual(true);
});

it('should properly set display names settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'feedback-display-names-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.isAnonymous);
expect(checkbox.prop('disabled')).toEqual(true);
});

it('should properly set the column list', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const list = component.find(List).first();

expect(list).toBeDefined();

const columns: IFeedbackColumnCard[] = list.prop<IFeedbackColumnCard[]>('items');

expect(columns).toHaveLength(testColumns.length);
expect(columns.every(c => c.markedForDeletion === false)).toBeTruthy();
});
})

describe('Duplicate Board', () => {

beforeEach(() => {
mockedProps.isNewBoardCreation = true;
mockedProps.isDuplicatingBoard = true;
mockedProps.currentBoard = testExistingBoard;
})

it('should set the title with the duplicate copy addition', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'retrospective-title-input').find(TextField);

expect(textField).toBeDefined();
expect(textField.prop('value')).toEqual(testExistingBoard.title + ' - copy');
});

it('should properly set max votes settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const textField = component.findWhere(c => c.prop('id') === 'max-vote-counter').find(TextField);

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

it('should properly set include team assessment settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'include-team-assessment-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.isIncludeTeamEffectivenessMeasurement);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set obscure feedback settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'obscure-feedback-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.shouldShowFeedbackAfterCollect);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set prime directive setting', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'display-prime-directive').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.displayPrimeDirective);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set display names settings', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const checkbox = component.findWhere(c => c.prop('id') === 'feedback-display-names-checkbox').find(Checkbox);

expect(checkbox).toBeDefined();
expect(checkbox.prop('defaultChecked')).toEqual(testExistingBoard.isAnonymous);
expect(checkbox.prop('disabled')).toEqual(false);
});

it('should properly set the column list', () => {
const wrapper = shallow(<FeedbackBoardMetadataForm {...mockedProps} />);
const component = wrapper.children().dive();
const list = component.find(List).first();

expect(list).toBeDefined();

const columns: IFeedbackColumnCard[] = list.prop<IFeedbackColumnCard[]>('items');

expect(columns).toHaveLength(testColumns.length);
expect(columns.every(c => c.markedForDeletion === false)).toBeTruthy();
});
})

});
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,4 @@ describe('Feedback Carousel ', () => {
expect(allColumn).toHaveLength(0);
});
})
});
});
Loading

0 comments on commit 766564c

Please sign in to comment.