mirror of
https://github.com/sudoxnym/habitica.git
synced 2026-08-04 09:39:23 +00:00
Merge branch 'develop' of github.com:lefnire/habitrpg into api
This commit is contained in:
commit
905e728c70
9 changed files with 142 additions and 170 deletions
|
|
@ -57,9 +57,6 @@ module.exports.app = (appExports, model) ->
|
|||
batch.commit()
|
||||
browser.resetDom(model)
|
||||
|
||||
appExports.closeKickstarterNofitication = (e, el) ->
|
||||
user.set('flags.kickstarter', 'hide')
|
||||
|
||||
appExports.closeCelebrationNofitication = (e, el) ->
|
||||
user.set('flags.celebrationEvent', 'hide')
|
||||
|
||||
|
|
@ -107,7 +104,6 @@ userSchema =
|
|||
flags:
|
||||
partyEnabled: false
|
||||
itemsEnabled: false
|
||||
kickstarter: 'show'
|
||||
# ads: 'show' # added on registration
|
||||
|
||||
module.exports.newUserObject = ->
|
||||
|
|
|
|||
|
|
@ -12,13 +12,10 @@ partyUnsubscribe = (model, cb) ->
|
|||
cb()
|
||||
|
||||
###
|
||||
Subscribe to the user, the users's party (meta), and the party's members. 3 subscriptions.
|
||||
If the user is solo, just subscribe to the user. If in a an empty party, just subscribe to the party. If full party,
|
||||
subscribe to everything.
|
||||
|
||||
Note a strange hack - later model.queries override previous model.queries'
|
||||
returned fields. Aka, we need this here otherwise we only get the "public" fields for the current user, which
|
||||
are defined in model.query('users').party(). So we need to subscribe to the main user last
|
||||
Subscribe to the user, the users's party (meta info like party name, member ids, etc), and the party's members. 3 subscriptions.
|
||||
1) If the user is solo, just subscribe to the user.
|
||||
2) If in a an empty party, just subscribe to the user & party meta.
|
||||
3) If full party, subscribe to everything.
|
||||
###
|
||||
module.exports.partySubscribe = partySubscribe = (model, cb) ->
|
||||
|
||||
|
|
@ -32,23 +29,30 @@ module.exports.partySubscribe = partySubscribe = (model, cb) ->
|
|||
u = self.at(0)
|
||||
uObj = u.get()
|
||||
|
||||
finished = ->
|
||||
model.unsubscribe selfQ, ->
|
||||
selfQ.subscribe (err, self) ->
|
||||
model.ref '_user', self.at(0)
|
||||
browser.resetDom(model) if window?
|
||||
cb() if cb?
|
||||
|
||||
## (1) User is solo, just return that subscription
|
||||
unless uObj.party?.current
|
||||
unless uObj.party?.current?
|
||||
model.ref '_user', u
|
||||
browser.resetDom(model) if window?
|
||||
return if cb then cb() else null
|
||||
return cb()
|
||||
|
||||
###
|
||||
Note this strange hack - we subscribe to queries incrementally. First self, then party, then party members.
|
||||
Party members come with limited fields, so you can't hack their stuff. Strangely, subscribing to the members after
|
||||
already subscribing to self limits self's fields to the fields which members are limited to. As a result, we have
|
||||
to re-subscribe to self to get all the fields (otherwise everything breaks). Weirdly, this last subscription doesn't
|
||||
do the opposite - granting all the fields back to members. I dont' know what's going on here
|
||||
|
||||
Another issue: `model.unsubscribe(selfQ)` would seem to mitigate the above, so we at least don't have a stray
|
||||
subscription floating around - but alas, it doesn't seem to work (or at least never calls the callback)
|
||||
###
|
||||
finished = ->
|
||||
# model.unsubscribe selfQ, ->
|
||||
selfQ.subscribe (err, self) ->
|
||||
model.ref '_user', self.at(0)
|
||||
cb()
|
||||
|
||||
# User in a party
|
||||
partiesQ = model.query('parties').withId(uObj.party.current)
|
||||
partiesQ.subscribe (err, res) ->
|
||||
partiesQ.fetch (err, res) ->
|
||||
throw err if err
|
||||
p = res.at(0)
|
||||
model.ref '_party', p
|
||||
|
|
@ -68,7 +72,7 @@ module.exports.partySubscribe = partySubscribe = (model, cb) ->
|
|||
else
|
||||
## (3) Party has members, subscribe to those users too
|
||||
membersQ = model.query('users').party(ids)
|
||||
membersQ.subscribe (err, members) ->
|
||||
membersQ.fetch (err, members) ->
|
||||
throw err if err
|
||||
model.ref '_partyMembers', members
|
||||
finished()
|
||||
|
|
@ -99,8 +103,9 @@ module.exports.app = (appExports, model) ->
|
|||
appExports.partyCreate = ->
|
||||
newParty = model.get("_newParty")
|
||||
id = model.add 'parties', { name: newParty, leader: user.get('id'), members: [user.get('id')], invites:[] }
|
||||
user.set 'party', {current: id, invitation: null, leader: true}
|
||||
partySubscribe model, -> $('#party-modal').modal('show')
|
||||
user.set 'party', {current: id, invitation: null, leader: true}, ->
|
||||
window.location.reload true
|
||||
# partySubscribe model, -> $('#party-modal').modal('show')
|
||||
|
||||
appExports.partyInvite = ->
|
||||
id = model.get('_newPartyMember').replace(/[\s"]/g, '')
|
||||
|
|
@ -123,18 +128,22 @@ module.exports.app = (appExports, model) ->
|
|||
model.set "users.#{id}.party.invitation", p.get('id')
|
||||
$.bootstrapGrowl "Invitation Sent."
|
||||
$('#party-modal').modal('hide')
|
||||
model.set '_newPartyMember', ''
|
||||
partySubscribe model
|
||||
model.set '_newPartyMember', '', -> window.location.reload true
|
||||
#partySubscribe model
|
||||
|
||||
appExports.partyAccept = ->
|
||||
user.set 'party.current', user.get('party.invitation')
|
||||
partyId = user.get('party.invitation')
|
||||
user.set 'party.invitation', null
|
||||
setTimeout (-> window.location.reload true), 10
|
||||
return
|
||||
# FIXME This should handle not requiring a refresh, but alas.
|
||||
partySubscribe model, ->
|
||||
p = model.at('_party')
|
||||
p.push 'members', user.get('id')
|
||||
user.set 'party.current', partyId
|
||||
# model.push "parties.#{partyId}.members", user.get('id'), -> #FIXME why this not working?
|
||||
model.query('parties').withId(partyId).fetch (err, p) ->
|
||||
members = p.at(0).get('members')
|
||||
members.push user.get('id')
|
||||
p.at(0).set 'members', members, ->
|
||||
window.location.reload true
|
||||
# partySubscribe model, ->
|
||||
# p = model.at('_party')
|
||||
# p.push 'members', user.get('id')
|
||||
|
||||
appExports.partyReject = ->
|
||||
user.set 'party.invitation', null
|
||||
|
|
@ -148,21 +157,16 @@ module.exports.app = (appExports, model) ->
|
|||
members = p.get('members')
|
||||
index = members.indexOf(user.get('id'))
|
||||
members.splice(index,1)
|
||||
p.set 'members', members
|
||||
if (members.length == 0)
|
||||
# last member out, kill the party
|
||||
model.del "parties.#{id}"
|
||||
model.set '_party', null
|
||||
model.set '_partyMembers', null
|
||||
setTimeout (-> window.location.reload true), 10
|
||||
return
|
||||
|
||||
# FIXME This should handle not requiring a refresh, but alas.
|
||||
partyUnsubscribe model, ->
|
||||
selfQ = model.query('users').withId(model.get('_userId') or model.session.userId)
|
||||
selfQ.subscribe (err, u) ->
|
||||
model.ref '_user', u.at(0)
|
||||
browser.resetDom model
|
||||
|
||||
|
||||
#exports.partyDisband = ->
|
||||
p.set 'members', members, ->
|
||||
if (members.length == 0)
|
||||
# last member out, kill the party
|
||||
model.del "parties.#{id}", -> window.location.reload true
|
||||
else
|
||||
window.location.reload true
|
||||
# model.set '_party', null
|
||||
# model.set '_partyMembers', null
|
||||
# partyUnsubscribe model, ->
|
||||
# selfQ = model.query('users').withId(model.get('_userId') or model.session.userId)
|
||||
# selfQ.subscribe (err, u) ->
|
||||
# model.ref '_user', u.at(0)
|
||||
# browser.resetDom model
|
||||
|
|
@ -3,16 +3,17 @@ path = require 'path'
|
|||
express = require 'express'
|
||||
gzippo = require 'gzippo'
|
||||
derby = require 'derby'
|
||||
racer = require 'racer'
|
||||
auth = require 'derby-auth'
|
||||
app = require '../app'
|
||||
serverError = require './serverError'
|
||||
MongoStore = require('connect-mongo')(express)
|
||||
auth = require 'derby-auth'
|
||||
priv = require './private'
|
||||
habitrpgStore = require('./store')
|
||||
habitrpgStore = require './store'
|
||||
middleware = require './middleware'
|
||||
|
||||
## RACER CONFIGURATION ##
|
||||
|
||||
racer = require 'racer'
|
||||
racer.io.set('transports', ['xhr-polling'])
|
||||
racer.ioClient.set('reconnection limit', 300000) # max reconect timeout to 5 minutes
|
||||
racer.set('bundleTimeout', 40000)
|
||||
|
|
@ -26,7 +27,7 @@ expressApp = express()
|
|||
server = http.createServer expressApp
|
||||
module.exports = server
|
||||
|
||||
derby.use(require 'racer-db-mongo')
|
||||
derby.use require('racer-db-mongo')
|
||||
store = derby.createStore
|
||||
db: {type: 'Mongo', uri: process.env.NODE_DB_URI, safe:true}
|
||||
listen: server
|
||||
|
|
@ -53,57 +54,27 @@ auth.store(store, habitrpgStore.customAccessControl)
|
|||
|
||||
mongo_store = new MongoStore {url: process.env.NODE_DB_URI}, ->
|
||||
expressApp
|
||||
#.use (req, res, next) ->
|
||||
# if toobusy()
|
||||
# return res.redirect 307, '/500.html'
|
||||
# else
|
||||
# next()
|
||||
|
||||
.use(express.favicon())
|
||||
.use(express.favicon("#{publicPath}/favicon.ico"))
|
||||
# Gzip static files and serve from memory
|
||||
.use(gzippo.staticGzip publicPath, maxAge: ONE_YEAR)
|
||||
.use(gzippo.staticGzip(publicPath, maxAge: ONE_YEAR))
|
||||
# Gzip dynamically rendered content
|
||||
.use(express.compress())
|
||||
|
||||
# Uncomment to add form data parsing support
|
||||
.use(express.bodyParser())
|
||||
.use(express.methodOverride())
|
||||
|
||||
# Uncomment and supply secret to add Derby session handling
|
||||
# Derby session middleware creates req.session and socket.io sessions
|
||||
.use(express.cookieParser())
|
||||
.use(store.sessionMiddleware
|
||||
secret: process.env.SESSION_SECRET || 'YOUR SECRET HERE'
|
||||
cookie: {maxAge: TWO_WEEKS} # defaults to 2 weeks? aka, can delete this line?
|
||||
cookie: { maxAge: TWO_WEEKS } # defaults to 2 weeks? aka, can delete this line?
|
||||
store: mongo_store
|
||||
)
|
||||
|
||||
#show splash page for newcomers
|
||||
.use (req, res, next) ->
|
||||
# This was an API call, not a page load
|
||||
return next() if req.is('json')
|
||||
|
||||
if !req.session.userId? and !req.query?.play? and req.url == '/'
|
||||
return res.redirect('/splash.html')
|
||||
else
|
||||
next()
|
||||
|
||||
# Show splash page for newcomers
|
||||
.use(middleware.splash)
|
||||
# Adds req.getModel method
|
||||
.use(store.modelMiddleware())
|
||||
# Middelware can be inserted after the modelMiddleware and before
|
||||
# the app router to pass server accessible data to a model
|
||||
.use(priv.middleware)
|
||||
|
||||
# HabitRPG Custom Middleware
|
||||
.use (req, res, next) ->
|
||||
model = req.getModel()
|
||||
_view = model.get('_view') || {}
|
||||
## Set _mobileDevice to true or false so view can exclude portions from mobile device
|
||||
_view.mobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(req.header 'User-Agent')
|
||||
_view.nodeEnv = process.env.NODE_ENV
|
||||
model.set '_view', _view
|
||||
next()
|
||||
|
||||
.use(middleware.view)
|
||||
.use(auth.middleware(strategies, options))
|
||||
# Creates an express middleware from the app's routes
|
||||
.use(app.router())
|
||||
|
|
@ -111,10 +82,10 @@ mongo_store = new MongoStore {url: process.env.NODE_DB_URI}, ->
|
|||
.use(require('./static').middleware)
|
||||
.use(require('./deprecated').middleware)
|
||||
.use(expressApp.router)
|
||||
.use(serverError root)
|
||||
.use(serverError(root))
|
||||
|
||||
priv.routes(expressApp)
|
||||
|
||||
# Errors
|
||||
expressApp.all '*', (req) ->
|
||||
throw "404: #{req.url}"
|
||||
throw "404: #{req.url}"
|
||||
|
|
|
|||
17
src/server/middleware.coffee
Normal file
17
src/server/middleware.coffee
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
module.exports.splash = (req, res, next) ->
|
||||
# This was an API call, not a page load
|
||||
return next() if req.is('json')
|
||||
|
||||
if !req.session.userId? and !req.query?.play?
|
||||
res.redirect('/splash.html')
|
||||
else
|
||||
next()
|
||||
|
||||
module.exports.view = (req, res, next) ->
|
||||
model = req.getModel()
|
||||
_view = model.get('_view') || {}
|
||||
## Set _mobileDevice to true or false so view can exclude portions from mobile device
|
||||
_view.mobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(req.header 'User-Agent')
|
||||
_view.nodeEnv = process.env.NODE_ENV
|
||||
model.set '_view', _view
|
||||
next()
|
||||
|
|
@ -8,7 +8,7 @@ casper.start url
|
|||
# ---------- Daily ------------
|
||||
casper.then ->
|
||||
helpers.reset()
|
||||
helpers.addTasks()
|
||||
helpers.addTasks(['daily'])
|
||||
|
||||
# Gained exp on +daily
|
||||
casper.then ->
|
||||
|
|
@ -27,15 +27,18 @@ casper.then ->
|
|||
# ---------- Cron ------------
|
||||
casper.then ->
|
||||
helpers.reset()
|
||||
helpers.addTasks()
|
||||
helpers.addTasks(['daily'])
|
||||
|
||||
casper.then ->
|
||||
helpers.cronBeforeAfter (model) ->
|
||||
casper.then ->
|
||||
#TODO make sure true for all dailies
|
||||
dailyId = model.before._user.dailyIds[0]
|
||||
casper.test.assert model.before._user.tasks[dailyId].value < model.after._user.tasks[dailyId].value, "daily:cron:daily gained value"
|
||||
casper.test.assert model.before._user.stats.hp < model.after._user.stats.hp, 'daily:cron:hp lost value'
|
||||
casper.test.assert model.before._user.stats.hp > model.after._user.stats.hp, 'daily:cron:hp lost value'
|
||||
|
||||
# Go through all the dailys, all of them are uncompleted, so should all get a negative value
|
||||
casper.echo "Testing all uncompleted dailys after cron"
|
||||
for id in model.before._user.dailyIds
|
||||
casper.test.assertEquals model.before._user.tasks[id].value, 0, "daily:cron:daily value before was 0"
|
||||
casper.test.assert model.after._user.tasks[id].value < 0, "daily:cron:daily value after is negative"
|
||||
|
||||
# ---------- Run ------------
|
||||
casper.run ->
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ utils = require('utils')
|
|||
|
||||
module.exports = ->
|
||||
|
||||
SYNC_WAIT_TIME = 20
|
||||
SYNC_WAIT_TIME = 40
|
||||
|
||||
baseUrl = 'http://localhost:3000'
|
||||
|
||||
|
|
@ -31,12 +31,13 @@ module.exports = ->
|
|||
|
||||
utils: utils
|
||||
|
||||
addTasks: ->
|
||||
['habit', 'daily', 'todo', 'reward'].forEach (type) ->
|
||||
# Add 15 of each task type
|
||||
num = 0
|
||||
casper.repeat 5, ->
|
||||
casper.fill "form#new-#{type}", {'new-task': "#{type}-#{num}"} # why can't I use true here?
|
||||
addTasks: (types = 'all', num = 5)->
|
||||
if types == 'all'
|
||||
types = ['habit', 'daily', 'todo', 'reward']
|
||||
types.forEach (type) ->
|
||||
i = 0
|
||||
casper.repeat num, ->
|
||||
casper.fill "form#new-#{type}", {'new-task': "#{type}-#{i}"} # why can't I use true here?
|
||||
casper.click "form#new-#{type} input[type=submit]"
|
||||
|
||||
reset: ->
|
||||
|
|
@ -58,7 +59,10 @@ module.exports = ->
|
|||
casper.then -> done_cb(model)
|
||||
|
||||
runCron: ->
|
||||
casper.evaluate -> window.DERBY.model.set('_user.lastCron', new Date('01/25/2013'))
|
||||
casper.evaluate ->
|
||||
yesterday = new Date()
|
||||
yesterday.setDate(yesterday.getDate() - 1);
|
||||
window.DERBY.app.model.set('_user.lastCron', yesterday)
|
||||
casper.then -> casper.reload()
|
||||
|
||||
cronBeforeAfter: (cb) ->
|
||||
|
|
@ -68,14 +72,13 @@ module.exports = ->
|
|||
model.before = before
|
||||
casper.then -> that.runCron()
|
||||
casper.then ->
|
||||
casper.wait 1050, -> # user's hp is updated after 1s for animation
|
||||
casper.wait 1100, -> # user's hp is updated after 1s for animation
|
||||
model.after = getModel()
|
||||
casper.then ->
|
||||
casper.test.assertEqual model.before._user.id, model.after._user.id, 'user id equal after cron'
|
||||
casper.test.assertEqual model.before._user.tasks.length, model.after._user.tasks.length, "Didn't lose anything on cron"
|
||||
cb(model)
|
||||
|
||||
|
||||
register: ->
|
||||
casper.fill 'form#derby-auth-register',
|
||||
username: random
|
||||
|
|
@ -90,13 +93,10 @@ module.exports = ->
|
|||
password: random
|
||||
, true
|
||||
|
||||
|
||||
deleteOne: (type) ->
|
||||
listType = if type == 'completed' then 'todo' else type
|
||||
selector = ".#{type}s a[data-original-title=\"Delete\"]"
|
||||
deleteOne: (list, typeSelector) ->
|
||||
selector = "#{typeSelector} a[data-original-title=\"Delete\"]"
|
||||
@modelBeforeAfter (-> casper.click selector), (model) ->
|
||||
# utils.dump model
|
||||
casper.test.assertEquals Object.keys(model.before._user.tasks).length - 1, Object.keys(model.after._user.tasks).length, "1 #{type} deleted from user.tasks"
|
||||
casper.test.assertEquals model.before._user["#{listType}Ids"].length - 1, model.after._user["#{listType}Ids"].length, "1 #{type} deleted from user._typeIds"
|
||||
casper.test.assertEquals model.before["_#{listType}List"].length - 1, model.after["_#{listType}List"].length, "1 #{type} deleted from _typeList"
|
||||
casper.test.assertEquals Object.keys(model.before._user.tasks).length - 1, Object.keys(model.after._user.tasks).length, "1 #{typeSelector} deleted from user.tasks"
|
||||
casper.test.assertEquals model.before._user["#{list}Ids"].length - 1, model.after._user["#{list}Ids"].length, "1 #{typeSelector} deleted from user._typeIds"
|
||||
casper.test.assertEquals model.before["_#{list}List"].length - 1, model.after["_#{list}List"].length, "1 #{typeSelector} deleted from _typeList"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +1,57 @@
|
|||
helper = new require('./test/casper/helpers')()
|
||||
casper = helper.casper
|
||||
utils = helper.utils
|
||||
url = helper.url
|
||||
helpers = new require('./test/casper/helpers')()
|
||||
casper = helpers.casper
|
||||
utils = helpers.utils
|
||||
url = helpers.playUrl
|
||||
|
||||
casper.start url + '/?play=1'
|
||||
casper.start url
|
||||
|
||||
# ---------- Todos ------------
|
||||
casper.then ->
|
||||
helper.reset()
|
||||
helper.addTasks()
|
||||
helpers.reset()
|
||||
helpers.addTasks(['todo'])
|
||||
|
||||
# Gained exp on +daily
|
||||
# Completing todo gives exp and gp
|
||||
casper.then ->
|
||||
helper.modelBeforeAfter (-> casper.click '.todos input[type="checkbox"]'), (model) ->
|
||||
helpers.modelBeforeAfter (-> casper.click '.todos .uncompleted input[type="checkbox"]'), (model) ->
|
||||
casper.test.assertEquals model.before._user.stats.hp, 50, 'todo:hp starts at 50'
|
||||
casper.test.assertEquals model.before._user.stats.hp, model.after._user.stats.hp, '+todo =hp'
|
||||
casper.test.assertEquals model.after._user.stats.exp, 1, '+todo exp=1'
|
||||
casper.test.assertEquals model.after._user.stats.money, 1, '+todo gp=1'
|
||||
casper.test.assertEquals model.after._user.stats.gp, 1, '+todo gp=1'
|
||||
|
||||
#FIXME before._user.stats not fully available until modified? Is this a Derby JIT caching mechanism?
|
||||
#casper.test.assert model.before._user.stats.exp < model.after._user.stats.exp, '+todo +exp'
|
||||
#casper.test.assert model.before._user.stats.money < model.after._user.stats.money, '+todo +money'
|
||||
casper.test.assert model.before._user.stats.exp < model.after._user.stats.exp, '+todo +exp'
|
||||
casper.test.assert model.before._user.stats.gp < model.after._user.stats.gp, '+todo +gp'
|
||||
|
||||
# -daily acts as undo
|
||||
# Can delete completed
|
||||
casper.then -> helpers.deleteOne('todo', '.todos .completed')
|
||||
|
||||
# Can delete uncompleted
|
||||
casper.then -> helpers.deleteOne('todo', '.todos .uncompleted')
|
||||
|
||||
# Uncompleting subtracts exp and gp
|
||||
casper.then ->
|
||||
helper.modelBeforeAfter (-> casper.click '.completeds input[type="checkbox"]'), (model) ->
|
||||
casper.click '.todos .uncompleted input[type="checkbox"]'
|
||||
helpers.modelBeforeAfter (-> casper.click '.todos .completed input[type="checkbox"]'), (model) ->
|
||||
casper.test.assertEquals model.before._user.stats.hp, model.after._user.stats.hp, '-todo =hp'
|
||||
casper.test.assert model.before._user.stats.exp > model.after._user.stats.exp, '-todo -exp'
|
||||
casper.test.assert model.before._user.stats.money > model.after._user.stats.money, '-todo -money'
|
||||
utils.dump {before:model.before._user.stats, after:model.after._user.stats}
|
||||
casper.test.assert model.before._user.stats.gp > model.after._user.stats.gp, '-todo -gp'
|
||||
|
||||
casper.then -> helper.deleteOne('todo')
|
||||
casper.then -> helper.deleteOne('completed')
|
||||
|
||||
|
||||
# ---------- Cron ------------
|
||||
casper.then ->
|
||||
helper.reset()
|
||||
helper.addTasks()
|
||||
helpers.reset()
|
||||
helpers.addTasks(['todo'])
|
||||
|
||||
casper.then ->
|
||||
helper.cronBeforeAfter (beforeAfter) ->
|
||||
helpers.cronBeforeAfter (model) ->
|
||||
casper.then ->
|
||||
#TODO make sure true for all todos
|
||||
todoId = beforeAfter.before.tasks.todo[0].id
|
||||
# utils.dump
|
||||
# dailyBefore:user.before.tasks[dailyId].value
|
||||
# dailyAfter:user.before.tasks[dailyId].value
|
||||
casper.test.assert beforeAfter.before.user.tasks[todoId].value < beforeAfter.after.user.tasks[todoId].value, "todo:cron:todo gained value"
|
||||
casper.test.assertEqual beforeAfter.before.user.stats.hp, beforeAfter.after.user.stats.hp, 'todo:cron:hp no change'
|
||||
casper.test.assertEqual model.before._user.stats.hp, model.after._user.stats.hp, 'todo:cron:hp no change'
|
||||
|
||||
# Go through all the todos, all of them are uncompleted, so should all get a negative value
|
||||
casper.echo "Testing all uncompleted todos after cron"
|
||||
for id in model.before._user.todoIds
|
||||
casper.test.assertEquals model.before._user.tasks[id].value, 0, "todo:cron:todo value before was 0"
|
||||
casper.test.assert model.after._user.tasks[id].value < 0, "todo:cron:todo value after is negative"
|
||||
|
||||
|
||||
# ---------- Run ------------
|
||||
|
|
|
|||
|
|
@ -3,27 +3,4 @@
|
|||
<ul class="alert alert-error">
|
||||
{#each _flash.error as :error}<li>{:error}</li>{/}
|
||||
</ul>
|
||||
{/}
|
||||
|
||||
{#if equal(_user.flags.kickstarter,'show')}
|
||||
<div class='alert alert-success'>
|
||||
<a x-bind="click:closeKickstarterNofitication" class=pull-right>[x]</a>
|
||||
|
||||
<table><tr>
|
||||
<td>
|
||||
Hi everyone, last stretch of the <a target="_blank" href="http://kck.st/XoA3Yg">Kickstarter</a>! Let's get a <a target="_blank" href="http://www.kickstarter.com/projects/lefnire/habitrpg-mobile/posts/403016">ton</a> of new features plus mobile apps. With ~25k registered users, if everyone backs $1 we can do it! Help spread the word:
|
||||
</td>
|
||||
<td>
|
||||
<div class="addthis_toolbox addthis_default_style "
|
||||
addthis:url="https://habitrpg.com"
|
||||
addthis:title="HabitRPG - Gamify Your Life">
|
||||
<a class="addthis_button_facebook"></a>
|
||||
<a class="addthis_button_twitter" tw:via="habitrpg"></a>
|
||||
<a class="addthis_button_compact"></a>
|
||||
<script type="text/javascript">var addthis_config = {"data_track_addressbar":true};</script>
|
||||
</div>
|
||||
</td>
|
||||
</tr></table>
|
||||
|
||||
</div>
|
||||
{/}
|
||||
|
|
@ -31,6 +31,7 @@
|
|||
<li><a target="_blank" href="https://trello.com/board/habitrpg/50e5d3684fe3a7266b0036d6">Features</a></li>
|
||||
<li><a target="_blank" href="https://github.com/lefnire/habitrpg/wiki/FAQ">FAQ</a></li>
|
||||
<li><a target="_blank" href="https://github.com/lefnire/habitrpg/wiki/API">API</a></li>
|
||||
<li><a target="_blank" href="https://github.com/lefnire/habitrpg/wiki/Add-ons-and-Extensions">Add-ons / Extensions</a></li>
|
||||
<li><a target="_blank" href="https://github.com/lefnire/habitrpg#contact">Contact</a></li>
|
||||
<li><a href="/privacy">Privacy</a></li>
|
||||
<li><a href="/terms">Terms</a></li>
|
||||
|
|
|
|||
Loading…
Reference in a new issue