mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-18 15:17:25 +01:00
change tasks routes to /tasks/(user|challenge)
This commit is contained in:
@@ -16,7 +16,7 @@ describe('DELETE /tasks/:id', () => {
|
|||||||
let task;
|
let task;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
}).then((createdTask) => {
|
}).then((createdTask) => {
|
||||||
@@ -48,7 +48,7 @@ describe('DELETE /tasks/:id', () => {
|
|||||||
it('cannot delete a task owned by someone else', () => {
|
it('cannot delete a task owned by someone else', () => {
|
||||||
return generateUser()
|
return generateUser()
|
||||||
.then((anotherUser) => {
|
.then((anotherUser) => {
|
||||||
return anotherUser.post('/tasks?tasksOwner=user', {
|
return anotherUser.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import {
|
|||||||
generateUser,
|
generateUser,
|
||||||
} from '../../../../helpers/api-integration.helper';
|
} from '../../../../helpers/api-integration.helper';
|
||||||
|
|
||||||
describe('GET /tasks', () => {
|
describe('GET /tasks/user', () => {
|
||||||
let user;
|
let user;
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
@@ -16,14 +16,14 @@ describe('GET /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns all user\'s tasks', async () => {
|
it('returns all user\'s tasks', async () => {
|
||||||
let createdTasks = await user.post('/tasks?tasksOwner=user', [{text: 'test habit', type: 'habit'}, {text: 'test todo', type: 'todo'}]);
|
let createdTasks = await user.post('/tasks/user', [{text: 'test habit', type: 'habit'}, {text: 'test todo', type: 'todo'}]);
|
||||||
let tasks = await user.get('/tasks?tasksOwner=user');
|
let tasks = await user.get('/tasks/user');
|
||||||
expect(tasks.length).to.equal(createdTasks.length + 1); // + 1 because 1 is a default task
|
expect(tasks.length).to.equal(createdTasks.length + 1); // + 1 because 1 is a default task
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns only a type of user\'s tasks if req.query.type is specified', async () => {
|
it('returns only a type of user\'s tasks if req.query.type is specified', async () => {
|
||||||
let createdTasks = await user.post('/tasks?tasksOwner=user', [{text: 'test habit', type: 'habit'}, {text: 'test todo', type: 'todo'}]);
|
let createdTasks = await user.post('/tasks/user', [{text: 'test habit', type: 'habit'}, {text: 'test todo', type: 'todo'}]);
|
||||||
let tasks = await user.get('/tasks?tasksOwner=user&type=habit');
|
let tasks = await user.get('/tasks/user?type=habit');
|
||||||
expect(tasks.length).to.equal(1);
|
expect(tasks.length).to.equal(1);
|
||||||
expect(tasks[0]._id).to.equal(createdTasks[0]._id);
|
expect(tasks[0]._id).to.equal(createdTasks[0]._id);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('GET /tasks/:id', () => {
|
|||||||
let task;
|
let task;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
}).then((createdTask) => {
|
}).then((createdTask) => {
|
||||||
@@ -54,7 +54,7 @@ describe('GET /tasks/:id', () => {
|
|||||||
.then((user2) => {
|
.then((user2) => {
|
||||||
anotherUser = user2;
|
anotherUser = user2;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
context('validates params', () => {
|
context('validates params', () => {
|
||||||
it('returns an error if req.body.type is absent', async () => {
|
it('returns an error if req.body.type is absent', async () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
notType: 'habit',
|
notType: 'habit',
|
||||||
})).to.eventually.be.rejected.and.eql({
|
})).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -24,7 +24,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error if req.body.type is not valid', async () => {
|
it('returns an error if req.body.type is not valid', async () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habitF',
|
type: 'habitF',
|
||||||
})).to.eventually.be.rejected.and.eql({
|
})).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -34,7 +34,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error if one object inside an array is invalid', async () => {
|
it('returns an error if one object inside an array is invalid', async () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', [
|
return expect(user.post('/tasks/user', [
|
||||||
{type: 'habitF'},
|
{type: 'habitF'},
|
||||||
{type: 'habit'},
|
{type: 'habit'},
|
||||||
])).to.eventually.be.rejected.and.eql({
|
])).to.eventually.be.rejected.and.eql({
|
||||||
@@ -45,7 +45,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('returns an error if req.body.text is absent', async () => {
|
it('returns an error if req.body.text is absent', async () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
})).to.eventually.be.rejected.and.eql({
|
})).to.eventually.be.rejected.and.eql({
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -56,7 +56,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('does not update user.tasksOrder.{taskType} when the task is not saved because invalid', async () => {
|
it('does not update user.tasksOrder.{taskType} when the task is not saved because invalid', async () => {
|
||||||
let originalHabitsOrder = (await user.get('/user')).tasksOrder.habits;
|
let originalHabitsOrder = (await user.get('/user')).tasksOrder.habits;
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
})).to.eventually.be.rejected.and.eql({ // this block is necessary
|
})).to.eventually.be.rejected.and.eql({ // this block is necessary
|
||||||
code: 400,
|
code: 400,
|
||||||
@@ -71,7 +71,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('does not update user.tasksOrder.{taskType} when a task inside an array is not saved because invalid', async () => {
|
it('does not update user.tasksOrder.{taskType} when a task inside an array is not saved because invalid', async () => {
|
||||||
let originalHabitsOrder = (await user.get('/user')).tasksOrder.habits;
|
let originalHabitsOrder = (await user.get('/user')).tasksOrder.habits;
|
||||||
return expect(user.post('/tasks?tasksOwner=user', [
|
return expect(user.post('/tasks/user', [
|
||||||
{type: 'habit'}, // Missing text
|
{type: 'habit'}, // Missing text
|
||||||
{type: 'habit', text: 'valid'}, // Valid
|
{type: 'habit', text: 'valid'}, // Valid
|
||||||
])).to.eventually.be.rejected.and.eql({ // this block is necessary
|
])).to.eventually.be.rejected.and.eql({ // this block is necessary
|
||||||
@@ -86,8 +86,8 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not save any task sent in an array when 1 is invalid', async () => {
|
it('does not save any task sent in an array when 1 is invalid', async () => {
|
||||||
let originalTasks = await user.get('/tasks?tasksOwner=user');
|
let originalTasks = await user.get('/tasks/user');
|
||||||
return expect(user.post('/tasks?tasksOwner=user', [
|
return expect(user.post('/tasks/user', [
|
||||||
{type: 'habit'}, // Missing text
|
{type: 'habit'}, // Missing text
|
||||||
{type: 'habit', text: 'valid'}, // Valid
|
{type: 'habit', text: 'valid'}, // Valid
|
||||||
])).to.eventually.be.rejected.and.eql({ // this block is necessary
|
])).to.eventually.be.rejected.and.eql({ // this block is necessary
|
||||||
@@ -95,14 +95,14 @@ describe('POST /tasks', () => {
|
|||||||
error: 'BadRequest',
|
error: 'BadRequest',
|
||||||
message: 'habit validation failed',
|
message: 'habit validation failed',
|
||||||
}).then(async () => {
|
}).then(async () => {
|
||||||
let updatedTasks = await user.get('/tasks?tasksOwner=user');
|
let updatedTasks = await user.get('/tasks/user');
|
||||||
|
|
||||||
expect(updatedTasks).to.eql(originalTasks);
|
expect(updatedTasks).to.eql(originalTasks);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('automatically sets "task.userId" to user\'s uuid', async () => {
|
it('automatically sets "task.userId" to user\'s uuid', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
});
|
});
|
||||||
@@ -113,7 +113,7 @@ describe('POST /tasks', () => {
|
|||||||
it(`ignores setting userId, history, createdAt,
|
it(`ignores setting userId, history, createdAt,
|
||||||
updatedAt, challenge, completed, streak,
|
updatedAt, challenge, completed, streak,
|
||||||
dateCompleted fields`, async () => {
|
dateCompleted fields`, async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
userId: 123,
|
userId: 123,
|
||||||
@@ -137,7 +137,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('ignores invalid fields', async () => {
|
it('ignores invalid fields', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
notValid: true,
|
notValid: true,
|
||||||
@@ -149,7 +149,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
context('habits', () => {
|
context('habits', () => {
|
||||||
it('creates a habit', async () => {
|
it('creates a habit', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
up: false,
|
up: false,
|
||||||
@@ -167,7 +167,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.habits when a new habit is created', async () => {
|
it('updates user.tasksOrder.habits when a new habit is created', async () => {
|
||||||
let originalHabitsOrderLen = (await user.get('/user')).tasksOrder.habits.length;
|
let originalHabitsOrderLen = (await user.get('/user')).tasksOrder.habits.length;
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'an habit',
|
text: 'an habit',
|
||||||
});
|
});
|
||||||
@@ -179,7 +179,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.habits when multiple habits are created', async () => {
|
it('updates user.tasksOrder.habits when multiple habits are created', async () => {
|
||||||
let originalHabitsOrderLen = (await user.get('/user')).tasksOrder.habits.length;
|
let originalHabitsOrderLen = (await user.get('/user')).tasksOrder.habits.length;
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'an habit',
|
text: 'an habit',
|
||||||
}, {
|
}, {
|
||||||
@@ -194,7 +194,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates multiple habits', async () => {
|
it('creates multiple habits', async () => {
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
up: false,
|
up: false,
|
||||||
@@ -224,7 +224,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to setting up and down to true', async () => {
|
it('defaults to setting up and down to true', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -235,7 +235,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('cannot create checklists', async () => {
|
it('cannot create checklists', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
checklist: [
|
checklist: [
|
||||||
@@ -249,7 +249,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
context('todos', () => {
|
context('todos', () => {
|
||||||
it('creates a todo', async () => {
|
it('creates a todo', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test todo',
|
text: 'test todo',
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -262,7 +262,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates multiple todos', async () => {
|
it('creates multiple todos', async () => {
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
text: 'test todo',
|
text: 'test todo',
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -285,7 +285,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.todos when a new todo is created', async () => {
|
it('updates user.tasksOrder.todos when a new todo is created', async () => {
|
||||||
let originalTodosOrderLen = (await user.get('/user')).tasksOrder.todos.length;
|
let originalTodosOrderLen = (await user.get('/user')).tasksOrder.todos.length;
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
text: 'a todo',
|
text: 'a todo',
|
||||||
});
|
});
|
||||||
@@ -297,7 +297,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.todos when multiple todos are created', async () => {
|
it('updates user.tasksOrder.todos when multiple todos are created', async () => {
|
||||||
let originalTodosOrderLen = (await user.get('/user')).tasksOrder.todos.length;
|
let originalTodosOrderLen = (await user.get('/user')).tasksOrder.todos.length;
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
text: 'a todo',
|
text: 'a todo',
|
||||||
}, {
|
}, {
|
||||||
@@ -312,7 +312,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can create checklists', async () => {
|
it('can create checklists', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test todo',
|
text: 'test todo',
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
checklist: [
|
checklist: [
|
||||||
@@ -333,7 +333,7 @@ describe('POST /tasks', () => {
|
|||||||
it('creates a daily', async () => {
|
it('creates a daily', async () => {
|
||||||
let now = new Date();
|
let now = new Date();
|
||||||
|
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -352,7 +352,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates multiple dailys', async () => {
|
it('creates multiple dailys', async () => {
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -375,7 +375,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.dailys when a new daily is created', async () => {
|
it('updates user.tasksOrder.dailys when a new daily is created', async () => {
|
||||||
let originalDailysOrderLen = (await user.get('/user')).tasksOrder.dailys.length;
|
let originalDailysOrderLen = (await user.get('/user')).tasksOrder.dailys.length;
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'a daily',
|
text: 'a daily',
|
||||||
});
|
});
|
||||||
@@ -387,7 +387,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.dailys when multiple dailys are created', async () => {
|
it('updates user.tasksOrder.dailys when multiple dailys are created', async () => {
|
||||||
let originalDailysOrderLen = (await user.get('/user')).tasksOrder.dailys.length;
|
let originalDailysOrderLen = (await user.get('/user')).tasksOrder.dailys.length;
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'a daily',
|
text: 'a daily',
|
||||||
}, {
|
}, {
|
||||||
@@ -402,7 +402,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to a weekly frequency, with every day set', async () => {
|
it('defaults to a weekly frequency, with every day set', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
});
|
});
|
||||||
@@ -421,7 +421,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('allows repeat field to be configured', async () => {
|
it('allows repeat field to be configured', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
repeat: {
|
repeat: {
|
||||||
@@ -445,7 +445,7 @@ describe('POST /tasks', () => {
|
|||||||
it('defaults startDate to today', async () => {
|
it('defaults startDate to today', async () => {
|
||||||
let today = (new Date()).getDay();
|
let today = (new Date()).getDay();
|
||||||
|
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
});
|
});
|
||||||
@@ -454,7 +454,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('can create checklists', async () => {
|
it('can create checklists', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
checklist: [
|
checklist: [
|
||||||
@@ -473,7 +473,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
context('rewards', () => {
|
context('rewards', () => {
|
||||||
it('creates a reward', async () => {
|
it('creates a reward', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -488,7 +488,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('creates multiple rewards', async () => {
|
it('creates multiple rewards', async () => {
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -515,7 +515,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.rewards when a new reward is created', async () => {
|
it('updates user.tasksOrder.rewards when a new reward is created', async () => {
|
||||||
let originalRewardsOrderLen = (await user.get('/user')).tasksOrder.rewards.length;
|
let originalRewardsOrderLen = (await user.get('/user')).tasksOrder.rewards.length;
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
text: 'a reward',
|
text: 'a reward',
|
||||||
});
|
});
|
||||||
@@ -527,7 +527,7 @@ describe('POST /tasks', () => {
|
|||||||
|
|
||||||
it('updates user.tasksOrder.dreward when multiple rewards are created', async () => {
|
it('updates user.tasksOrder.dreward when multiple rewards are created', async () => {
|
||||||
let originalRewardsOrderLen = (await user.get('/user')).tasksOrder.rewards.length;
|
let originalRewardsOrderLen = (await user.get('/user')).tasksOrder.rewards.length;
|
||||||
let [task, task2] = await user.post('/tasks?tasksOwner=user', [{
|
let [task, task2] = await user.post('/tasks/user', [{
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
text: 'a reward',
|
text: 'a reward',
|
||||||
}, {
|
}, {
|
||||||
@@ -542,7 +542,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('defaults to a 0 value', async () => {
|
it('defaults to a 0 value', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
});
|
});
|
||||||
@@ -551,7 +551,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('requires value to be coerced into a number', async () => {
|
it('requires value to be coerced into a number', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
value: '10',
|
value: '10',
|
||||||
@@ -561,7 +561,7 @@ describe('POST /tasks', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('cannot create checklists', async () => {
|
it('cannot create checklists', async () => {
|
||||||
let task = await user.post('/tasks?tasksOwner=user', {
|
let task = await user.post('/tasks/user', {
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
checklist: [
|
checklist: [
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ describe('POST /tasks/:id/score/:direction', () => {
|
|||||||
let todo;
|
let todo;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test todo',
|
text: 'test todo',
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
}).then((task) => {
|
}).then((task) => {
|
||||||
@@ -149,7 +149,7 @@ describe('POST /tasks/:id/score/:direction', () => {
|
|||||||
let daily;
|
let daily;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
}).then((task) => {
|
}).then((task) => {
|
||||||
@@ -226,26 +226,26 @@ describe('POST /tasks/:id/score/:direction', () => {
|
|||||||
let habit, minusHabit, plusHabit, neitherHabit; // eslint-disable-line no-unused-vars
|
let habit, minusHabit, plusHabit, neitherHabit; // eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
}).then((task) => {
|
}).then((task) => {
|
||||||
habit = task;
|
habit = task;
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test min habit',
|
text: 'test min habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
up: false,
|
up: false,
|
||||||
});
|
});
|
||||||
}).then((task) => {
|
}).then((task) => {
|
||||||
minusHabit = task;
|
minusHabit = task;
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test plus habit',
|
text: 'test plus habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
down: false,
|
down: false,
|
||||||
});
|
});
|
||||||
}).then((task) => {
|
}).then((task) => {
|
||||||
plusHabit = task;
|
plusHabit = task;
|
||||||
user.post('/tasks?tasksOwner=user', {
|
user.post('/tasks/user', {
|
||||||
text: 'test neither habit',
|
text: 'test neither habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
up: false,
|
up: false,
|
||||||
@@ -297,7 +297,7 @@ describe('POST /tasks/:id/score/:direction', () => {
|
|||||||
let reward;
|
let reward;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
value: 5,
|
value: 5,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('PUT /tasks/:id', () => {
|
|||||||
let task;
|
let task;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
}).then((createdTask) => {
|
}).then((createdTask) => {
|
||||||
@@ -65,7 +65,7 @@ describe('PUT /tasks/:id', () => {
|
|||||||
let habit;
|
let habit;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test habit',
|
text: 'test habit',
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -93,7 +93,7 @@ describe('PUT /tasks/:id', () => {
|
|||||||
let todo;
|
let todo;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test todo',
|
text: 'test todo',
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -150,7 +150,7 @@ describe('PUT /tasks/:id', () => {
|
|||||||
let daily;
|
let daily;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test daily',
|
text: 'test daily',
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
@@ -254,7 +254,7 @@ describe('PUT /tasks/:id', () => {
|
|||||||
let reward;
|
let reward;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
text: 'test reward',
|
text: 'test reward',
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
notes: 1976,
|
notes: 1976,
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('DELETE /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
it('deletes a checklist item', () => {
|
it('deletes a checklist item', () => {
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'Daily with checklist',
|
text: 'Daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -33,7 +33,7 @@ describe('DELETE /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
|
|
||||||
it('does not work with habits', () => {
|
it('does not work with habits', () => {
|
||||||
let habit;
|
let habit;
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'habit with checklist',
|
text: 'habit with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -47,7 +47,7 @@ describe('DELETE /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not work with rewards', async () => {
|
it('does not work with rewards', async () => {
|
||||||
let reward = await user.post('/tasks?tasksOwner=user', {
|
let reward = await user.post('/tasks/user', {
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
text: 'reward with checklist',
|
text: 'reward with checklist',
|
||||||
});
|
});
|
||||||
@@ -68,7 +68,7 @@ describe('DELETE /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails on checklist item not found', () => {
|
it('fails on checklist item not found', () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'daily with checklist',
|
text: 'daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('POST /tasks/:taskId/checklist/', () => {
|
|||||||
it('adds a checklist item to a task', () => {
|
it('adds a checklist item to a task', () => {
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'Daily with checklist',
|
text: 'Daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -36,7 +36,7 @@ describe('POST /tasks/:taskId/checklist/', () => {
|
|||||||
it('does not add a checklist to habits', () => {
|
it('does not add a checklist to habits', () => {
|
||||||
let habit;
|
let habit;
|
||||||
|
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'habit with checklist',
|
text: 'habit with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -51,7 +51,7 @@ describe('POST /tasks/:taskId/checklist/', () => {
|
|||||||
|
|
||||||
it('does not add a checklist to rewards', () => {
|
it('does not add a checklist to rewards', () => {
|
||||||
let reward;
|
let reward;
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
text: 'reward with checklist',
|
text: 'reward with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('POST /tasks/:taskId/checklist/:itemId/score', () => {
|
|||||||
it('scores a checklist item', () => {
|
it('scores a checklist item', () => {
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'Daily with checklist',
|
text: 'Daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -32,7 +32,7 @@ describe('POST /tasks/:taskId/checklist/:itemId/score', () => {
|
|||||||
|
|
||||||
it('fails on habits', () => {
|
it('fails on habits', () => {
|
||||||
let habit;
|
let habit;
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'habit with checklist',
|
text: 'habit with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -46,7 +46,7 @@ describe('POST /tasks/:taskId/checklist/:itemId/score', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails on rewards', async () => {
|
it('fails on rewards', async () => {
|
||||||
let reward = await user.post('/tasks?tasksOwner=user', {
|
let reward = await user.post('/tasks/user', {
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
text: 'reward with checklist',
|
text: 'reward with checklist',
|
||||||
});
|
});
|
||||||
@@ -67,7 +67,7 @@ describe('POST /tasks/:taskId/checklist/:itemId/score', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails on checklist item not found', () => {
|
it('fails on checklist item not found', () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'daily with checklist',
|
text: 'daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ describe('PUT /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
it('updates a checklist item', () => {
|
it('updates a checklist item', () => {
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'Daily with checklist',
|
text: 'Daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -33,7 +33,7 @@ describe('PUT /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails on habits', async () => {
|
it('fails on habits', async () => {
|
||||||
let habit = await user.post('/tasks?tasksOwner=user', {
|
let habit = await user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'habit with checklist',
|
text: 'habit with checklist',
|
||||||
});
|
});
|
||||||
@@ -46,7 +46,7 @@ describe('PUT /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails on rewards', async () => {
|
it('fails on rewards', async () => {
|
||||||
let reward = await user.post('/tasks?tasksOwner=user', {
|
let reward = await user.post('/tasks/user', {
|
||||||
type: 'reward',
|
type: 'reward',
|
||||||
text: 'reward with checklist',
|
text: 'reward with checklist',
|
||||||
});
|
});
|
||||||
@@ -67,7 +67,7 @@ describe('PUT /tasks/:taskId/checklist/:itemId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('fails on checklist item not found', () => {
|
it('fails on checklist item not found', () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'daily',
|
type: 'daily',
|
||||||
text: 'daily with checklist',
|
text: 'daily with checklist',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('DELETE /tasks/:taskId/tags/:tagId', () => {
|
|||||||
let tag;
|
let tag;
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'Task with tag',
|
text: 'Task with tag',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -35,7 +35,7 @@ describe('DELETE /tasks/:taskId/tags/:tagId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('only deletes existing tags', () => {
|
it('only deletes existing tags', () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'Task with tag',
|
text: 'Task with tag',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ describe('POST /tasks/:taskId/tags/:tagId', () => {
|
|||||||
let tag;
|
let tag;
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return user.post('/tasks?tasksOwner=user', {
|
return user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'Task with tag',
|
text: 'Task with tag',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -35,7 +35,7 @@ describe('POST /tasks/:taskId/tags/:tagId', () => {
|
|||||||
let tag;
|
let tag;
|
||||||
let task;
|
let task;
|
||||||
|
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'Task with tag',
|
text: 'Task with tag',
|
||||||
}).then(createdTask => {
|
}).then(createdTask => {
|
||||||
@@ -54,7 +54,7 @@ describe('POST /tasks/:taskId/tags/:tagId', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('does not add a non existing tag to a task', () => {
|
it('does not add a non existing tag to a task', () => {
|
||||||
return expect(user.post('/tasks?tasksOwner=user', {
|
return expect(user.post('/tasks/user', {
|
||||||
type: 'habit',
|
type: 'habit',
|
||||||
text: 'Task with tag',
|
text: 'Task with tag',
|
||||||
}).then((task) => {
|
}).then((task) => {
|
||||||
|
|||||||
@@ -16,88 +16,197 @@ import { preenHistory } from '../../../../common/script/api-v3/preenHistory';
|
|||||||
|
|
||||||
let api = {};
|
let api = {};
|
||||||
|
|
||||||
|
// challenge must be passed only when a challenge task is being created
|
||||||
|
async function _createTasks (req, res, user, challenge) {
|
||||||
|
let toSave = Array.isArray(req.body) ? req.body : [req.body];
|
||||||
|
|
||||||
|
toSave = toSave.map(taskData => {
|
||||||
|
// Validate that task.type is valid
|
||||||
|
if (!taskData || Tasks.tasksTypes.indexOf(taskData.type) === -1) throw new BadRequest(res.t('invalidTaskType'));
|
||||||
|
|
||||||
|
let taskType = taskData.type;
|
||||||
|
let newTask = new Tasks[taskType](Tasks.Task.sanitizeCreate(taskData));
|
||||||
|
|
||||||
|
if (challenge) {
|
||||||
|
newTask.challenge.id = challenge.id;
|
||||||
|
} else {
|
||||||
|
newTask.userId = user._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate that the task is valid and throw if it isn't
|
||||||
|
// otherwise since we're saving user/challenge and task in parallel it could save the user/challenge with a tasksOrder that doens't match reality
|
||||||
|
let validationErrors = newTask.validateSync();
|
||||||
|
if (validationErrors) throw validationErrors;
|
||||||
|
|
||||||
|
// Otherwise update the user/challenge
|
||||||
|
(challenge || user).tasksOrder[`${taskType}s`].unshift(newTask._id);
|
||||||
|
|
||||||
|
return newTask;
|
||||||
|
}).map(task => task.save({ // If all tasks are valid (this is why it's not in the previous .map()), save everything, withough running validation again
|
||||||
|
validateBeforeSave: false,
|
||||||
|
}));
|
||||||
|
|
||||||
|
toSave.unshift((challenge || user).save());
|
||||||
|
|
||||||
|
let tasks = await Q.all(toSave);
|
||||||
|
tasks.splice(0, 1); // Remove user or challenge
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {post} /tasks Create a new task. Can be passed an object to create a single task or an array of objects to create multiple tasks.
|
* @api {post} /tasks/user Create a new task belonging to the autheticated user. Can be passed an object to create a single task or an array of objects to create multiple tasks.
|
||||||
* @apiVersion 3.0.0
|
* @apiVersion 3.0.0
|
||||||
* @apiName CreateTask
|
* @apiName CreateUserTasks
|
||||||
* @apiGroup Task
|
* @apiGroup Task
|
||||||
*
|
*
|
||||||
* @apiParam {string="user","challenge"} tasksOwner Query parameter to define if tasks will belong to the auhenticated user or to a challenge (specifying the "challengeId" parameter).
|
|
||||||
* @apiParam {UUID} challengeId Optional. Query parameter. If "tasksOwner" is "challenge" then specify the challenge id.
|
|
||||||
*
|
|
||||||
* @apiSuccess {Object|Array} task The newly created task(s)
|
* @apiSuccess {Object|Array} task The newly created task(s)
|
||||||
*/
|
*/
|
||||||
api.createTask = {
|
api.createUserTasks = {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: '/tasks',
|
url: '/tasks/user',
|
||||||
middlewares: [authWithHeaders(), cron],
|
middlewares: [authWithHeaders(), cron],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkQuery('tasksOwner', res.t('invalidTasksOwner')).isIn(['user', 'challenge']);
|
let tasks = await _createTasks(req, res, res.locals.user);
|
||||||
req.checkQuery('challengeId', res.t('challengeIdRequired')).optional().isUUID();
|
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {post} /tasks/challenge/:challengeId Create a new task belonging to the challenge. Can be passed an object to create a single task or an array of objects to create multiple tasks.
|
||||||
|
* @apiVersion 3.0.0
|
||||||
|
* @apiName CreateChallengeTasks
|
||||||
|
* @apiGroup Task
|
||||||
|
*
|
||||||
|
* @apiParam {UUID} challengeId The id of the challenge the new task(s) will belong to.
|
||||||
|
*
|
||||||
|
* @apiSuccess {Object|Array} task The newly created task(s)
|
||||||
|
*/
|
||||||
|
api.createChallengeTasks = {
|
||||||
|
method: 'POST',
|
||||||
|
url: '/tasks/challenge/:challengeId',
|
||||||
|
middlewares: [authWithHeaders(), cron],
|
||||||
|
async handler (req, res) {
|
||||||
|
req.checkQuery('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
|
||||||
|
|
||||||
let reqValidationErrors = req.validationErrors();
|
let reqValidationErrors = req.validationErrors();
|
||||||
if (reqValidationErrors) throw reqValidationErrors;
|
if (reqValidationErrors) throw reqValidationErrors;
|
||||||
|
|
||||||
let tasksData = Array.isArray(req.body) ? req.body : [req.body];
|
let user = res.local.user;
|
||||||
let user = res.locals.user;
|
let challengeId = req.params.challengeId;
|
||||||
let tasksOwner = req.query.tasksOwner;
|
|
||||||
let challengeId = req.query.challengeId;
|
|
||||||
let challenge;
|
|
||||||
|
|
||||||
if (tasksOwner === 'user' && challengeId) throw new BadRequest(res.t('userTasksNoChallengeId'));
|
let challenge = await Challenge.findOne({_id: challengeId}).exec();
|
||||||
if (tasksOwner === 'challenge') {
|
|
||||||
if (!challengeId) throw new BadRequest(res.t('challengeIdRequired'));
|
|
||||||
challenge = await Challenge.findOne({_id: challengeId}).exec();
|
|
||||||
|
|
||||||
// If the challenge does not exist, or if it exists but user is not the leader -> throw error
|
// If the challenge does not exist, or if it exists but user is not the leader -> throw error
|
||||||
if (!challenge) throw new NotFound(res.t('challengeNotFound'));
|
if (!challenge || user.challenges.indexOf(challengeId) === -1) throw new NotFound(res.t('challengeNotFound'));
|
||||||
if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
|
if (challenge.leader !== user._id) throw new NotAuthorized(res.t('onlyChalLeaderEditTasks'));
|
||||||
}
|
|
||||||
|
|
||||||
let toSave = tasksData.map(taskData => {
|
let tasks = await _createTasks(req, res, user, challenge);
|
||||||
// Validate that task.type is valid
|
res.respond(201, tasks.length === 1 ? tasks[0] : tasks);
|
||||||
if (!taskData || Tasks.tasksTypes.indexOf(taskData.type) === -1) throw new BadRequest(res.t('invalidTaskType'));
|
|
||||||
|
|
||||||
let taskType = taskData.type;
|
|
||||||
let newTask = new Tasks[taskType](Tasks.Task.sanitizeCreate(taskData));
|
|
||||||
|
|
||||||
if (challenge) {
|
|
||||||
newTask.challenge.id = challengeId;
|
|
||||||
} else {
|
|
||||||
newTask.userId = user._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate that the task is valid and throw if it isn't
|
|
||||||
// otherwise since we're saving user/challenge and task in parallel it could save the user/challenge with a tasksOrder that doens't match reality
|
|
||||||
let validationErrors = newTask.validateSync();
|
|
||||||
if (validationErrors) throw validationErrors;
|
|
||||||
|
|
||||||
// Otherwise update the user/challenge
|
|
||||||
(challenge || user).tasksOrder[`${taskType}s`].unshift(newTask._id);
|
|
||||||
|
|
||||||
return newTask;
|
|
||||||
});
|
|
||||||
|
|
||||||
// If all tasks are valid, save everything, withough running validation again
|
|
||||||
toSave = toSave.map(task => task.save({
|
|
||||||
validateBeforeSave: false,
|
|
||||||
}));
|
|
||||||
toSave.unshift((challenge || user).save());
|
|
||||||
|
|
||||||
let tasks = await Q.all(toSave);
|
|
||||||
|
|
||||||
if (tasks.length === 2) {
|
|
||||||
res.respond(201, tasks[1]);
|
|
||||||
} else {
|
|
||||||
tasks.splice(0, 1); // remove the user/challenge
|
|
||||||
res.respond(201, tasks);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If adding tasks to a challenge -> sync users
|
// If adding tasks to a challenge -> sync users
|
||||||
if (challenge) challenge.addTasks(tasks); // TODO catch/log
|
if (challenge) challenge.addTasks(tasks); // TODO catch/log
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// challenge must be passed only when a challenge task is being created
|
||||||
|
async function _getTasks (req, res, user, challenge) {
|
||||||
|
let query = challenge ? {'challenge.id': challenge.id, userId: {$exists: false}} : {userId: user._id};
|
||||||
|
let type = req.query.type;
|
||||||
|
|
||||||
|
if (type) {
|
||||||
|
query.type = type;
|
||||||
|
if (type === 'todo') query.completed = false; // Exclude completed todos
|
||||||
|
} else {
|
||||||
|
query.$or = [ // Exclude completed todos
|
||||||
|
{type: 'todo', completed: false},
|
||||||
|
{type: {$in: ['habit', 'daily', 'reward']}},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (req.query.includeCompletedTodos === 'true' && (!type || type === 'todo')) {
|
||||||
|
if (challenge) throw new BadRequest(res.t('noCompletedTodosChallenge')); // no completed todos for challenges
|
||||||
|
|
||||||
|
let queryCompleted = Tasks.Task.find({
|
||||||
|
type: 'todo',
|
||||||
|
completed: true,
|
||||||
|
}).limit(30).sort({ // TODO add ability to pick more than 30 completed todos
|
||||||
|
dateCompleted: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
let results = await Q.all([
|
||||||
|
queryCompleted.exec(),
|
||||||
|
Tasks.Task.find(query).exec(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
res.respond(200, results[1].concat(results[0]));
|
||||||
|
} else {
|
||||||
|
let tasks = await Tasks.Task.find(query).exec();
|
||||||
|
res.respond(200, tasks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} /tasks/user Get an user's tasks
|
||||||
|
* @apiVersion 3.0.0
|
||||||
|
* @apiName GetUserTasks
|
||||||
|
* @apiGroup Task
|
||||||
|
*
|
||||||
|
* @apiParam {string="habit","daily","todo","reward"} type Optional query parameter to return just a type of tasks
|
||||||
|
* @apiParam {boolean} includeCompletedTodos Optional query parameter to include completed todos when "type" is "todo". Only valid whe "tasksOwner" is "user".
|
||||||
|
*
|
||||||
|
* @apiSuccess {Array} tasks An array of task objects
|
||||||
|
*/
|
||||||
|
api.getUserTasks = {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/tasks/user',
|
||||||
|
middlewares: [authWithHeaders(), cron],
|
||||||
|
async handler (req, res) {
|
||||||
|
req.checkQuery('type', res.t('invalidTaskType')).optional().isIn(Tasks.tasksTypes);
|
||||||
|
|
||||||
|
let validationErrors = req.validationErrors();
|
||||||
|
if (validationErrors) throw validationErrors;
|
||||||
|
|
||||||
|
await _getTasks(req, res, res.locals.user);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @api {get} /tasks/challenge/:challengeId Get a challenge's tasks
|
||||||
|
* @apiVersion 3.0.0
|
||||||
|
* @apiName GetChallengeTasks
|
||||||
|
* @apiGroup Task
|
||||||
|
*
|
||||||
|
* @apiParam {UUID} challengeId The id of the challenge from which to retrieve the tasks.
|
||||||
|
*
|
||||||
|
* @apiParam {string="habit","daily","todo","reward"} type Optional query parameter to return just a type of tasks
|
||||||
|
*
|
||||||
|
* @apiSuccess {Array} tasks An array of task objects
|
||||||
|
*/
|
||||||
|
api.getChallengeTasks = {
|
||||||
|
method: 'GET',
|
||||||
|
url: '/tasks/challenge/:challengeId',
|
||||||
|
middlewares: [authWithHeaders(), cron],
|
||||||
|
async handler (req, res) {
|
||||||
|
req.checkQuery('challengeId', res.t('challengeIdRequired')).notEmpty().isUUID();
|
||||||
|
req.checkQuery('type', res.t('invalidTaskType')).optional().isIn(Tasks.tasksTypes);
|
||||||
|
|
||||||
|
let validationErrors = req.validationErrors();
|
||||||
|
if (validationErrors) throw validationErrors;
|
||||||
|
|
||||||
|
let user = res.local.user;
|
||||||
|
let challengeId = req.params.challengeId;
|
||||||
|
|
||||||
|
let challenge = await Challenge.findOne({_id: challengeId}).select('leader').exec();
|
||||||
|
|
||||||
|
// If the challenge does not exist, or if it exists but user is not a member, not the leader and not an admin -> throw error
|
||||||
|
if (!challenge || (user.challenges.indexOf(challengeId) === -1 && challenge.leader !== user._id && !user.contributor.admin)) { // eslint-disable-line no-extra-parens
|
||||||
|
throw new NotFound(res.t('challengeNotFound'));
|
||||||
|
}
|
||||||
|
|
||||||
|
await _getTasks(req, res, res.locals.user, challenge);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @api {get} /tasks/:tasksOwner/:challengeId Get an user's tasks
|
* @api {get} /tasks/:tasksOwner/:challengeId Get an user's tasks
|
||||||
* @apiVersion 3.0.0
|
* @apiVersion 3.0.0
|
||||||
@@ -116,29 +225,10 @@ api.getTasks = {
|
|||||||
url: '/tasks',
|
url: '/tasks',
|
||||||
middlewares: [authWithHeaders(), cron],
|
middlewares: [authWithHeaders(), cron],
|
||||||
async handler (req, res) {
|
async handler (req, res) {
|
||||||
req.checkQuery('tasksOwner', res.t('invalidTasksOwner')).isIn(['user', 'challenge']);
|
|
||||||
req.checkQuery('challengeId', res.t('challengeIdRequired')).optional().isUUID();
|
|
||||||
req.checkQuery('type', res.t('invalidTaskType')).optional().isIn(Tasks.tasksTypes);
|
|
||||||
|
|
||||||
let validationErrors = req.validationErrors();
|
|
||||||
if (validationErrors) throw validationErrors;
|
|
||||||
|
|
||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
let tasksOwner = req.query.tasksOwner;
|
|
||||||
let challengeId = req.query.challengeId;
|
let challengeId = req.query.challengeId;
|
||||||
let challenge;
|
let challenge;
|
||||||
|
|
||||||
if (tasksOwner === 'user' && challengeId) throw new BadRequest(res.t('userTasksNoChallengeId'));
|
|
||||||
if (tasksOwner === 'challenge') {
|
|
||||||
if (!challengeId) throw new BadRequest(res.t('challengeIdRequired'));
|
|
||||||
challenge = await Challenge.findOne({_id: challengeId}).select('leader').exec();
|
|
||||||
|
|
||||||
// If the challenge does not exist, or if it exists but user is not a member, not the leader and not an admin -> throw error
|
|
||||||
if (!challenge || (user.challenges.indexOf(challengeId) === -1 && challenge.leader !== user._id && !user.contributor.admin)) { // eslint-disable-line no-extra-parens
|
|
||||||
throw new NotFound(res.t('challengeNotFound'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let query = challenge ? {'challenge.id': challengeId, userId: {$exists: false}} : {userId: user._id};
|
let query = challenge ? {'challenge.id': challengeId, userId: {$exists: false}} : {userId: user._id};
|
||||||
let type = req.query.type;
|
let type = req.query.type;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user