mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-17 06:37:23 +01:00
If user's cron will happen later today, start the task yesterday. (#10783)
* If user's cron will happen later today, start the task yesterday. * Added default dayStart to taskDefaults. * Removed the need to call shouldDo twice to calculate nextDue. * Revert "Removed the need to call shouldDo twice to calculate nextDue." This reverts commit e1467f2fc33cfb11e6a4fc667460df6a48b69d45. * Removed defaults from taskDefault arguments. * Got user from $store in copyAsTodoModal.vue. * Fixed tests for taskDefaults to include mock user. * Fix shouldDo tests when run in GMT timezone. * Added test to taskDefault; added utcOffset to taskDefault. * Replaced utcOffset with zone. * Removed erroneous import.
This commit is contained in:
committed by
Matteo Pagliazzi
parent
12aef475c8
commit
a48a6a292d
@@ -1,8 +1,11 @@
|
|||||||
|
import moment from 'moment';
|
||||||
|
|
||||||
import taskDefaults from '../../../website/common/script/libs/taskDefaults';
|
import taskDefaults from '../../../website/common/script/libs/taskDefaults';
|
||||||
|
import { generateUser } from '../../helpers/common.helper';
|
||||||
|
|
||||||
describe('taskDefaults', () => {
|
describe('taskDefaults', () => {
|
||||||
it('applies defaults to undefined type or habit', () => {
|
it('applies defaults to undefined type or habit', () => {
|
||||||
let task = taskDefaults();
|
let task = taskDefaults({}, generateUser());
|
||||||
expect(task.type).to.eql('habit');
|
expect(task.type).to.eql('habit');
|
||||||
expect(task._id).to.exist;
|
expect(task._id).to.exist;
|
||||||
expect(task.text).to.eql(task._id);
|
expect(task.text).to.eql(task._id);
|
||||||
@@ -18,7 +21,7 @@ describe('taskDefaults', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('applies defaults to a daily', () => {
|
it('applies defaults to a daily', () => {
|
||||||
let task = taskDefaults({ type: 'daily' });
|
let task = taskDefaults({ type: 'daily' }, generateUser());
|
||||||
expect(task.type).to.eql('daily');
|
expect(task.type).to.eql('daily');
|
||||||
expect(task._id).to.exist;
|
expect(task._id).to.exist;
|
||||||
expect(task.text).to.eql(task._id);
|
expect(task.text).to.eql(task._id);
|
||||||
@@ -42,7 +45,7 @@ describe('taskDefaults', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('applies defaults a reward', () => {
|
it('applies defaults a reward', () => {
|
||||||
let task = taskDefaults({ type: 'reward' });
|
let task = taskDefaults({ type: 'reward' }, generateUser());
|
||||||
expect(task.type).to.eql('reward');
|
expect(task.type).to.eql('reward');
|
||||||
expect(task._id).to.exist;
|
expect(task._id).to.exist;
|
||||||
expect(task.text).to.eql(task._id);
|
expect(task.text).to.eql(task._id);
|
||||||
@@ -52,7 +55,7 @@ describe('taskDefaults', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('applies defaults a todo', () => {
|
it('applies defaults a todo', () => {
|
||||||
let task = taskDefaults({ type: 'todo' });
|
let task = taskDefaults({ type: 'todo' }, generateUser());
|
||||||
expect(task.type).to.eql('todo');
|
expect(task.type).to.eql('todo');
|
||||||
expect(task._id).to.exist;
|
expect(task._id).to.exist;
|
||||||
expect(task.text).to.eql(task._id);
|
expect(task.text).to.eql(task._id);
|
||||||
@@ -61,4 +64,18 @@ describe('taskDefaults', () => {
|
|||||||
expect(task.priority).to.eql(1);
|
expect(task.priority).to.eql(1);
|
||||||
expect(task.completed).to.eql(false);
|
expect(task.completed).to.eql(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('starts a task yesterday if user cron is later today', () => {
|
||||||
|
// Configure to have a day start that's *always* tomorrow.
|
||||||
|
let user = generateUser({'preferences.dayStart': 25});
|
||||||
|
let task = taskDefaults({ type: 'daily' }, user);
|
||||||
|
|
||||||
|
expect(task.startDate).to.eql(
|
||||||
|
moment()
|
||||||
|
.zone(user.preferences.timezoneOffset, 'hour')
|
||||||
|
.startOf('day')
|
||||||
|
.subtract(1, 'day')
|
||||||
|
.toDate()
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ describe('shouldDo', () => {
|
|||||||
options.timezoneOffset = 0;
|
options.timezoneOffset = 0;
|
||||||
options.nextDue = true;
|
options.nextDue = true;
|
||||||
|
|
||||||
day = moment('2017-05-01').toDate();
|
day = moment.utc('2017-05-01').toDate();
|
||||||
dailyTask.frequency = 'daily';
|
dailyTask.frequency = 'daily';
|
||||||
dailyTask.everyX = 2;
|
dailyTask.everyX = 2;
|
||||||
dailyTask.startDate = day;
|
dailyTask.startDate = day;
|
||||||
@@ -391,7 +391,7 @@ describe('shouldDo', () => {
|
|||||||
options.timezoneOffset = 0;
|
options.timezoneOffset = 0;
|
||||||
options.nextDue = true;
|
options.nextDue = true;
|
||||||
|
|
||||||
day = moment('2017-05-01').toDate();
|
day = moment.utc('2017-05-01').toDate();
|
||||||
dailyTask.frequency = 'weekly';
|
dailyTask.frequency = 'weekly';
|
||||||
dailyTask.everyX = 1;
|
dailyTask.everyX = 1;
|
||||||
dailyTask.repeat = {
|
dailyTask.repeat = {
|
||||||
@@ -780,7 +780,7 @@ describe('shouldDo', () => {
|
|||||||
options.timezoneOffset = 0;
|
options.timezoneOffset = 0;
|
||||||
options.nextDue = true;
|
options.nextDue = true;
|
||||||
|
|
||||||
day = moment('2017-05-01').toDate();
|
day = moment.utc('2017-05-01').toDate();
|
||||||
|
|
||||||
dailyTask.frequency = 'monthly';
|
dailyTask.frequency = 'monthly';
|
||||||
dailyTask.everyX = 3;
|
dailyTask.everyX = 3;
|
||||||
@@ -817,7 +817,7 @@ describe('shouldDo', () => {
|
|||||||
expect(moment(nextDue[4]).toDate()).to.eql(moment.utc('2017-10-02').toDate());
|
expect(moment(nextDue[4]).toDate()).to.eql(moment.utc('2017-10-02').toDate());
|
||||||
expect(moment(nextDue[5]).toDate()).to.eql(moment.utc('2017-11-06').toDate());
|
expect(moment(nextDue[5]).toDate()).to.eql(moment.utc('2017-11-06').toDate());
|
||||||
|
|
||||||
day = moment('2017-05-08').toDate();
|
day = moment.utc('2017-05-08').toDate();
|
||||||
|
|
||||||
dailyTask.daysOfMonth = [];
|
dailyTask.daysOfMonth = [];
|
||||||
dailyTask.weeksOfMonth = [1];
|
dailyTask.weeksOfMonth = [1];
|
||||||
@@ -841,7 +841,7 @@ describe('shouldDo', () => {
|
|||||||
expect(moment(nextDue[4]).toDate()).to.eql(moment.utc('2017-10-09').toDate());
|
expect(moment(nextDue[4]).toDate()).to.eql(moment.utc('2017-10-09').toDate());
|
||||||
expect(moment(nextDue[5]).toDate()).to.eql(moment.utc('2017-11-13').toDate());
|
expect(moment(nextDue[5]).toDate()).to.eql(moment.utc('2017-11-13').toDate());
|
||||||
|
|
||||||
day = moment('2017-05-29').toDate();
|
day = moment.utc('2017-05-29').toDate();
|
||||||
|
|
||||||
dailyTask.daysOfMonth = [];
|
dailyTask.daysOfMonth = [];
|
||||||
dailyTask.weeksOfMonth = [4];
|
dailyTask.weeksOfMonth = [4];
|
||||||
@@ -1143,7 +1143,7 @@ describe('shouldDo', () => {
|
|||||||
options.timezoneOffset = 0;
|
options.timezoneOffset = 0;
|
||||||
options.nextDue = true;
|
options.nextDue = true;
|
||||||
|
|
||||||
day = moment('2017-05-01').toDate();
|
day = moment.utc('2017-05-01').toDate();
|
||||||
|
|
||||||
dailyTask.frequency = 'yearly';
|
dailyTask.frequency = 'yearly';
|
||||||
dailyTask.everyX = 5;
|
dailyTask.everyX = 5;
|
||||||
|
|||||||
@@ -317,7 +317,7 @@ export default {
|
|||||||
},
|
},
|
||||||
createTask (type) {
|
createTask (type) {
|
||||||
this.taskFormPurpose = 'create';
|
this.taskFormPurpose = 'create';
|
||||||
this.creatingTask = taskDefaults({type, text: ''});
|
this.creatingTask = taskDefaults({type, text: ''}, this.user);
|
||||||
this.workingTask = this.creatingTask;
|
this.workingTask = this.creatingTask;
|
||||||
// Necessary otherwise the first time the modal is not rendered
|
// Necessary otherwise the first time the modal is not rendered
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default {
|
|||||||
type: 'todo',
|
type: 'todo',
|
||||||
notes,
|
notes,
|
||||||
};
|
};
|
||||||
this.task = taskDefaults(newTask);
|
this.task = taskDefaults(newTask, this.$store.state.user.data);
|
||||||
this.$root.$emit('bv::show::modal', 'copyAsTodo');
|
this.$root.$emit('bv::show::modal', 'copyAsTodo');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -401,7 +401,7 @@ export default {
|
|||||||
},
|
},
|
||||||
createTask (type) {
|
createTask (type) {
|
||||||
this.taskFormPurpose = 'create';
|
this.taskFormPurpose = 'create';
|
||||||
this.creatingTask = taskDefaults({type, text: ''});
|
this.creatingTask = taskDefaults({type, text: ''}, this.user);
|
||||||
this.workingTask = this.creatingTask;
|
this.workingTask = this.creatingTask;
|
||||||
// Necessary otherwise the first time the modal is not rendered
|
// Necessary otherwise the first time the modal is not rendered
|
||||||
Vue.nextTick(() => {
|
Vue.nextTick(() => {
|
||||||
|
|||||||
@@ -540,7 +540,7 @@ export default {
|
|||||||
const tasks = text.split('\n').reverse().filter(taskText => {
|
const tasks = text.split('\n').reverse().filter(taskText => {
|
||||||
return taskText ? true : false;
|
return taskText ? true : false;
|
||||||
}).map(taskText => {
|
}).map(taskText => {
|
||||||
const task = taskDefaults({type: this.type, text: taskText});
|
const task = taskDefaults({type: this.type, text: taskText}, this.user);
|
||||||
task.tags = this.selectedTags;
|
task.tags = this.selectedTags;
|
||||||
return task;
|
return task;
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ export default {
|
|||||||
},
|
},
|
||||||
createTask (type) {
|
createTask (type) {
|
||||||
this.openCreateBtn = false;
|
this.openCreateBtn = false;
|
||||||
this.creatingTask = taskDefaults({type, text: ''});
|
this.creatingTask = taskDefaults({type, text: ''}, this.user);
|
||||||
this.creatingTask.tags = this.selectedTags;
|
this.creatingTask.tags = this.selectedTags;
|
||||||
|
|
||||||
// Necessary otherwise the first time the modal is not rendered
|
// Necessary otherwise the first time the modal is not rendered
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import moment from 'moment';
|
|||||||
|
|
||||||
const tasksTypes = ['habit', 'daily', 'todo', 'reward'];
|
const tasksTypes = ['habit', 'daily', 'todo', 'reward'];
|
||||||
|
|
||||||
module.exports = function taskDefaults (task = {}) {
|
module.exports = function taskDefaults (task, user) {
|
||||||
if (!task.type || tasksTypes.indexOf(task.type) === -1) {
|
if (!task.type || tasksTypes.indexOf(task.type) === -1) {
|
||||||
task.type = 'habit';
|
task.type = 'habit';
|
||||||
}
|
}
|
||||||
@@ -65,6 +65,14 @@ module.exports = function taskDefaults (task = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (task.type === 'daily') {
|
if (task.type === 'daily') {
|
||||||
|
let now = moment().zone(user.preferences.timezoneOffset);
|
||||||
|
let startOfDay = now.clone().startOf('day');
|
||||||
|
let startOfDayWithCDSTime = startOfDay
|
||||||
|
.clone()
|
||||||
|
.add({
|
||||||
|
hours: user.preferences.dayStart,
|
||||||
|
});
|
||||||
|
|
||||||
defaults(task, {
|
defaults(task, {
|
||||||
streak: 0,
|
streak: 0,
|
||||||
repeat: {
|
repeat: {
|
||||||
@@ -76,7 +84,10 @@ module.exports = function taskDefaults (task = {}) {
|
|||||||
s: true,
|
s: true,
|
||||||
su: true,
|
su: true,
|
||||||
},
|
},
|
||||||
startDate: moment().startOf('day').toDate(),
|
// If cron will happen today, start the daily yesterday
|
||||||
|
startDate: startOfDayWithCDSTime.isAfter(now) ?
|
||||||
|
startOfDay.clone().subtract(1, 'day').toDate() :
|
||||||
|
startOfDay.toDate(),
|
||||||
everyX: 1,
|
everyX: 1,
|
||||||
frequency: 'weekly',
|
frequency: 'weekly',
|
||||||
daysOfMonth: [],
|
daysOfMonth: [],
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import clone from 'lodash/clone';
|
|||||||
// TODO move to client since it's only used there?
|
// TODO move to client since it's only used there?
|
||||||
|
|
||||||
module.exports = function addTask (user, req = {body: {}}) {
|
module.exports = function addTask (user, req = {body: {}}) {
|
||||||
let task = taskDefaults(req.body);
|
let task = taskDefaults(req.body, user);
|
||||||
user.tasksOrder[`${task.type}s`].unshift(task._id);
|
user.tasksOrder[`${task.type}s`].unshift(task._id);
|
||||||
user[`${task.type}s`].unshift(task);
|
user[`${task.type}s`].unshift(task);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user