mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 14:47:53 +01:00
port updateTask, addTask, clearCompleted, taskDefaults, uuid
This commit is contained in:
@@ -121,6 +121,8 @@ import openMysteryItem from './ops/openMysteryItem';
|
|||||||
import releasePets from './ops/releasePets';
|
import releasePets from './ops/releasePets';
|
||||||
import releaseBoth from './ops/releaseBoth';
|
import releaseBoth from './ops/releaseBoth';
|
||||||
import releaseMounts from './ops/releaseMounts';
|
import releaseMounts from './ops/releaseMounts';
|
||||||
|
import updateTask from './ops/updateTask';
|
||||||
|
import clearCompleted from './ops/clearCompleted';
|
||||||
|
|
||||||
api.ops = {
|
api.ops = {
|
||||||
scoreTask,
|
scoreTask,
|
||||||
@@ -143,6 +145,8 @@ api.ops = {
|
|||||||
releasePets,
|
releasePets,
|
||||||
releaseBoth,
|
releaseBoth,
|
||||||
releaseMounts,
|
releaseMounts,
|
||||||
|
updateTask,
|
||||||
|
clearCompleted,
|
||||||
};
|
};
|
||||||
|
|
||||||
import handleTwoHanded from './fns/handleTwoHanded';
|
import handleTwoHanded from './fns/handleTwoHanded';
|
||||||
|
|||||||
@@ -1,71 +1,74 @@
|
|||||||
import uuid from './uuid';
|
import { v4 as uuid } from 'uuid';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
/*
|
// Even though Mongoose handles task defaults, we want to make sure defaults are set on the client-side before
|
||||||
Even though Mongoose handles task defaults, we want to make sure defaults are set on the client-side before
|
// sending up to the server for performance
|
||||||
sending up to the server for performance
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO revisit
|
// TODO move to client code?
|
||||||
|
|
||||||
module.exports = function(task) {
|
const tasksTypes = ['habit', 'daily', 'todo', 'reward'];
|
||||||
var defaults, ref, ref1, ref2;
|
|
||||||
if (task == null) {
|
module.exports = function taskDefaults (task = {}) {
|
||||||
task = {};
|
if (!task.type || tasksTypes.indexOf(task.type) === -1) {
|
||||||
}
|
|
||||||
if (!(task.type && ((ref = task.type) === 'habit' || ref === 'daily' || ref === 'todo' || ref === 'reward'))) {
|
|
||||||
task.type = 'habit';
|
task.type = 'habit';
|
||||||
}
|
}
|
||||||
defaults = {
|
|
||||||
id: uuid(),
|
let defaultId = uuid();
|
||||||
text: task.id != null ? task.id : '',
|
let defaults = {
|
||||||
|
_id: defaultId, // TODO convert all occurencies of id to _id
|
||||||
|
text: task._id || defaultId,
|
||||||
notes: '',
|
notes: '',
|
||||||
|
tags: [],
|
||||||
|
value: task.type === 'reward' ? 10 : 0,
|
||||||
priority: 1,
|
priority: 1,
|
||||||
challenge: {},
|
challenge: {},
|
||||||
|
reminders: {},
|
||||||
attribute: 'str',
|
attribute: 'str',
|
||||||
dateCreated: new Date()
|
createdAt: new Date(), // TODO these are going to be overwritten by the server...
|
||||||
|
updatedAt: new Date(),
|
||||||
};
|
};
|
||||||
|
|
||||||
_.defaults(task, defaults);
|
_.defaults(task, defaults);
|
||||||
|
|
||||||
|
if (task.type === 'habit' || task.type === 'daily') {
|
||||||
|
_.defaults(task, {
|
||||||
|
history: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (task.type === 'todo' || task.type === 'daily') {
|
||||||
|
_.defaults(task, {
|
||||||
|
completed: false,
|
||||||
|
collapseChecklist: false,
|
||||||
|
checklist: [],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (task.type === 'habit') {
|
if (task.type === 'habit') {
|
||||||
_.defaults(task, {
|
_.defaults(task, {
|
||||||
up: true,
|
up: true,
|
||||||
down: true
|
down: true,
|
||||||
});
|
|
||||||
}
|
|
||||||
if ((ref1 = task.type) === 'habit' || ref1 === 'daily') {
|
|
||||||
_.defaults(task, {
|
|
||||||
history: []
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if ((ref2 = task.type) === 'daily' || ref2 === 'todo') {
|
|
||||||
_.defaults(task, {
|
|
||||||
completed: false
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.type === 'daily') {
|
if (task.type === 'daily') {
|
||||||
_.defaults(task, {
|
_.defaults(task, {
|
||||||
streak: 0,
|
streak: 0,
|
||||||
repeat: {
|
repeat: {
|
||||||
su: true,
|
|
||||||
m: true,
|
m: true,
|
||||||
t: true,
|
t: true,
|
||||||
w: true,
|
w: true,
|
||||||
th: true,
|
th: true,
|
||||||
f: true,
|
f: true,
|
||||||
s: true
|
s: true,
|
||||||
}
|
su: true,
|
||||||
}, {
|
},
|
||||||
startDate: new Date(),
|
startDate: moment().startOf('day').toDate(),
|
||||||
everyX: 1,
|
everyX: 1,
|
||||||
frequency: 'weekly'
|
frequency: 'weekly',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
task._id = task.id;
|
|
||||||
if (task.value == null) {
|
|
||||||
task.value = task.type === 'reward' ? 10 : 0;
|
|
||||||
}
|
|
||||||
if (!_.isNumber(task.priority)) {
|
|
||||||
task.priority = 1;
|
|
||||||
}
|
|
||||||
return task;
|
return task;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,4 @@
|
|||||||
// TODO use node-uuid module
|
import uuid from 'uuid';
|
||||||
module.exports = function() {
|
|
||||||
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
// TODO remove this file completely
|
||||||
var r, v;
|
module.exports = uuid.v4;
|
||||||
r = Math.random() * 16 | 0;
|
|
||||||
v = (c === "x" ? r : r & 0x3 | 0x8);
|
|
||||||
return v.toString(16);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,27 +1,22 @@
|
|||||||
import taskDefaults from '../libs/taskDefaults';
|
import taskDefaults from '../libs/taskDefaults';
|
||||||
import i18n from '../i18n';
|
|
||||||
|
|
||||||
module.exports = function(user, req, cb) {
|
// TODO move to client since it's only used there?
|
||||||
var task;
|
|
||||||
task = taskDefaults(req.body);
|
module.exports = function addTask (user, req = {body: {}}) {
|
||||||
if (user.tasks[task.id] != null) {
|
let task = taskDefaults(req.body);
|
||||||
return typeof cb === "function" ? cb({
|
user.tasksOrder[`${task.type}s`].unshift(task._id);
|
||||||
code: 409,
|
|
||||||
message: i18n.t('messageDuplicateTaskID', req.language)
|
|
||||||
}) : void 0;
|
|
||||||
}
|
|
||||||
user[task.type + "s"].unshift(task);
|
|
||||||
if (user.preferences.newTaskEdit) {
|
if (user.preferences.newTaskEdit) {
|
||||||
task._editing = true;
|
task._editing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.preferences.tagsCollapsed) {
|
if (user.preferences.tagsCollapsed) {
|
||||||
task._tags = true;
|
task._tags = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!user.preferences.advancedCollapsed) {
|
if (!user.preferences.advancedCollapsed) {
|
||||||
task._advanced = true;
|
task._advanced = true;
|
||||||
}
|
}
|
||||||
if (typeof cb === "function") {
|
|
||||||
cb(null, task);
|
|
||||||
}
|
|
||||||
return task;
|
return task;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
module.exports = function(user, req, cb) {
|
// TODO move to client since it's only used there?
|
||||||
_.remove(user.todos, function(t) {
|
// TODO rename file to clearCompletedTodos
|
||||||
var ref;
|
|
||||||
return t.completed && !((ref = t.challenge) != null ? ref.id : void 0);
|
module.exports = function clearCompletedTodos (todos) {
|
||||||
|
_.remove(todos, todo => {
|
||||||
|
return todo.completed && (!todo.challenge || !todo.challenge.id || todo.challenge.broken);
|
||||||
});
|
});
|
||||||
if (typeof user.markModified === "function") {
|
|
||||||
user.markModified('todos');
|
|
||||||
}
|
|
||||||
return typeof cb === "function" ? cb(null, user.todos) : void 0;
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,23 +1,26 @@
|
|||||||
import i18n from '../i18n';
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
module.exports = function(user, req, cb) {
|
// From server pass task.toObject() not the task document directly
|
||||||
var ref, task;
|
module.exports = function updateTask (task, req = {}) {
|
||||||
if (!(task = user.tasks[(ref = req.params) != null ? ref.id : void 0])) {
|
// If reminders are updated -> replace the original ones
|
||||||
return typeof cb === "function" ? cb({
|
|
||||||
code: 404,
|
|
||||||
message: i18n.t('messageTaskNotFound', req.language)
|
|
||||||
}) : void 0;
|
|
||||||
}
|
|
||||||
_.merge(task, _.omit(req.body, ['checklist', 'reminders', 'id', 'type']));
|
|
||||||
if (req.body.checklist) {
|
|
||||||
task.checklist = req.body.checklist;
|
|
||||||
}
|
|
||||||
if (req.body.reminders) {
|
if (req.body.reminders) {
|
||||||
task.reminders = req.body.reminders;
|
task.reminders = req.body.reminders;
|
||||||
|
delete req.body.reminders;
|
||||||
}
|
}
|
||||||
if (typeof task.markModified === "function") {
|
|
||||||
task.markModified('tags');
|
// If checklist is updated -> replace the original one
|
||||||
|
if (req.body.checklist) {
|
||||||
|
task.checklist = req.body.checklist;
|
||||||
|
delete req.body.checklist;
|
||||||
}
|
}
|
||||||
return typeof cb === "function" ? cb(null, task) : void 0;
|
|
||||||
|
// If tags are updated -> replace the original ones
|
||||||
|
if (req.body.tags) {
|
||||||
|
task.tags = req.body.tags;
|
||||||
|
delete req.body.tags;
|
||||||
|
}
|
||||||
|
|
||||||
|
_.merge(task, _.omit(req.body, ['_id', 'id', 'type']));
|
||||||
|
|
||||||
|
return task;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -90,7 +90,8 @@
|
|||||||
"validator": "~4.2.1",
|
"validator": "~4.2.1",
|
||||||
"vinyl-buffer": "^1.0.0",
|
"vinyl-buffer": "^1.0.0",
|
||||||
"vinyl-source-stream": "^1.1.0",
|
"vinyl-source-stream": "^1.1.0",
|
||||||
"winston": "^2.1.0"
|
"winston": "^2.1.0",
|
||||||
|
"uuid": "^2.0.1"
|
||||||
},
|
},
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
@@ -153,7 +154,6 @@
|
|||||||
"sinon": "^1.17.2",
|
"sinon": "^1.17.2",
|
||||||
"sinon-chai": "^2.8.0",
|
"sinon-chai": "^2.8.0",
|
||||||
"superagent-defaults": "^0.1.13",
|
"superagent-defaults": "^0.1.13",
|
||||||
"uuid": "^2.0.1",
|
|
||||||
"vinyl-source-stream": "^1.0.0",
|
"vinyl-source-stream": "^1.0.0",
|
||||||
"vinyl-transform": "^1.0.0",
|
"vinyl-transform": "^1.0.0",
|
||||||
"xml2js": "^0.4.16"
|
"xml2js": "^0.4.16"
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ const COMMON_FILES = [
|
|||||||
'!./common/script/content/index.js',
|
'!./common/script/content/index.js',
|
||||||
'!./common/script/ops/addPushDevice.js',
|
'!./common/script/ops/addPushDevice.js',
|
||||||
'!./common/script/ops/addTag.js',
|
'!./common/script/ops/addTag.js',
|
||||||
'!./common/script/ops/addTask.js',
|
|
||||||
'!./common/script/ops/addWebhook.js',
|
'!./common/script/ops/addWebhook.js',
|
||||||
'!./common/script/ops/blockUser.js',
|
'!./common/script/ops/blockUser.js',
|
||||||
'!./common/script/ops/clearCompleted.js',
|
|
||||||
'!./common/script/ops/clearPMs.js',
|
'!./common/script/ops/clearPMs.js',
|
||||||
'!./common/script/ops/deletePM.js',
|
'!./common/script/ops/deletePM.js',
|
||||||
'!./common/script/ops/deleteTag.js',
|
'!./common/script/ops/deleteTag.js',
|
||||||
@@ -36,7 +34,6 @@ const COMMON_FILES = [
|
|||||||
'!./common/script/ops/unlock.js',
|
'!./common/script/ops/unlock.js',
|
||||||
'!./common/script/ops/update.js',
|
'!./common/script/ops/update.js',
|
||||||
'!./common/script/ops/updateTag.js',
|
'!./common/script/ops/updateTag.js',
|
||||||
'!./common/script/ops/updateTask.js',
|
|
||||||
'!./common/script/ops/updateWebhook.js',
|
'!./common/script/ops/updateWebhook.js',
|
||||||
'!./common/script/fns/crit.js',
|
'!./common/script/fns/crit.js',
|
||||||
'!./common/script/fns/cron.js',
|
'!./common/script/fns/cron.js',
|
||||||
@@ -63,8 +60,6 @@ const COMMON_FILES = [
|
|||||||
'!./common/script/libs/silver.js',
|
'!./common/script/libs/silver.js',
|
||||||
'!./common/script/libs/splitWhitespace.js',
|
'!./common/script/libs/splitWhitespace.js',
|
||||||
'!./common/script/libs/taskClasses.js',
|
'!./common/script/libs/taskClasses.js',
|
||||||
'!./common/script/libs/taskDefaults.js',
|
|
||||||
'!./common/script/libs/uuid.js',
|
|
||||||
'!./common/script/public/**/*.js',
|
'!./common/script/public/**/*.js',
|
||||||
];
|
];
|
||||||
const TEST_FILES = [
|
const TEST_FILES = [
|
||||||
|
|||||||
135
test/common/ops/addTask.js
Normal file
135
test/common/ops/addTask.js
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
import addTask from '../../../common/script/ops/addTask';
|
||||||
|
import {
|
||||||
|
generateUser,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
|
||||||
|
describe('shared.ops.addTask', () => {
|
||||||
|
let user;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
user = generateUser();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds an habit', () => {
|
||||||
|
let habit = addTask(user, {
|
||||||
|
body: {
|
||||||
|
type: 'habit',
|
||||||
|
text: 'habit',
|
||||||
|
down: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(user.tasksOrder.habits).to.eql([
|
||||||
|
habit._id,
|
||||||
|
]);
|
||||||
|
expect(habit._id).to.be.a('string');
|
||||||
|
expect(habit.text).to.equal('habit');
|
||||||
|
expect(habit.type).to.equal('habit');
|
||||||
|
expect(habit.up).to.equal(true);
|
||||||
|
expect(habit.down).to.equal(false);
|
||||||
|
expect(habit.history).to.eql([]);
|
||||||
|
expect(habit.checklist).to.not.exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds an habtit when type is invalid', () => {
|
||||||
|
let habit = addTask(user, {
|
||||||
|
body: {
|
||||||
|
type: 'invalid',
|
||||||
|
text: 'habit',
|
||||||
|
down: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(user.tasksOrder.habits).to.eql([
|
||||||
|
habit._id,
|
||||||
|
]);
|
||||||
|
expect(habit._id).to.be.a('string');
|
||||||
|
expect(habit.text).to.equal('habit');
|
||||||
|
expect(habit.type).to.equal('habit');
|
||||||
|
expect(habit.up).to.equal(true);
|
||||||
|
expect(habit.down).to.equal(false);
|
||||||
|
expect(habit.history).to.eql([]);
|
||||||
|
expect(habit.checklist).to.not.exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds a daily', () => {
|
||||||
|
let daily = addTask(user, {
|
||||||
|
body: {
|
||||||
|
type: 'daily',
|
||||||
|
text: 'daily',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(user.tasksOrder.dailys).to.eql([
|
||||||
|
daily._id,
|
||||||
|
]);
|
||||||
|
expect(daily._id).to.be.a('string');
|
||||||
|
expect(daily.type).to.equal('daily');
|
||||||
|
expect(daily.text).to.equal('daily');
|
||||||
|
expect(daily.history).to.eql([]);
|
||||||
|
expect(daily.checklist).to.eql([]);
|
||||||
|
expect(daily.completed).to.be.false;
|
||||||
|
expect(daily.up).to.not.exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds a todo', () => {
|
||||||
|
let todo = addTask(user, {
|
||||||
|
body: {
|
||||||
|
type: 'todo',
|
||||||
|
text: 'todo',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(user.tasksOrder.todos).to.eql([
|
||||||
|
todo._id,
|
||||||
|
]);
|
||||||
|
expect(todo._id).to.be.a('string');
|
||||||
|
expect(todo.type).to.equal('todo');
|
||||||
|
expect(todo.text).to.equal('todo');
|
||||||
|
expect(todo.checklist).to.eql([]);
|
||||||
|
expect(todo.completed).to.be.false;
|
||||||
|
expect(todo.up).to.not.exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('adds a reward', () => {
|
||||||
|
let reward = addTask(user, {
|
||||||
|
body: {
|
||||||
|
type: 'reward',
|
||||||
|
text: 'reward',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(user.tasksOrder.rewards).to.eql([
|
||||||
|
reward._id,
|
||||||
|
]);
|
||||||
|
expect(reward._id).to.be.a('string');
|
||||||
|
expect(reward.type).to.equal('reward');
|
||||||
|
expect(reward.text).to.equal('reward');
|
||||||
|
expect(reward.value).to.equal(10);
|
||||||
|
expect(reward.up).to.not.exists;
|
||||||
|
});
|
||||||
|
|
||||||
|
context('respects preferences', () => {
|
||||||
|
it('true', () => {
|
||||||
|
user.preferences.newTaskEdit = true;
|
||||||
|
user.preferences.tagsCollapsed = true;
|
||||||
|
user.preferences.advancedCollapsed = false;
|
||||||
|
let task = addTask(user);
|
||||||
|
|
||||||
|
expect(task._editing).to.be.true;
|
||||||
|
expect(task._tags).to.be.true;
|
||||||
|
expect(task._advanced).to.be.true;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('false', () => {
|
||||||
|
user.preferences.newTaskEdit = false;
|
||||||
|
user.preferences.tagsCollapsed = false;
|
||||||
|
user.preferences.advancedCollapsed = true;
|
||||||
|
let task = addTask(user);
|
||||||
|
|
||||||
|
expect(task._editing).to.not.exists;
|
||||||
|
expect(task._tags).to.not.exists;
|
||||||
|
expect(task._advanced).to.not.exists;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
37
test/common/ops/clearCompleted.js
Normal file
37
test/common/ops/clearCompleted.js
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import clearCompleted from '../../../common/script/ops/clearCompleted';
|
||||||
|
import {
|
||||||
|
generateTodo,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
|
||||||
|
describe('shared.ops.clearCompleted', () => {
|
||||||
|
it('clear completed todos', () => {
|
||||||
|
let todos = [
|
||||||
|
generateTodo({text: 'todo'}),
|
||||||
|
generateTodo({
|
||||||
|
text: 'done',
|
||||||
|
completed: true,
|
||||||
|
}),
|
||||||
|
generateTodo({
|
||||||
|
text: 'done chellenge broken',
|
||||||
|
completed: true,
|
||||||
|
challenge: {
|
||||||
|
id: 123,
|
||||||
|
broken: 'TASK_DELETED',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
generateTodo({
|
||||||
|
text: 'done chellenge not broken',
|
||||||
|
completed: true,
|
||||||
|
challenge: {
|
||||||
|
id: 123,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
];
|
||||||
|
|
||||||
|
clearCompleted(todos);
|
||||||
|
|
||||||
|
expect(todos.length).to.equal(2);
|
||||||
|
expect(todos[0].text).to.equal('todo');
|
||||||
|
expect(todos[1].text).to.equal('done chellenge not broken');
|
||||||
|
});
|
||||||
|
});
|
||||||
53
test/common/ops/updateTask.js
Normal file
53
test/common/ops/updateTask.js
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import updateTask from '../../../common/script/ops/updateTask';
|
||||||
|
import {
|
||||||
|
generateHabit,
|
||||||
|
} from '../../helpers/common.helper';
|
||||||
|
|
||||||
|
describe('shared.ops.updateTask', () => {
|
||||||
|
it('updates a task', () => {
|
||||||
|
let now = new Date();
|
||||||
|
let habit = generateHabit({
|
||||||
|
tags: [
|
||||||
|
'123',
|
||||||
|
'456',
|
||||||
|
],
|
||||||
|
|
||||||
|
reminders: [{
|
||||||
|
_id: '123',
|
||||||
|
startDate: now,
|
||||||
|
time: now,
|
||||||
|
}],
|
||||||
|
});
|
||||||
|
|
||||||
|
let res = updateTask(habit, {
|
||||||
|
body: {
|
||||||
|
text: 'updated',
|
||||||
|
id: '123',
|
||||||
|
_id: '123',
|
||||||
|
type: 'todo',
|
||||||
|
tags: ['678'],
|
||||||
|
checklist: [{
|
||||||
|
completed: false,
|
||||||
|
text: 'item',
|
||||||
|
_id: '123',
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res.id).to.not.equal('123');
|
||||||
|
expect(res._id).to.not.equal('123');
|
||||||
|
expect(res.type).to.equal('habit');
|
||||||
|
expect(res.text).to.equal('updated');
|
||||||
|
expect(res.checklist).to.eql([{
|
||||||
|
completed: false,
|
||||||
|
text: 'item',
|
||||||
|
_id: '123',
|
||||||
|
}]);
|
||||||
|
expect(res.reminders).to.eql([{
|
||||||
|
_id: '123',
|
||||||
|
startDate: now,
|
||||||
|
time: now,
|
||||||
|
}]);
|
||||||
|
expect(res.tags).to.eql(['678']);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -324,7 +324,7 @@ api.updateTask = {
|
|||||||
|
|
||||||
// TODO we have to convert task to an object because otherwise things don't get merged correctly. Bad for performances?
|
// TODO we have to convert task to an object because otherwise things don't get merged correctly. Bad for performances?
|
||||||
// TODO regarding comment above, make sure other models with nested fields are using this trick too
|
// TODO regarding comment above, make sure other models with nested fields are using this trick too
|
||||||
_.assign(task, _.merge(task.toObject(), Tasks.Task.sanitizeUpdate(req.body)));
|
_.assign(task, common.ops.updateTask(task.toObject(), req));
|
||||||
// TODO console.log(task.modifiedPaths(), task.toObject().repeat === tep)
|
// TODO console.log(task.modifiedPaths(), task.toObject().repeat === tep)
|
||||||
// repeat is always among modifiedPaths because mongoose changes the other of the keys when using .toObject()
|
// repeat is always among modifiedPaths because mongoose changes the other of the keys when using .toObject()
|
||||||
// see https://github.com/Automattic/mongoose/issues/2749
|
// see https://github.com/Automattic/mongoose/issues/2749
|
||||||
@@ -836,12 +836,15 @@ api.clearCompletedTodos = {
|
|||||||
let user = res.locals.user;
|
let user = res.locals.user;
|
||||||
|
|
||||||
// Clear completed todos
|
// Clear completed todos
|
||||||
// Do not delete challenges completed todos TODO unless the task is broken?
|
// Do not delete challenges completed todos unless the task is broken
|
||||||
await Tasks.Task.remove({
|
await Tasks.Task.remove({
|
||||||
userId: user._id,
|
userId: user._id,
|
||||||
type: 'todo',
|
type: 'todo',
|
||||||
completed: true,
|
completed: true,
|
||||||
'challenge.id': {$exists: false},
|
$or: [
|
||||||
|
{'challenge.id': {$exists: false}},
|
||||||
|
{'challenge.broken': {$exists: true}},
|
||||||
|
],
|
||||||
}).exec();
|
}).exec();
|
||||||
|
|
||||||
res.respond(200, {});
|
res.respond(200, {});
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { uuid } from '../../../../common';
|
import { v4 as uuid } from 'uuid';
|
||||||
import validator from 'validator';
|
import validator from 'validator';
|
||||||
import objectPath from 'object-path'; // TODO use lodash's unset once v4 is out
|
import objectPath from 'object-path'; // TODO use lodash's unset once v4 is out
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ let subDiscriminatorOptions = _.defaults(_.cloneDeep(discriminatorOptions), {_id
|
|||||||
|
|
||||||
export let tasksTypes = ['habit', 'daily', 'todo', 'reward'];
|
export let tasksTypes = ['habit', 'daily', 'todo', 'reward'];
|
||||||
|
|
||||||
|
// Important
|
||||||
|
// When something changes here remember to update the client side model at common/script/libs/taskDefaults
|
||||||
export let TaskSchema = new Schema({
|
export let TaskSchema = new Schema({
|
||||||
type: {type: String, enum: tasksTypes, required: true, default: tasksTypes[0]},
|
type: {type: String, enum: tasksTypes, required: true, default: tasksTypes[0]},
|
||||||
text: {type: String, required: true},
|
text: {type: String, required: true},
|
||||||
@@ -35,7 +37,7 @@ export let TaskSchema = new Schema({
|
|||||||
},
|
},
|
||||||
|
|
||||||
reminders: [{
|
reminders: [{
|
||||||
id: {type: String, validate: [validator.isUUID, 'Invalid uuid.'], default: shared.uuid, required: true},
|
_id: {type: String, validate: [validator.isUUID, 'Invalid uuid.'], default: shared.uuid, required: true},
|
||||||
startDate: {type: Date, required: true},
|
startDate: {type: Date, required: true},
|
||||||
time: {type: Date, required: true},
|
time: {type: Date, required: true},
|
||||||
}],
|
}],
|
||||||
|
|||||||
Reference in New Issue
Block a user