Group Tasks Shared Completion (#10515)

* WIP(groups): add shared completion prop
Also fix an issue where the Needs Approval toggle would not read/save 
correctly.

* fix(groups): save group options on task create
Also, correct count of assigned members when viewing user is among 
assignments

* fix(groups): display correct messages in two places

* fix(tasks): eliminate console error related to filtering
Also localize a group plans string

* WIP(groups): implement single completion for approval workflow

* WIP(groups): Add shared completion handling to no-approval-needed flow

* WIP(groups): cover approval flow case for all-assigned
Also save new field on initial task creation

* fix(tasks): use default sharedCompletion value when creating tasks

* WIP(tests): non-working draft test

* Added completed todo to group query

* WIP(group-tasks): fix bugs, add tests

* refactor(group-tasks): deleteMany op, add more tests

* refactor(group-tasks): move shared completion handling to lib

* WIP(group-tasks): broken refactor

* WIP(group-tasks): await all the things

* Turned complete master task to save

* WIP(group-tasks): show completed

* fix(filtering): don't try to filter if no list is passed

* refactor(group-tasks): load completed to-dos on demand, not at start

* fix(group-tasks): don't double up on repeat visits

* fix(group-tasks): include brief explanation in dropdown

* fix(group-tasks): improve wording some more
This commit is contained in:
Sabe Jones
2018-07-20 12:29:44 -05:00
committed by GitHub
parent 8b69540e71
commit 284b2cc413
13 changed files with 341 additions and 14 deletions

View File

@@ -140,4 +140,89 @@ describe('POST /tasks/:id/approve/:userId', () => {
message: t('canOnlyApproveTaskOnce'),
});
});
it('completes master task when single-completion task is approved', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: true,
sharedCompletion: 'singleCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/approve/${member._id}`);
let groupTasks = await user.get(`/tasks/group/${guild._id}?type=completedTodos`);
let masterTask = find(groupTasks, (groupTask) => {
return groupTask._id === sharedCompletionTask._id;
});
expect(masterTask.completed).to.equal(true);
});
it('deletes other assigned user tasks when single-completion task is approved', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: true,
sharedCompletion: 'singleCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/approve/${member._id}`);
let member2Tasks = await member2.get('/tasks/user');
let syncedTask2 = find(member2Tasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
expect(syncedTask2).to.equal(undefined);
});
it('does not complete master task when not all user tasks are approved if all assigned must complete', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: true,
sharedCompletion: 'allAssignedCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/approve/${member._id}`);
let groupTasks = await user.get(`/tasks/group/${guild._id}`);
let masterTask = find(groupTasks, (groupTask) => {
return groupTask._id === sharedCompletionTask._id;
});
expect(masterTask.completed).to.equal(false);
});
it('completes master task when all user tasks are approved if all assigned must complete', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: true,
sharedCompletion: 'allAssignedCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/approve/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/approve/${member2._id}`);
let groupTasks = await user.get(`/tasks/group/${guild._id}?type=completedTodos`);
let masterTask = find(groupTasks, (groupTask) => {
return groupTask._id === sharedCompletionTask._id;
});
expect(masterTask.completed).to.equal(true);
});
});

View File

@@ -125,7 +125,7 @@ describe('POST /tasks/:id/score/:direction', () => {
});
});
it('allows a user to score an apporoved task', async () => {
it('allows a user to score an approved task', async () => {
let memberTasks = await member.get('/tasks/user');
let syncedTask = find(memberTasks, findAssignedTask);
@@ -137,4 +137,112 @@ describe('POST /tasks/:id/score/:direction', () => {
expect(updatedTask.completed).to.equal(true);
expect(updatedTask.dateCompleted).to.be.a('string'); // date gets converted to a string as json doesn't have a Date type
});
it('completes master task when single-completion task is completed', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: false,
sharedCompletion: 'singleCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
let memberTasks = await member.get('/tasks/user');
let syncedTask = find(memberTasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
await member.post(`/tasks/${syncedTask._id}/score/up`);
let groupTasks = await user.get(`/tasks/group/${guild._id}?type=completedTodos`);
let masterTask = find(groupTasks, (groupTask) => {
return groupTask._id === sharedCompletionTask._id;
});
expect(masterTask.completed).to.equal(true);
});
it('deletes other assigned user tasks when single-completion task is completed', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: false,
sharedCompletion: 'singleCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
let memberTasks = await member.get('/tasks/user');
let syncedTask = find(memberTasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
await member.post(`/tasks/${syncedTask._id}/score/up`);
let member2Tasks = await member2.get('/tasks/user');
let syncedTask2 = find(member2Tasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
expect(syncedTask2).to.equal(undefined);
});
it('does not complete master task when not all user tasks are completed if all assigned must complete', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: false,
sharedCompletion: 'allAssignedCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
let memberTasks = await member.get('/tasks/user');
let syncedTask = find(memberTasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
await member.post(`/tasks/${syncedTask._id}/score/up`);
let groupTasks = await user.get(`/tasks/group/${guild._id}`);
let masterTask = find(groupTasks, (groupTask) => {
return groupTask._id === sharedCompletionTask._id;
});
expect(masterTask.completed).to.equal(false);
});
it('completes master task when all user tasks are completed if all assigned must complete', async () => {
let sharedCompletionTask = await user.post(`/tasks/group/${guild._id}`, {
text: 'shared completion todo',
type: 'todo',
requiresApproval: false,
sharedCompletion: 'allAssignedCompletion',
});
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member._id}`);
await user.post(`/tasks/${sharedCompletionTask._id}/assign/${member2._id}`);
let memberTasks = await member.get('/tasks/user');
let member2Tasks = await member2.get('/tasks/user');
let syncedTask = find(memberTasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
let syncedTask2 = find(member2Tasks, (memberTask) => {
return memberTask.group.taskId === sharedCompletionTask._id;
});
await member.post(`/tasks/${syncedTask._id}/score/up`);
await member2.post(`/tasks/${syncedTask2._id}/score/up`);
let groupTasks = await user.get(`/tasks/group/${guild._id}?type=completedTodos`);
let masterTask = find(groupTasks, (groupTask) => {
return groupTask._id === sharedCompletionTask._id;
});
expect(masterTask.completed).to.equal(true);
});
});