From 362ca73c94ec010d05e7a888c7de8a82e7e23e5a Mon Sep 17 00:00:00 2001 From: negue Date: Mon, 1 Oct 2018 13:29:14 +0200 Subject: [PATCH] raise coverage for tasks api calls (#10029) * - updates a group task - approval is required - updates a group task with checklist * add expect to test the new checklist length * - moves tasks to a specified position out of length * remove unused line * website getter tasks tests * re-add sanitizeUserChallengeTask * change config.json.example variable to be a string not a boolean * fix tests - pick the text / up/down props too * fix test - remove changes on text/up/down - revert sanitize condition - revert sanitization props --- config.json.example | 2 +- test/api/unit/libs/taskManager.js | 8 + .../tasks/groups/PUT-group_task_id.test.js | 64 +++++++- .../specs/store/getters/tasks/canDelete.js | 19 +++ .../store/getters/tasks/getTaskClasses.js | 141 ++++++++++++++++++ website/server/models/task.js | 8 +- 6 files changed, 231 insertions(+), 11 deletions(-) create mode 100644 test/client/unit/specs/store/getters/tasks/canDelete.js create mode 100644 test/client/unit/specs/store/getters/tasks/getTaskClasses.js diff --git a/config.json.example b/config.json.example index 260d57989b..57464ef94a 100644 --- a/config.json.example +++ b/config.json.example @@ -17,7 +17,7 @@ "NODE_DB_URI":"mongodb://localhost/habitrpg", "TEST_DB_URI":"mongodb://localhost/habitrpg_test", "NODE_ENV":"development", - "ENABLE_CONSOLE_LOGS_IN_TEST": false, + "ENABLE_CONSOLE_LOGS_IN_TEST": "false", "CRON_SAFE_MODE":"false", "CRON_SEMI_SAFE_MODE":"false", "MAINTENANCE_MODE": "false", diff --git a/test/api/unit/libs/taskManager.js b/test/api/unit/libs/taskManager.js index 262b3058de..57c6f3957f 100644 --- a/test/api/unit/libs/taskManager.js +++ b/test/api/unit/libs/taskManager.js @@ -178,4 +178,12 @@ describe('taskManager', () => { expect(order).to.eql(['task-id-2', 'task-id-1']); }); + + it('moves tasks to a specified position out of length', async () => { + let order = ['task-id-1']; + + moveTask(order, 'task-id-2', 2); + + expect(order).to.eql(['task-id-1', 'task-id-2']); + }); }); diff --git a/test/api/v3/integration/tasks/groups/PUT-group_task_id.test.js b/test/api/v3/integration/tasks/groups/PUT-group_task_id.test.js index 3ce0524866..bf073cf251 100644 --- a/test/api/v3/integration/tasks/groups/PUT-group_task_id.test.js +++ b/test/api/v3/integration/tasks/groups/PUT-group_task_id.test.js @@ -1,7 +1,7 @@ import { - createAndPopulateGroup, + createAndPopulateGroup, translate as t, } from '../../../../../helpers/api-integration/v3'; -import { find } from 'lodash'; +import {find} from 'lodash'; describe('PUT /tasks/:id', () => { let user, guild, member, member2, task; @@ -38,16 +38,64 @@ describe('PUT /tasks/:id', () => { it('updates a group task', async () => { let savedHabit = await user.put(`/tasks/${task._id}`, { - text: 'some new text', - up: false, - down: false, notes: 'some new notes', }); - expect(savedHabit.text).to.eql('some new text'); expect(savedHabit.notes).to.eql('some new notes'); - expect(savedHabit.up).to.eql(false); - expect(savedHabit.down).to.eql(false); + }); + + it('updates a group task - approval is required', async () => { + // allow to manage + await user.post(`/groups/${guild._id}/add-manager`, { + managerId: member._id, + }); + + // change the todo + task = await member.put(`/tasks/${task._id}`, { + text: 'new text!', + requiresApproval: true, + }); + + let memberTasks = await member.get('/tasks/user'); + let syncedTask = find(memberTasks, (memberTask) => memberTask.group.taskId === task._id); + + // score up to trigger approval + await expect(member.post(`/tasks/${syncedTask._id}/score/up`)) + .to.eventually.be.rejected.and.to.eql({ + code: 401, + error: 'NotAuthorized', + message: t('taskApprovalHasBeenRequested'), + }); + }); + + it('updates a group task with checklist', async () => { + // add a new todo + task = await user.post(`/tasks/group/${guild._id}`, { + text: 'todo', + type: 'todo', + checklist: [ + { + text: 'checklist 1', + }, + ], + }); + + await user.post(`/tasks/${task._id}/assign/${member._id}`); + + // change the checklist text + task = await user.put(`/tasks/${task._id}`, { + checklist: [ + { + id: task.checklist[0].id, + text: 'checklist 1 - edit', + }, + { + text: 'checklist 2 - edit', + }, + ], + }); + + expect(task.checklist.length).to.eql(2); }); it('updates the linked tasks', async () => { diff --git a/test/client/unit/specs/store/getters/tasks/canDelete.js b/test/client/unit/specs/store/getters/tasks/canDelete.js new file mode 100644 index 0000000000..d40036697b --- /dev/null +++ b/test/client/unit/specs/store/getters/tasks/canDelete.js @@ -0,0 +1,19 @@ +import generateStore from 'client/store'; + +describe('canDelete getter', () => { + it('cannot delete active challenge task', () => { + const store = generateStore(); + + + const task = {userId: 1, challenge: {id: 2}}; + expect(store.getters['tasks:canDelete'](task)).to.equal(false); + }); + + it('can delete broken challenge task', () => { + const store = generateStore(); + + + const task = {userId: 1, challenge: {id: 2, broken: true}}; + expect(store.getters['tasks:canDelete'](task)).to.equal(true); + }); +}); diff --git a/test/client/unit/specs/store/getters/tasks/getTaskClasses.js b/test/client/unit/specs/store/getters/tasks/getTaskClasses.js new file mode 100644 index 0000000000..1399283f55 --- /dev/null +++ b/test/client/unit/specs/store/getters/tasks/getTaskClasses.js @@ -0,0 +1,141 @@ +import generateStore from 'client/store'; + +describe('getTaskClasses getter', () => { + let store, getTaskClasses; + + beforeEach(() => { + store = generateStore(); + store.state.user.data = { + preferences: { + }, + }; + + getTaskClasses = store.getters['tasks:getTaskClasses']; + }); + + it('returns reward edit-modal-bg class', () => { + const task = {type: 'reward'}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-purple-modal-bg'); + }); + + it('returns worst task edit-modal-bg class', () => { + const task = {type: 'todo', value: -21}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-worst-modal-bg'); + }); + + it('returns worse task edit-modal-bg class', () => { + const task = {type: 'todo', value: -11}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-worse-modal-bg'); + }); + + it('returns bad task edit-modal-bg class', () => { + const task = {type: 'todo', value: -6}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-bad-modal-bg'); + }); + + it('returns neutral task edit-modal-bg class', () => { + const task = {type: 'todo', value: 0}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-neutral-modal-bg'); + }); + + it('returns good task edit-modal-bg class', () => { + const task = {type: 'todo', value: 2}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-good-modal-bg'); + }); + + it('returns better task edit-modal-bg class', () => { + const task = {type: 'todo', value: 6}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-better-modal-bg'); + }); + + + it('returns best task edit-modal-bg class', () => { + const task = {type: 'todo', value: 12}; + expect(getTaskClasses(task, 'edit-modal-bg')).to.equal('task-best-modal-bg'); + }); + + it('returns best task edit-modal-text class', () => { + const task = {type: 'todo', value: 12}; + expect(getTaskClasses(task, 'edit-modal-text')).to.equal('task-best-modal-text'); + }); + + it('returns best task edit-modal-icon class', () => { + const task = {type: 'todo', value: 12}; + expect(getTaskClasses(task, 'edit-modal-icon')).to.equal('task-best-modal-icon'); + }); + + it('returns best task edit-modal-option-disabled class', () => { + const task = {type: 'todo', value: 12}; + expect(getTaskClasses(task, 'edit-modal-option-disabled')).to.equal('task-best-modal-option-disabled'); + }); + + it('returns best task edit-modal-control-disabled class', () => { + const task = {type: 'todo', value: 12}; + expect(getTaskClasses(task, 'edit-modal-habit-control-disabled')).to.equal('task-best-modal-habit-control-disabled'); + }); + + it('returns create-modal-bg class', () => { + const task = {type: 'todo'}; + expect(getTaskClasses(task, 'create-modal-bg')).to.equal('task-purple-modal-bg'); + }); + + it('returns create-modal-text class', () => { + const task = {type: 'todo'}; + expect(getTaskClasses(task, 'create-modal-text')).to.equal('task-purple-modal-text'); + }); + + it('returns create-modal-icon class', () => { + const task = {type: 'todo'}; + expect(getTaskClasses(task, 'create-modal-icon')).to.equal('task-purple-modal-icon'); + }); + + it('returns create-modal-option-disabled class', () => { + const task = {type: 'todo'}; + expect(getTaskClasses(task, 'create-modal-option-disabled')).to.equal('task-purple-modal-option-disabled'); + }); + + it('returns create-modal-habit-control-disabled class', () => { + const task = {type: 'todo'}; + expect(getTaskClasses(task, 'create-modal-habit-control-disabled')).to.equal('task-purple-modal-habit-control-disabled'); + }); + + it('returns completed todo classes', () => { + const task = {type: 'todo', value: 2, completed: true}; + expect(getTaskClasses(task, 'control')).to.deep.equal({ + bg: 'task-disabled-daily-todo-control-bg', + checkbox: 'task-disabled-daily-todo-control-checkbox', + inner: 'task-disabled-daily-todo-control-inner', + content: 'task-disabled-daily-todo-control-content', + }); + }); + + xit('returns good todo classes', () => { + const task = {type: 'todo', value: 2}; + expect(getTaskClasses(task, 'control')).to.deep.equal({ + bg: 'task-good-control-bg', + checkbox: 'task-good-control-checkbox', + inner: 'task-good-control-inner-daily-todo`', + }); + }); + + it('returns reward classes', () => { + const task = {type: 'reward'}; + expect(getTaskClasses(task, 'control')).to.deep.equal({ + bg: 'task-reward-control-bg', + }); + }); + + it('returns habit up classes', () => { + const task = {type: 'habit', value: 2, up: true}; + expect(getTaskClasses(task, 'control')).to.deep.equal({ + up: { + bg: 'task-good-control-bg', + inner: 'task-good-control-inner-habit', + }, + down: { + bg: 'task-disabled-habit-control-bg', + inner: 'task-disabled-habit-control-inner', + }, + }); + }); +}); diff --git a/website/server/models/task.js b/website/server/models/task.js index 52b1a0450b..7614f46903 100644 --- a/website/server/models/task.js +++ b/website/server/models/task.js @@ -169,9 +169,13 @@ TaskSchema.statics.findByIdOrAlias = async function findByIdOrAlias (identifier, // Sanitize user tasks linked to a challenge // See http://habitica.wikia.com/wiki/Challenges#Challenge_Participant.27s_Permissions for more info TaskSchema.statics.sanitizeUserChallengeTask = function sanitizeUserChallengeTask (taskObj) { - let initialSanitization = this.sanitize(taskObj); + const initialSanitization = this.sanitize(taskObj); - return _.pick(initialSanitization, ['streak', 'checklist', 'attribute', 'reminders', 'tags', 'notes', 'collapseChecklist', 'alias', 'yesterDaily', 'counterDown', 'counterUp']); + return _.pick(initialSanitization, [ + 'streak', 'checklist', 'attribute', 'reminders', + 'tags', 'notes', 'collapseChecklist', + 'alias', 'yesterDaily', 'counterDown', 'counterUp', + ]); }; // Sanitize checklist objects (disallowing id)