mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-03-24 11:50:58 -04:00
Merge branch 'master' into production
This commit is contained in:
commit
472b05a5e0
13 changed files with 174 additions and 149 deletions
|
@ -342,6 +342,7 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
@ended = true
|
@ended = true
|
||||||
@setPaused true
|
@setPaused true
|
||||||
Backbone.Mediator.publish 'surface:playback-ended', {}
|
Backbone.Mediator.publish 'surface:playback-ended', {}
|
||||||
|
@updatePaths() # TODO: this is a hack to make sure paths are on the first time the level loads
|
||||||
else if @currentFrame < @world.totalFrames and @ended
|
else if @currentFrame < @world.totalFrames and @ended
|
||||||
@ended = false
|
@ended = false
|
||||||
@setPaused false
|
@setPaused false
|
||||||
|
@ -586,7 +587,6 @@ module.exports = Surface = class Surface extends CocoClass
|
||||||
|
|
||||||
updatePaths: ->
|
updatePaths: ->
|
||||||
return unless @options.paths and @heroLank
|
return unless @options.paths and @heroLank
|
||||||
return unless me.isAdmin() # TODO: Fix world thang points, targets, then remove this
|
|
||||||
@hidePaths()
|
@hidePaths()
|
||||||
return if @world.showPaths is 'never'
|
return if @world.showPaths is 'never'
|
||||||
layerAdapter = @lankBoss.layerAdapters['Path']
|
layerAdapter = @lankBoss.layerAdapters['Path']
|
||||||
|
|
|
@ -66,7 +66,7 @@
|
||||||
&.disabled
|
&.disabled
|
||||||
@include opacity(0.8)
|
@include opacity(0.8)
|
||||||
.ace_cursor, .executing, .ace_active-line, .ace_gutter-active-line
|
.ace_cursor, .executing, .ace_active-line, .ace_gutter-active-line
|
||||||
@include opacity(0.2)
|
@include opacity(0.1)
|
||||||
|
|
||||||
.ace_gutter
|
.ace_gutter
|
||||||
background-color: transparent
|
background-color: transparent
|
||||||
|
|
|
@ -45,11 +45,15 @@
|
||||||
// color: rgb(197, 6, 11)
|
// color: rgb(197, 6, 11)
|
||||||
color: rgb(243, 169, 49)
|
color: rgb(243, 169, 49)
|
||||||
|
|
||||||
|
|
||||||
|
body:not(.dialogue-view-active)
|
||||||
|
.spell-palette-popover.popover
|
||||||
|
right: 45%
|
||||||
|
min-width: 350px
|
||||||
|
|
||||||
.spell-palette-popover.popover
|
.spell-palette-popover.popover
|
||||||
// Only those popovers which are our direct children (spell documentation)
|
// Only those popovers which are our direct children (spell documentation)
|
||||||
max-width: 600px
|
max-width: 600px
|
||||||
right: 45%
|
|
||||||
min-width: 350px
|
|
||||||
|
|
||||||
&.pinned
|
&.pinned
|
||||||
left: auto !important
|
left: auto !important
|
||||||
|
|
|
@ -378,11 +378,13 @@ module.exports = class InventoryModal extends ModalView
|
||||||
unless itemModel and heroClass in itemModel.classes
|
unless itemModel and heroClass in itemModel.classes
|
||||||
console.log 'Unequipping', itemModel.get('heroClass'), 'item', itemModel.get('name'), 'from slot due to class restrictions.'
|
console.log 'Unequipping', itemModel.get('heroClass'), 'item', itemModel.get('name'), 'from slot due to class restrictions.'
|
||||||
@unequipItemFromSlot @$el.find(".item-slot[data-slot='#{slot}']")
|
@unequipItemFromSlot @$el.find(".item-slot[data-slot='#{slot}']")
|
||||||
|
delete equipment[slot]
|
||||||
for slot, item of restrictedGear
|
for slot, item of restrictedGear
|
||||||
equipped = equipment[slot]
|
equipped = equipment[slot]
|
||||||
if equipped and equipped is gear[restrictedGear[slot]]
|
if equipped and equipped is gear[restrictedGear[slot]]
|
||||||
console.log 'Unequipping restricted item', restrictedGear[slot], 'for', slot, 'before level', @options.levelID
|
console.log 'Unequipping restricted item', restrictedGear[slot], 'for', slot, 'before level', @options.levelID
|
||||||
@unequipItemFromSlot @$el.find(".item-slot[data-slot='#{slot}']")
|
@unequipItemFromSlot @$el.find(".item-slot[data-slot='#{slot}']")
|
||||||
|
delete equipment[slot]
|
||||||
if heroClass is 'Warrior'
|
if heroClass is 'Warrior'
|
||||||
# After they switch to a ranger or wizard, we stop being so finicky about gear.
|
# After they switch to a ranger or wizard, we stop being so finicky about gear.
|
||||||
for slot, item of requiredGear
|
for slot, item of requiredGear
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = class WorldMapView extends RootView
|
||||||
@levelStatusMap = {}
|
@levelStatusMap = {}
|
||||||
@levelPlayCountMap = {}
|
@levelPlayCountMap = {}
|
||||||
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', null, 0).model
|
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(), 'your_sessions', null, 0).model
|
||||||
|
|
||||||
# Temporary attempt to make sure all earned rewards are accounted for. Figure out a better solution...
|
# Temporary attempt to make sure all earned rewards are accounted for. Figure out a better solution...
|
||||||
@earnedAchievements = new CocoCollection([], {url: '/db/earned_achievement', model:EarnedAchievement, project: ['earnedRewards']})
|
@earnedAchievements = new CocoCollection([], {url: '/db/earned_achievement', model:EarnedAchievement, project: ['earnedRewards']})
|
||||||
@listenToOnce @earnedAchievements, 'sync', ->
|
@listenToOnce @earnedAchievements, 'sync', ->
|
||||||
|
@ -56,7 +56,7 @@ module.exports = class WorldMapView extends RootView
|
||||||
earned[group].push(reward)
|
earned[group].push(reward)
|
||||||
addedSomething = true
|
addedSomething = true
|
||||||
@supermodel.loadCollection(@earnedAchievements, 'achievements')
|
@supermodel.loadCollection(@earnedAchievements, 'achievements')
|
||||||
|
|
||||||
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
@listenToOnce @sessions, 'sync', @onSessionsLoaded
|
||||||
@getLevelPlayCounts()
|
@getLevelPlayCounts()
|
||||||
$(window).on 'resize', @onWindowResize
|
$(window).on 'resize', @onWindowResize
|
||||||
|
@ -136,7 +136,7 @@ module.exports = class WorldMapView extends RootView
|
||||||
if levelID = @$el.find('.level.next').data('level-id')
|
if levelID = @$el.find('.level.next').data('level-id')
|
||||||
@$levelInfo = @$el.find(".level-info-container[data-level-id=#{levelID}]").show()
|
@$levelInfo = @$el.find(".level-info-container[data-level-id=#{levelID}]").show()
|
||||||
pos = @$el.find('.level.next').offset()
|
pos = @$el.find('.level.next').offset()
|
||||||
@adjustLevelInfoPosition pageX: pos.left, pageY: pos.top + 250
|
@adjustLevelInfoPosition pageX: pos.left, pageY: pos.top
|
||||||
@manuallyPositionedLevelInfoID = levelID
|
@manuallyPositionedLevelInfoID = levelID
|
||||||
|
|
||||||
afterInsert: ->
|
afterInsert: ->
|
||||||
|
@ -203,6 +203,7 @@ module.exports = class WorldMapView extends RootView
|
||||||
@$levelInfo = @$el.find(".level-info-container[data-level-id=#{levelID}]").show()
|
@$levelInfo = @$el.find(".level-info-container[data-level-id=#{levelID}]").show()
|
||||||
@adjustLevelInfoPosition e
|
@adjustLevelInfoPosition e
|
||||||
@endHighlight()
|
@endHighlight()
|
||||||
|
@manuallyPositionedLevelInfoID = false
|
||||||
|
|
||||||
onMouseLeaveLevel: (e) ->
|
onMouseLeaveLevel: (e) ->
|
||||||
return if application.isIPadApp
|
return if application.isIPadApp
|
||||||
|
|
|
@ -19,13 +19,10 @@ module.exports = class LevelDialogueView extends CocoView
|
||||||
onClick: (e) ->
|
onClick: (e) ->
|
||||||
Backbone.Mediator.publish 'tome:focus-editor', {}
|
Backbone.Mediator.publish 'tome:focus-editor', {}
|
||||||
|
|
||||||
onFrameChanged: (e) ->
|
|
||||||
@timeProgress = e.progress
|
|
||||||
@update()
|
|
||||||
|
|
||||||
onSpriteDialogue: (e) ->
|
onSpriteDialogue: (e) ->
|
||||||
return unless e.message
|
return unless e.message
|
||||||
@$el.addClass 'active speaking'
|
@$el.addClass 'active speaking'
|
||||||
|
$('body').addClass('dialogue-view-active')
|
||||||
@setMessage e.message, e.mood, e.responses
|
@setMessage e.message, e.mood, e.responses
|
||||||
|
|
||||||
window.tracker?.trackEvent 'Heard Sprite', {message: e.message, label: e.message}, ['Google Analytics']
|
window.tracker?.trackEvent 'Heard Sprite', {message: e.message, label: e.message}, ['Google Analytics']
|
||||||
|
@ -35,6 +32,7 @@ module.exports = class LevelDialogueView extends CocoView
|
||||||
|
|
||||||
onSpriteClearDialogue: ->
|
onSpriteClearDialogue: ->
|
||||||
@$el.removeClass 'active speaking'
|
@$el.removeClass 'active speaking'
|
||||||
|
$('body').removeClass('dialogue-view-active')
|
||||||
|
|
||||||
setMessage: (message, mood, responses) ->
|
setMessage: (message, mood, responses) ->
|
||||||
message = marked message
|
message = marked message
|
||||||
|
|
|
@ -56,6 +56,7 @@ module.exports = class LevelHUDView extends CocoView
|
||||||
setThang: (thang, thangType) ->
|
setThang: (thang, thangType) ->
|
||||||
if not thang? and not @thang? then return
|
if not thang? and not @thang? then return
|
||||||
if thang? and @thang? and thang.id is @thang.id then return
|
if thang? and @thang? and thang.id is @thang.id then return
|
||||||
|
if thang? and @hidesHUD and thang.id isnt 'Hero Placeholder' then return # Don't let them find the names of their opponents this way
|
||||||
@thang = thang
|
@thang = thang
|
||||||
@thangType = thangType
|
@thangType = thangType
|
||||||
return unless @thang
|
return unless @thang
|
||||||
|
|
|
@ -37,10 +37,11 @@ module.exports = class SpellPaletteEntryView extends CocoView
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
super()
|
super()
|
||||||
@$el.addClass(@doc.type)
|
@$el.addClass(@doc.type)
|
||||||
|
placement = -> if $('body').hasClass('dialogue-view-active') then 'top' else 'left'
|
||||||
@$el.popover(
|
@$el.popover(
|
||||||
animation: false
|
animation: false
|
||||||
html: true
|
html: true
|
||||||
placement: 'left'
|
placement: placement
|
||||||
trigger: 'manual' # Hover, until they click, which will then pin it until unclick.
|
trigger: 'manual' # Hover, until they click, which will then pin it until unclick.
|
||||||
content: @docFormatter.formatPopover()
|
content: @docFormatter.formatPopover()
|
||||||
container: 'body'
|
container: 'body'
|
||||||
|
|
|
@ -131,13 +131,12 @@ module.exports = class SpellView extends CocoView
|
||||||
addCommand
|
addCommand
|
||||||
name: 'toggle-playing'
|
name: 'toggle-playing'
|
||||||
bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
|
bindKey: {win: 'Ctrl-P', mac: 'Command-P|Ctrl-P'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'level:toggle-playing', {}
|
exec: -> Backbone.Mediator.publish 'level:toggle-playing', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'end-current-script'
|
name: 'end-current-script'
|
||||||
bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
|
bindKey: {win: 'Shift-Space', mac: 'Shift-Space'}
|
||||||
# passEvent: true # https://github.com/ajaxorg/ace/blob/master/lib/ace/keyboard/keybinding.js#L114
|
readOnly: true
|
||||||
# No easy way to selectively cancel shift+space, since we don't get access to the event.
|
|
||||||
# Maybe we could temporarily set ourselves to read-only if we somehow know that a script is active?
|
|
||||||
exec: =>
|
exec: =>
|
||||||
if @scriptRunning
|
if @scriptRunning
|
||||||
Backbone.Mediator.publish 'level:shift-space-pressed', {}
|
Backbone.Mediator.publish 'level:shift-space-pressed', {}
|
||||||
|
@ -147,34 +146,44 @@ module.exports = class SpellView extends CocoView
|
||||||
addCommand
|
addCommand
|
||||||
name: 'end-all-scripts'
|
name: 'end-all-scripts'
|
||||||
bindKey: {win: 'Escape', mac: 'Escape'}
|
bindKey: {win: 'Escape', mac: 'Escape'}
|
||||||
exec: -> Backbone.Mediator.publish 'level:escape-pressed', {}
|
readOnly: true
|
||||||
|
exec: ->
|
||||||
|
console.log 'esc pressed'
|
||||||
|
Backbone.Mediator.publish 'level:escape-pressed', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'toggle-grid'
|
name: 'toggle-grid'
|
||||||
bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
|
bindKey: {win: 'Ctrl-G', mac: 'Command-G|Ctrl-G'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'level:toggle-grid', {}
|
exec: -> Backbone.Mediator.publish 'level:toggle-grid', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'toggle-debug'
|
name: 'toggle-debug'
|
||||||
bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
|
bindKey: {win: 'Ctrl-\\', mac: 'Command-\\|Ctrl-\\'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'level:toggle-debug', {}
|
exec: -> Backbone.Mediator.publish 'level:toggle-debug', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'toggle-pathfinding'
|
name: 'toggle-pathfinding'
|
||||||
bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
|
bindKey: {win: 'Ctrl-O', mac: 'Command-O|Ctrl-O'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'level:toggle-pathfinding', {}
|
exec: -> Backbone.Mediator.publish 'level:toggle-pathfinding', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'level-scrub-forward'
|
name: 'level-scrub-forward'
|
||||||
bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
|
bindKey: {win: 'Ctrl-]', mac: 'Command-]|Ctrl-]'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'level:scrub-forward', {}
|
exec: -> Backbone.Mediator.publish 'level:scrub-forward', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'level-scrub-back'
|
name: 'level-scrub-back'
|
||||||
bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
|
bindKey: {win: 'Ctrl-[', mac: 'Command-[|Ctrl-]'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'level:scrub-back', {}
|
exec: -> Backbone.Mediator.publish 'level:scrub-back', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'spell-step-forward'
|
name: 'spell-step-forward'
|
||||||
bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
|
bindKey: {win: 'Ctrl-Alt-]', mac: 'Command-Alt-]|Ctrl-Alt-]'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'tome:spell-step-forward', {}
|
exec: -> Backbone.Mediator.publish 'tome:spell-step-forward', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'spell-step-backward'
|
name: 'spell-step-backward'
|
||||||
bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
|
bindKey: {win: 'Ctrl-Alt-[', mac: 'Command-Alt-[|Ctrl-Alt-]'}
|
||||||
|
readOnly: true
|
||||||
exec: -> Backbone.Mediator.publish 'tome:spell-step-backward', {}
|
exec: -> Backbone.Mediator.publish 'tome:spell-step-backward', {}
|
||||||
addCommand
|
addCommand
|
||||||
name: 'spell-beautify'
|
name: 'spell-beautify'
|
||||||
|
@ -815,10 +824,11 @@ module.exports = class SpellView extends CocoView
|
||||||
return if enabled is @controlsEnabled
|
return if enabled is @controlsEnabled
|
||||||
@controlsEnabled = enabled and @writable
|
@controlsEnabled = enabled and @writable
|
||||||
disabled = not enabled
|
disabled = not enabled
|
||||||
$('body').focus() if disabled and $(document.activeElement).is('.ace_text-input')
|
wasFocused = @ace.isFocused()
|
||||||
@ace.setReadOnly disabled
|
@ace.setReadOnly disabled
|
||||||
@ace[if disabled then 'setStyle' else 'unsetStyle'] 'disabled'
|
@ace[if disabled then 'setStyle' else 'unsetStyle'] 'disabled'
|
||||||
@toggleBackground()
|
@toggleBackground()
|
||||||
|
$('body').focus() if disabled and wasFocused
|
||||||
|
|
||||||
toggleBackground: =>
|
toggleBackground: =>
|
||||||
# TODO: make the background an actual background and do the CSS trick
|
# TODO: make the background an actual background and do the CSS trick
|
||||||
|
|
|
@ -67,7 +67,7 @@ class EarnedAchievementHandler extends Handler
|
||||||
if achievement.get('proportionalTo')
|
if achievement.get('proportionalTo')
|
||||||
return @sendBadInputError(res, 'Cannot currently do this to repeatable docs...')
|
return @sendBadInputError(res, 'Cannot currently do this to repeatable docs...')
|
||||||
EarnedAchievement.createForAchievement(achievement, trigger, null, (earnedAchievementDoc) =>
|
EarnedAchievement.createForAchievement(achievement, trigger, null, (earnedAchievementDoc) =>
|
||||||
@sendSuccess(res, earnedAchievementDoc.toObject())
|
@sendCreated(res, earnedAchievementDoc.toObject())
|
||||||
)
|
)
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -88,10 +88,13 @@ PaymentHandler = class PaymentHandler extends Handler
|
||||||
|
|
||||||
#- Check existence
|
#- Check existence
|
||||||
transactionID = transaction.transaction_id
|
transactionID = transaction.transaction_id
|
||||||
criteria = { recipient: req.user._id, 'ios.transactionID': transactionID }
|
criteria = { 'ios.transactionID': transactionID }
|
||||||
Payment.findOne(criteria).exec((err, payment) =>
|
Payment.findOne(criteria).exec((err, payment) =>
|
||||||
|
|
||||||
if payment
|
if payment
|
||||||
|
unless payment.get('recipient').equals(req.user._id)
|
||||||
|
return @sendForbiddenError(res)
|
||||||
|
|
||||||
@recalculateGemsFor(req.user, (err) =>
|
@recalculateGemsFor(req.user, (err) =>
|
||||||
return @sendDatabaseError(res, err) if err
|
return @sendDatabaseError(res, err) if err
|
||||||
@sendSuccess(res, @formatEntity(req, payment))
|
@sendSuccess(res, @formatEntity(req, payment))
|
||||||
|
|
|
@ -122,134 +122,133 @@ describe 'Achievement', ->
|
||||||
|
|
||||||
# TODO: Took level achievements out of this auto achievement business, so fix these tests
|
# TODO: Took level achievements out of this auto achievement business, so fix these tests
|
||||||
|
|
||||||
#describe 'Achieving Achievements', ->
|
describe 'Level Session Achievement', ->
|
||||||
# it 'wait for achievements to be loaded', (done) ->
|
it 'does not generate earned achievements automatically, they need to be created manually', (done) ->
|
||||||
# Achievement.loadAchievements (achievements) ->
|
unittest.getNormalJoe (joe) ->
|
||||||
# expect(Object.keys(achievements).length).toBe(1)
|
session = new LevelSession
|
||||||
#
|
permissions: simplePermissions
|
||||||
# loadedAchievements = Achievement.getLoadedAchievements()
|
creator: joe._id
|
||||||
# expect(Object.keys(loadedAchievements).length).toBe(1)
|
level: original: 'dungeon-arena'
|
||||||
# done()
|
session.save (err, session) ->
|
||||||
#
|
expect(err).toBeNull()
|
||||||
# it 'saving an object that should trigger an unlockable achievement', (done) ->
|
expect(session).toBeDefined()
|
||||||
# unittest.getNormalJoe (joe) ->
|
expect(session.creator).toBe(session.creator)
|
||||||
# session = new LevelSession
|
|
||||||
# permissions: simplePermissions
|
EarnedAchievement.find {}, (err, earnedAchievements) ->
|
||||||
# creator: joe._id
|
expect(err).toBeNull()
|
||||||
# level: original: 'dungeon-arena'
|
expect(earnedAchievements.length).toBe(0)
|
||||||
# session.save (err, doc) ->
|
|
||||||
# expect(err).toBeNull()
|
json = {achievement: unlockable._id, triggeredBy: session._id, collection: 'level.sessions'}
|
||||||
# expect(doc).toBeDefined()
|
request.post {uri: getURL('/db/earned_achievement'), json: json}, (err, res, body) ->
|
||||||
# expect(doc.creator).toBe(session.creator)
|
expect(res.statusCode).toBe(201)
|
||||||
# done()
|
expect(body.achievement).toBe unlockable._id+''
|
||||||
#
|
expect(body.user).toBe joe._id.toHexString()
|
||||||
# it 'verify that an unlockable achievement has been earned', (done) ->
|
expect(body.notified).toBeFalsy()
|
||||||
# unittest.getNormalJoe (joe) ->
|
expect(body.earnedPoints).toBe unlockable.worth
|
||||||
# EarnedAchievement.find {}, (err, docs) ->
|
expect(body.achievedAmount).toBeUndefined()
|
||||||
# expect(err).toBeNull()
|
expect(body.previouslyAchievedAmount).toBeUndefined()
|
||||||
# expect(docs.length).toBe(1)
|
done()
|
||||||
# achievement = docs[0]
|
|
||||||
# expect(achievement).toBeDefined()
|
|
||||||
#
|
|
||||||
# expect(achievement.get 'achievement').toBe unlockable._id
|
|
||||||
# expect(achievement.get 'user').toBe joe._id.toHexString()
|
|
||||||
# expect(achievement.get 'notified').toBeFalsy()
|
|
||||||
# expect(achievement.get 'earnedPoints').toBe unlockable.worth
|
|
||||||
# expect(achievement.get 'achievedAmount').toBeUndefined()
|
|
||||||
# expect(achievement.get 'previouslyAchievedAmount').toBeUndefined()
|
|
||||||
# done()
|
|
||||||
#
|
|
||||||
# it 'saving an object that should trigger a repeatable achievement', (done) ->
|
|
||||||
# unittest.getNormalJoe (joe) ->
|
|
||||||
# expect(joe.get 'simulatedBy').toBeFalsy()
|
|
||||||
# joe.set('simulatedBy', 2)
|
|
||||||
# joe.save (err, doc) ->
|
|
||||||
# expect(err).toBeNull()
|
|
||||||
# done()
|
|
||||||
#
|
|
||||||
# it 'verify that a repeatable achievement has been earned', (done) ->
|
|
||||||
# unittest.getNormalJoe (joe) ->
|
|
||||||
# EarnedAchievement.find {achievementName: repeatable.name}, (err, docs) ->
|
|
||||||
# expect(err).toBeNull()
|
|
||||||
# expect(docs.length).toBe(1)
|
|
||||||
# achievement = docs[0]
|
|
||||||
#
|
|
||||||
# expect(achievement.get 'achievement').toBe repeatable._id
|
|
||||||
# expect(achievement.get 'user').toBe joe._id.toHexString()
|
|
||||||
# expect(achievement.get 'notified').toBeFalsy()
|
|
||||||
# expect(achievement.get 'earnedPoints').toBe 2 * repeatable.worth
|
|
||||||
# expect(achievement.get 'achievedAmount').toBe 2
|
|
||||||
# expect(achievement.get 'previouslyAchievedAmount').toBeFalsy()
|
|
||||||
# done()
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# it 'verify that the repeatable achievement with complex exp has been earned', (done) ->
|
|
||||||
# unittest.getNormalJoe (joe) ->
|
|
||||||
# EarnedAchievement.find {achievementName: diminishing.name}, (err, docs) ->
|
|
||||||
# expect(err).toBeNull()
|
|
||||||
# expect(docs.length).toBe 1
|
|
||||||
# achievement = docs[0]
|
|
||||||
#
|
|
||||||
# expect(achievement.get 'achievedAmount').toBe 2
|
|
||||||
# expect(achievement.get 'earnedPoints').toBe (Math.log(.5 * (2 + .5)) + 1) * diminishing.worth
|
|
||||||
#
|
|
||||||
# done()
|
|
||||||
|
|
||||||
#describe 'Recalculate Achievements', ->
|
|
||||||
# EarnedAchievementHandler = require '../../../server/achievements/earned_achievement_handler'
|
describe 'Achieving Achievements', ->
|
||||||
#
|
it 'wait for achievements to be loaded', (done) ->
|
||||||
# it 'remove earned achievements', (done) ->
|
Achievement.loadAchievements (achievements) ->
|
||||||
# clearModels [EarnedAchievement], (err) ->
|
expect(Object.keys(achievements).length).toBe(1)
|
||||||
# expect(err).toBeNull()
|
|
||||||
# EarnedAchievement.find {}, (err, earned) ->
|
loadedAchievements = Achievement.getLoadedAchievements()
|
||||||
# expect(earned.length).toBe 0
|
expect(Object.keys(loadedAchievements).length).toBe(1)
|
||||||
#
|
done()
|
||||||
# User.update {}, {$set: {points: 0}}, {multi:true}, (err) ->
|
|
||||||
# expect(err).toBeNull()
|
it 'saving an object that should trigger a repeatable achievement', (done) ->
|
||||||
# done()
|
unittest.getNormalJoe (joe) ->
|
||||||
#
|
expect(joe.get 'simulatedBy').toBeFalsy()
|
||||||
# it 'can not be accessed by regular users', (done) ->
|
joe.set('simulatedBy', 2)
|
||||||
# loginJoe -> request.post {uri:getURL '/admin/earned_achievement/recalculate'}, (err, res, body) ->
|
joe.save (err, doc) ->
|
||||||
# expect(res.statusCode).toBe 403
|
expect(err).toBeNull()
|
||||||
# done()
|
done()
|
||||||
#
|
|
||||||
# it 'can recalculate a selection of achievements', (done) ->
|
it 'verify that a repeatable achievement has been earned', (done) ->
|
||||||
# loginAdmin ->
|
unittest.getNormalJoe (joe) ->
|
||||||
# EarnedAchievementHandler.constructor.recalculate ['dungeon-arena-started'], ->
|
EarnedAchievement.find {achievementName: repeatable.name}, (err, docs) ->
|
||||||
# EarnedAchievement.find {}, (err, earnedAchievements) ->
|
expect(err).toBeNull()
|
||||||
# expect(earnedAchievements.length).toBe 1
|
expect(docs.length).toBe(1)
|
||||||
#
|
achievement = docs[0]
|
||||||
# # Recalculate again, doesn't change a thing
|
|
||||||
# EarnedAchievementHandler.constructor.recalculate ['dungeon-arena-started'], ->
|
expect(achievement.get 'achievement').toBe repeatable._id
|
||||||
# EarnedAchievement.find {}, (err, earnedAchievements) ->
|
expect(achievement.get 'user').toBe joe._id.toHexString()
|
||||||
# expect(earnedAchievements.length).toBe 1
|
expect(achievement.get 'notified').toBeFalsy()
|
||||||
#
|
expect(achievement.get 'earnedPoints').toBe 2 * repeatable.worth
|
||||||
# unittest.getNormalJoe (joe) ->
|
expect(achievement.get 'achievedAmount').toBe 2
|
||||||
# User.findById joe.get('id'), (err, guy) ->
|
expect(achievement.get 'previouslyAchievedAmount').toBeFalsy()
|
||||||
# expect(err).toBeNull()
|
done()
|
||||||
# expect(guy.get 'points').toBe unlockable.worth
|
|
||||||
# done()
|
it 'verify that the repeatable achievement with complex exp has been earned', (done) ->
|
||||||
#
|
unittest.getNormalJoe (joe) ->
|
||||||
# it 'can recalculate all achievements', (done) ->
|
EarnedAchievement.find {achievementName: diminishing.name}, (err, docs) ->
|
||||||
# loginAdmin ->
|
expect(err).toBeNull()
|
||||||
# Achievement.count {}, (err, count) ->
|
expect(docs.length).toBe 1
|
||||||
# expect(count).toBe 3
|
achievement = docs[0]
|
||||||
# EarnedAchievementHandler.constructor.recalculate ->
|
|
||||||
# EarnedAchievement.find {}, (err, earnedAchievements) ->
|
expect(achievement.get 'achievedAmount').toBe 2
|
||||||
# expect(earnedAchievements.length).toBe 3
|
expect(achievement.get 'earnedPoints').toBe (Math.log(.5 * (2 + .5)) + 1) * diminishing.worth
|
||||||
# unittest.getNormalJoe (joe) ->
|
|
||||||
# User.findById joe.get('id'), (err, guy) ->
|
done()
|
||||||
# expect(err).toBeNull()
|
|
||||||
# expect(guy.get 'points').toBe unlockable.worth + 2 * repeatable.worth + (Math.log(.5 * (2 + .5)) + 1) * diminishing.worth
|
describe 'Recalculate Achievements', ->
|
||||||
# done()
|
EarnedAchievementHandler = require '../../../server/achievements/earned_achievement_handler'
|
||||||
#
|
|
||||||
# it 'cleaning up test: deleting all Achievements and related', (done) ->
|
it 'remove earned achievements', (done) ->
|
||||||
# clearModels [Achievement, EarnedAchievement, LevelSession], (err) ->
|
clearModels [EarnedAchievement], (err) ->
|
||||||
# expect(err).toBeNull()
|
expect(err).toBeNull()
|
||||||
#
|
EarnedAchievement.find {}, (err, earned) ->
|
||||||
# # reset achievements in memory as well
|
expect(earned.length).toBe 0
|
||||||
# Achievement.resetAchievements()
|
|
||||||
# loadedAchievements = Achievement.getLoadedAchievements()
|
User.update {}, {$set: {points: 0}}, {multi:true}, (err) ->
|
||||||
# expect(Object.keys(loadedAchievements).length).toBe(0)
|
expect(err).toBeNull()
|
||||||
#
|
done()
|
||||||
# done()
|
|
||||||
|
it 'can not be accessed by regular users', (done) ->
|
||||||
|
loginJoe -> request.post {uri:getURL '/admin/earned_achievement/recalculate'}, (err, res, body) ->
|
||||||
|
expect(res.statusCode).toBe 403
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'can recalculate a selection of achievements', (done) ->
|
||||||
|
loginAdmin ->
|
||||||
|
EarnedAchievementHandler.constructor.recalculate ['dungeon-arena-started'], ->
|
||||||
|
EarnedAchievement.find {}, (err, earnedAchievements) ->
|
||||||
|
expect(earnedAchievements.length).toBe 1
|
||||||
|
|
||||||
|
# Recalculate again, doesn't change a thing
|
||||||
|
EarnedAchievementHandler.constructor.recalculate ['dungeon-arena-started'], ->
|
||||||
|
EarnedAchievement.find {}, (err, earnedAchievements) ->
|
||||||
|
expect(earnedAchievements.length).toBe 1
|
||||||
|
|
||||||
|
unittest.getNormalJoe (joe) ->
|
||||||
|
User.findById joe.get('id'), (err, guy) ->
|
||||||
|
expect(err).toBeNull()
|
||||||
|
expect(guy.get 'points').toBe unlockable.worth
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'can recalculate all achievements', (done) ->
|
||||||
|
loginAdmin ->
|
||||||
|
Achievement.count {}, (err, count) ->
|
||||||
|
expect(count).toBe 3
|
||||||
|
EarnedAchievementHandler.constructor.recalculate ->
|
||||||
|
EarnedAchievement.find {}, (err, earnedAchievements) ->
|
||||||
|
expect(earnedAchievements.length).toBe 3
|
||||||
|
unittest.getNormalJoe (joe) ->
|
||||||
|
User.findById joe.get('id'), (err, guy) ->
|
||||||
|
expect(err).toBeNull()
|
||||||
|
expect(guy.get 'points').toBe unlockable.worth + 2 * repeatable.worth + (Math.log(.5 * (2 + .5)) + 1) * diminishing.worth
|
||||||
|
done()
|
||||||
|
|
||||||
|
it 'cleaning up test: deleting all Achievements and related', (done) ->
|
||||||
|
clearModels [Achievement, EarnedAchievement, LevelSession], (err) ->
|
||||||
|
expect(err).toBeNull()
|
||||||
|
|
||||||
|
# reset achievements in memory as well
|
||||||
|
Achievement.resetAchievements()
|
||||||
|
loadedAchievements = Achievement.getLoadedAchievements()
|
||||||
|
expect(Object.keys(loadedAchievements).length).toBe(0)
|
||||||
|
|
||||||
|
done()
|
||||||
|
|
|
@ -52,6 +52,12 @@ describe '/db/payment', ->
|
||||||
done()
|
done()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
it 'prevents other users from reusing payment receipts', (done) ->
|
||||||
|
loginSam ->
|
||||||
|
request.post {uri: paymentURL, json: firstApplePayment}, (err, res, body) ->
|
||||||
|
expect(res.statusCode).toBe 403
|
||||||
|
done()
|
||||||
|
|
||||||
it 'processes only the transactionID that is given', (done) ->
|
it 'processes only the transactionID that is given', (done) ->
|
||||||
loginJoe ->
|
loginJoe ->
|
||||||
request.post {uri: paymentURL, json: secondApplePayment}, (err, res, body) ->
|
request.post {uri: paymentURL, json: secondApplePayment}, (err, res, body) ->
|
||||||
|
|
Loading…
Add table
Reference in a new issue