mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-07-14 02:02:19 +00:00
merge cron-fix
This commit is contained in:
commit
d63cc4da8f
3 changed files with 95 additions and 39 deletions
32
dist/habitrpg-shared.js
vendored
32
dist/habitrpg-shared.js
vendored
|
|
@ -14308,14 +14308,20 @@ api.startOfWeek = api.startOfWeek = function(options) {
|
|||
};
|
||||
|
||||
api.startOfDay = function(options) {
|
||||
var o;
|
||||
var dayStart, o;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
o = sanitizeOptions(options);
|
||||
return moment(o.now).startOf('day').add({
|
||||
dayStart = moment(o.now).startOf('day').add({
|
||||
hours: o.dayStart
|
||||
});
|
||||
if (moment(o.now).hour() < o.dayStart) {
|
||||
dayStart.subtract({
|
||||
days: 1
|
||||
});
|
||||
}
|
||||
return dayStart;
|
||||
};
|
||||
|
||||
api.dayMapping = {
|
||||
|
|
@ -14341,7 +14347,9 @@ api.daysSince = function(yesterday, options) {
|
|||
o = sanitizeOptions(options);
|
||||
return Math.abs(api.startOfDay(_.defaults({
|
||||
now: yesterday
|
||||
}, o)).diff(o.now, 'days'));
|
||||
}, o)).diff(api.startOfDay(_.defaults({
|
||||
now: o.now
|
||||
}, o)), 'days'));
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -14350,7 +14358,7 @@ api.daysSince = function(yesterday, options) {
|
|||
*/
|
||||
|
||||
api.shouldDo = function(day, repeat, options) {
|
||||
var o, selected, yesterday;
|
||||
var o, selected;
|
||||
if (options == null) {
|
||||
options = {};
|
||||
}
|
||||
|
|
@ -14361,17 +14369,7 @@ api.shouldDo = function(day, repeat, options) {
|
|||
selected = repeat[api.dayMapping[api.startOfDay(_.defaults({
|
||||
now: day
|
||||
}, o)).day()]];
|
||||
if (!moment(day).zone(o.timezoneOffset).isSame(o.now, 'd')) {
|
||||
return selected;
|
||||
}
|
||||
if (options.dayStart <= o.now.hour()) {
|
||||
return selected;
|
||||
} else {
|
||||
yesterday = moment(o.now).subtract({
|
||||
days: 1
|
||||
}).day();
|
||||
return repeat[api.dayMapping[yesterday]];
|
||||
}
|
||||
return selected;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -16570,5 +16568,5 @@ api.wrap = function(user, main) {
|
|||
};
|
||||
|
||||
|
||||
}).call(this,require("/Users/lefnire/Google Drive/Sync/Sites/habitrpg/modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
|
||||
},{"./content.coffee":5,"./i18n.coffee":6,"/Users/lefnire/Google Drive/Sync/Sites/habitrpg/modules/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":2,"lodash":3,"moment":4}]},{},[1])
|
||||
}).call(this,require("/home/matteo/Dev/habitrpg/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js"))
|
||||
},{"./content.coffee":5,"./i18n.coffee":6,"/home/matteo/Dev/habitrpg/habitrpg-shared/node_modules/browserify/node_modules/insert-module-globals/node_modules/process/browser.js":2,"lodash":3,"moment":4}]},{},[1])
|
||||
|
|
@ -57,7 +57,10 @@ api.startOfWeek = api.startOfWeek = (options={}) ->
|
|||
|
||||
api.startOfDay = (options={}) ->
|
||||
o = sanitizeOptions(options)
|
||||
moment(o.now).startOf('day').add({hours:o.dayStart})
|
||||
dayStart = moment(o.now).startOf('day').add({hours:o.dayStart})
|
||||
if moment(o.now).hour() < o.dayStart
|
||||
dayStart.subtract({days:1})
|
||||
dayStart
|
||||
|
||||
api.dayMapping = {0:'su',1:'m',2:'t',3:'w',4:'th',5:'f',6:'s'}
|
||||
|
||||
|
|
@ -66,7 +69,7 @@ api.dayMapping = {0:'su',1:'m',2:'t',3:'w',4:'th',5:'f',6:'s'}
|
|||
###
|
||||
api.daysSince = (yesterday, options = {}) ->
|
||||
o = sanitizeOptions options
|
||||
Math.abs api.startOfDay(_.defaults {now:yesterday}, o).diff(o.now, 'days')
|
||||
Math.abs api.startOfDay(_.defaults {now:yesterday}, o).diff(api.startOfDay(_.defaults {now:o.now}, o), 'days')
|
||||
|
||||
###
|
||||
Should the user do this taks on this date, given the task's repeat options and user.preferences.dayStart?
|
||||
|
|
@ -75,12 +78,7 @@ api.shouldDo = (day, repeat, options={}) ->
|
|||
return false unless repeat
|
||||
o = sanitizeOptions options
|
||||
selected = repeat[api.dayMapping[api.startOfDay(_.defaults {now:day}, o).day()]]
|
||||
return selected unless moment(day).zone(o.timezoneOffset).isSame(o.now,'d')
|
||||
if options.dayStart <= o.now.hour() # we're past the dayStart mark, is it due today?
|
||||
return selected
|
||||
else # we're not past dayStart mark, check if it was due "yesterday"
|
||||
yesterday = moment(o.now).subtract({days:1}).day() # have to wrap o.now so as not to modify original
|
||||
return repeat[api.dayMapping[yesterday]] # FIXME is this correct?? Do I need to do any timezone calcaulation here?
|
||||
return selected
|
||||
|
||||
###
|
||||
------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -56,6 +56,9 @@ expectStrings = (obj, paths) ->
|
|||
_.each paths, (path) -> expect(obj[path]).to.be.ok()
|
||||
|
||||
# options.daysAgo: days ago when the last cron was executed
|
||||
# cronAfterStart: moves the lastCron to be after the dayStart.
|
||||
# This way the daysAgo works as expected if the test case
|
||||
# makes the assumption that the lastCron was after dayStart.
|
||||
beforeAfter = (options={}) ->
|
||||
user = newUser()
|
||||
[before, after] = [user, _.cloneDeep(user)]
|
||||
|
|
@ -66,7 +69,9 @@ beforeAfter = (options={}) ->
|
|||
if options.limitOne
|
||||
before["#{options.limitOne}s"] = [before["#{options.limitOne}s"][0]]
|
||||
after["#{options.limitOne}s"] = [after["#{options.limitOne}s"][0]]
|
||||
lastCron = +(moment(options.now || +new Date).subtract(options.daysAgo, 'days')) if options.daysAgo
|
||||
lastCron = moment(options.now || +new Date).subtract( {days:options.daysAgo} ) if options.daysAgo
|
||||
lastCron.add( {hours:options.dayStart, minutes:1} ) if options.daysAgo and options.cronAfterStart
|
||||
lastCron = +lastCron if options.daysAgo
|
||||
_.each [before,after], (obj) ->
|
||||
obj.lastCron = lastCron if options.daysAgo
|
||||
{before:before, after:after}
|
||||
|
|
@ -517,6 +522,59 @@ describe 'Cron', ->
|
|||
expect(after.todos[0].value).to.be.lessThan before.todos[0].value
|
||||
expect(after.history.todos).to.have.length 1
|
||||
|
||||
# I used hard-coded dates here instead of 'now' so the tests don't fail
|
||||
# when you run them between midnight and dayStart. Nothing worse than
|
||||
# intermittent failures.
|
||||
describe 'cron day calculations', ->
|
||||
dayStart = 4
|
||||
fstr = "YYYY-MM-DD HH:mm:ss"
|
||||
|
||||
it 'startOfDay before dayStart', ->
|
||||
# If the time is before dayStart, then we expect the start of the day to be yesterday at dayStart
|
||||
start = shared.startOfDay {now: moment('2014-10-09 02:30:00'), dayStart}
|
||||
expect(start.format(fstr)).to.eql '2014-10-08 04:00:00'
|
||||
|
||||
it 'startOfDay after dayStart', ->
|
||||
# If the time is after dayStart, then we expect the start of the day to be today at dayStart
|
||||
start = shared.startOfDay {now: moment('2014-10-09 05:30:00'), dayStart}
|
||||
expect(start.format(fstr)).to.eql '2014-10-09 04:00:00'
|
||||
|
||||
it 'daysSince cron before, now after', ->
|
||||
# If the lastCron was before dayStart, then a time on the same day after dayStart
|
||||
# should be 1 day later than lastCron
|
||||
lastCron = moment('2014-10-09 02:30:00')
|
||||
days = shared.daysSince(lastCron, {now: moment('2014-10-09 11:30:00'), dayStart})
|
||||
expect(days).to.eql 1
|
||||
|
||||
it 'daysSince cron before, now before', ->
|
||||
# If the lastCron was before dayStart, then a time on the same day also before dayStart
|
||||
# should be 0 days later than lastCron
|
||||
lastCron = moment('2014-10-09 02:30:00')
|
||||
days = shared.daysSince(lastCron, {now: moment('2014-10-09 03:30:00'), dayStart})
|
||||
expect(days).to.eql 0
|
||||
|
||||
it 'daysSince cron after, now after', ->
|
||||
# If the lastCron was after dayStart, then a time on the same day also after dayStart
|
||||
# should be 0 days later than lastCron
|
||||
lastCron = moment('2014-10-09 05:30:00')
|
||||
days = shared.daysSince(lastCron, {now: moment('2014-10-09 06:30:00'), dayStart})
|
||||
expect(days).to.eql 0
|
||||
|
||||
it 'daysSince cron after, now tomorrow before', ->
|
||||
# If the lastCron was after dayStart, then a time on the following day but before dayStart
|
||||
# should be 0 days later than lastCron
|
||||
lastCron = moment('2014-10-09 12:30:00')
|
||||
days = shared.daysSince(lastCron, {now: moment('2014-10-10 01:30:00'), dayStart})
|
||||
expect(days).to.eql 0
|
||||
|
||||
it 'daysSince cron after, now tomorrow after', ->
|
||||
# If the lastCron was after dayStart, then a time on the following day and after dayStart
|
||||
# should be 1 day later than lastCron
|
||||
lastCron = moment('2014-10-09 12:30:00')
|
||||
days = shared.daysSince(lastCron, {now: moment('2014-10-10 10:30:00'), dayStart})
|
||||
expect(days).to.eql 1
|
||||
|
||||
|
||||
describe 'dailies', ->
|
||||
|
||||
describe 'new day', ->
|
||||
|
|
@ -530,7 +588,7 @@ describe 'Cron', ->
|
|||
runCron = (options) ->
|
||||
_.each [480, 240, 0, -120], (timezoneOffset) -> # test different timezones
|
||||
now = shared.startOfWeek({timezoneOffset}).add(options.currentHour||0, 'hours')
|
||||
{before,after} = beforeAfter({now, timezoneOffset, daysAgo:1, dayStart:options.dayStart||0, limitOne:'daily'})
|
||||
{before,after} = beforeAfter({now, timezoneOffset, daysAgo:1, cronAfterStart:options.cronAfterStart||true, dayStart:options.dayStart||0, limitOne:'daily'})
|
||||
before.dailys[0].repeat = after.dailys[0].repeat = options.repeat if options.repeat
|
||||
before.dailys[0].streak = after.dailys[0].streak = 10
|
||||
before.dailys[0].completed = after.dailys[0].completed = true if options.checked
|
||||
|
|
@ -544,11 +602,14 @@ describe 'Cron', ->
|
|||
when 'noDamage' then expectDayResetNoDamage(before,after)
|
||||
{before,after}
|
||||
|
||||
# These test cases were written assuming that lastCron was run after dayStart
|
||||
# even if currentHour < dayStart and lastCron = yesterday at currentHour.
|
||||
# cronAfterStart makes sure that lastCron is moved to be after dayStart.
|
||||
cronMatrix =
|
||||
steps:
|
||||
|
||||
'due yesterday':
|
||||
defaults: {daysAgo:1, limitOne: 'daily'}
|
||||
defaults: {daysAgo:1, cronAfterStart:true, limitOne: 'daily'}
|
||||
steps:
|
||||
|
||||
'(simple)': {expect:'losePoints'}
|
||||
|
|
@ -599,15 +660,8 @@ describe 'Cron', ->
|
|||
it "#{options.text}", -> runCron(_.defaults(obj,options))
|
||||
recurseCronMatrix(cronMatrix)
|
||||
|
||||
it 'calculates day differences with dayStart properly', ->
|
||||
dayStart = 4
|
||||
yesterday = shared.startOfDay {now: moment().subtract(1, 'd'), dayStart}
|
||||
now = shared.startOfDay {dayStart: dayStart-1}
|
||||
expect(shared.daysSince(yesterday, {now, dayStart})).to.eql 0
|
||||
now = moment().startOf('day').add(dayStart, 'h').add(1, 'm')
|
||||
expect(shared.daysSince(yesterday, {now, dayStart})).to.eql 1
|
||||
|
||||
describe 'Helper', ->
|
||||
|
||||
it 'calculates gold coins', ->
|
||||
expect(shared.gold(10)).to.eql 10
|
||||
expect(shared.gold(1.957)).to.eql 1
|
||||
|
|
@ -626,9 +680,15 @@ describe 'Helper', ->
|
|||
expect(shared.tnl 99).to.eql 3580
|
||||
|
||||
it 'calculates the start of the day', ->
|
||||
expect(shared.startOfDay({now: new Date(2013, 0, 1, 0)}).format('YYYY-MM-DD HH:mm')).to.eql '2013-01-01 00:00'
|
||||
expect(shared.startOfDay({now: new Date(2013, 0, 1, 5)}).format('YYYY-MM-DD HH:mm')).to.eql '2013-01-01 00:00'
|
||||
expect(shared.startOfDay({now: new Date(2013, 0, 1, 23, 59, 59)}).format('YYYY-MM-DD HH:mm')).to.eql '2013-01-01 00:00'
|
||||
fstr = 'YYYY-MM-DD HH:mm:ss'
|
||||
today = '2013-01-01 00:00:00'
|
||||
# get the timezone for the day, so the test case doesn't fail
|
||||
# if you run it during daylight savings time because by default
|
||||
# it uses moment().zone() which is the current minute offset
|
||||
zone = moment(today).zone()
|
||||
expect(shared.startOfDay({now: new Date(2013, 0, 1, 0)}, timezoneOffset:zone).format(fstr)).to.eql today
|
||||
expect(shared.startOfDay({now: new Date(2013, 0, 1, 5)}, timezoneOffset:zone).format(fstr)).to.eql today
|
||||
expect(shared.startOfDay({now: new Date(2013, 0, 1, 23, 59, 59), timezoneOffset:zone}).format(fstr)).to.eql today
|
||||
|
||||
it 'counts pets', ->
|
||||
pets = {}
|
||||
|
|
|
|||
Loading…
Reference in a new issue