mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-30 02:55:43 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
c1948ab083
41 changed files with 299 additions and 80 deletions
|
@ -15,8 +15,10 @@ before_script:
|
||||||
- "./node_modules/.bin/bower install"
|
- "./node_modules/.bin/bower install"
|
||||||
- "gem install sass"
|
- "gem install sass"
|
||||||
- "./node_modules/.bin/brunch b"
|
- "./node_modules/.bin/brunch b"
|
||||||
- "./bin/coco-mongodb fork"
|
- "mkdir mongo"
|
||||||
|
- "mongod --dbpath=./mongo --fork --logpath ./mongodb.log"
|
||||||
- "node index.js --unittest &"
|
- "node index.js --unittest &"
|
||||||
|
- "sleep 5" # to give node a chance to start
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- "./node_modules/jasmine-node/bin/jasmine-node test/server/ --coffee --captureExceptions"
|
- "./node_modules/jasmine-node/bin/jasmine-node test/server/ --coffee --captureExceptions"
|
||||||
|
|
|
@ -13,9 +13,6 @@ userPropsToSave =
|
||||||
|
|
||||||
|
|
||||||
module.exports = FacebookHandler = class FacebookHandler extends CocoClass
|
module.exports = FacebookHandler = class FacebookHandler extends CocoClass
|
||||||
constructor: ->
|
|
||||||
super()
|
|
||||||
|
|
||||||
subscriptions:
|
subscriptions:
|
||||||
'facebook-logged-in':'onFacebookLogin'
|
'facebook-logged-in':'onFacebookLogin'
|
||||||
'facebook-logged-out': 'onFacebookLogout'
|
'facebook-logged-out': 'onFacebookLogout'
|
||||||
|
@ -42,22 +39,18 @@ module.exports = FacebookHandler = class FacebookHandler extends CocoClass
|
||||||
return
|
return
|
||||||
|
|
||||||
oldEmail = me.get('email')
|
oldEmail = me.get('email')
|
||||||
patch = {}
|
me.set('firstName', r.first_name) if r.first_name
|
||||||
patch.firstName = r.first_name if r.first_name
|
me.set('lastName', r.last_name) if r.last_name
|
||||||
patch.lastName = r.last_name if r.last_name
|
me.set('gender', r.gender) if r.gender
|
||||||
patch.gender = r.gender if r.gender
|
me.set('email', r.email) if r.email
|
||||||
patch.email = r.email if r.email
|
me.set('facebookID', r.id) if r.id
|
||||||
patch.facebookID = r.id if r.id
|
|
||||||
me.set(patch)
|
|
||||||
patch._id = me.id
|
|
||||||
|
|
||||||
Backbone.Mediator.publish('logging-in-with-facebook')
|
Backbone.Mediator.publish('logging-in-with-facebook')
|
||||||
window.tracker?.trackEvent 'Facebook Login'
|
window.tracker?.trackEvent 'Facebook Login'
|
||||||
window.tracker?.identify()
|
window.tracker?.identify()
|
||||||
me.save(patch, {
|
me.patch({
|
||||||
patch: true
|
|
||||||
error: backboneFailure,
|
error: backboneFailure,
|
||||||
url: "/db/user?facebookID=#{r.id}&facebookAccessToken=#{@authResponse.accessToken}"
|
url: "/db/user/#{me.id}?facebookID=#{r.id}&facebookAccessToken=#{@authResponse.accessToken}"
|
||||||
success: (model) ->
|
success: (model) ->
|
||||||
window.location.reload() if model.get('email') isnt oldEmail
|
window.location.reload() if model.get('email') isnt oldEmail
|
||||||
})
|
})
|
||||||
|
|
|
@ -224,7 +224,7 @@ module.exports = class LevelBus extends Bus
|
||||||
|
|
||||||
saveSession: ->
|
saveSession: ->
|
||||||
return if _.isEmpty @changedSessionProperties
|
return if _.isEmpty @changedSessionProperties
|
||||||
# don't let peaking admins mess with the session accidentally
|
# don't let peeking admins mess with the session accidentally
|
||||||
return unless @session.get('multiplayer') or @session.get('creator') is me.id
|
return unless @session.get('multiplayer') or @session.get('creator') is me.id
|
||||||
Backbone.Mediator.publish 'level:session-will-save', session: @session
|
Backbone.Mediator.publish 'level:session-will-save', session: @session
|
||||||
patch = {}
|
patch = {}
|
||||||
|
|
|
@ -10,7 +10,7 @@ init = ->
|
||||||
if me and not me.get('testGroupNumber')?
|
if me and not me.get('testGroupNumber')?
|
||||||
# Assign testGroupNumber to returning visitors; new ones in server/routes/auth
|
# Assign testGroupNumber to returning visitors; new ones in server/routes/auth
|
||||||
me.set 'testGroupNumber', Math.floor(Math.random() * 256)
|
me.set 'testGroupNumber', Math.floor(Math.random() * 256)
|
||||||
me.save()
|
me.patch()
|
||||||
|
|
||||||
Backbone.listenTo(me, 'sync', Backbone.Mediator.publish('me:synced', {me:me}))
|
Backbone.listenTo(me, 'sync', Backbone.Mediator.publish('me:synced', {me:me}))
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
module.exports.thangNames = thangNames =
|
module.exports.thangNames = thangNames =
|
||||||
"Soldier M": [
|
"Soldier M": [
|
||||||
|
"Duke"
|
||||||
"William"
|
"William"
|
||||||
"Lucas"
|
"Lucas"
|
||||||
"Marcus"
|
"Marcus"
|
||||||
|
@ -66,6 +67,7 @@ module.exports.thangNames = thangNames =
|
||||||
"Coco"
|
"Coco"
|
||||||
"Buffy"
|
"Buffy"
|
||||||
"Allankrita"
|
"Allankrita"
|
||||||
|
"Kay"
|
||||||
]
|
]
|
||||||
"Peasant M": [
|
"Peasant M": [
|
||||||
"Yorik"
|
"Yorik"
|
||||||
|
@ -355,6 +357,8 @@ module.exports.thangNames = thangNames =
|
||||||
"Hank"
|
"Hank"
|
||||||
"Jeph"
|
"Jeph"
|
||||||
"Neville"
|
"Neville"
|
||||||
|
"Alphonse"
|
||||||
|
"Edward"
|
||||||
]
|
]
|
||||||
"Captain": [
|
"Captain": [
|
||||||
"Anya"
|
"Anya"
|
||||||
|
@ -367,4 +371,5 @@ module.exports.thangNames = thangNames =
|
||||||
"Jane"
|
"Jane"
|
||||||
"Lia"
|
"Lia"
|
||||||
"Hardcastle"
|
"Hardcastle"
|
||||||
|
"Leona"
|
||||||
]
|
]
|
||||||
|
|
|
@ -294,6 +294,7 @@
|
||||||
project_picture_help: "Upload a 230x115px or larger image showing off the project."
|
project_picture_help: "Upload a 230x115px or larger image showing off the project."
|
||||||
project_link: "Link"
|
project_link: "Link"
|
||||||
project_link_help: "Link to the project."
|
project_link_help: "Link to the project."
|
||||||
|
player_code: "Player Code"
|
||||||
|
|
||||||
employers:
|
employers:
|
||||||
want_to_hire_our_players: "Want to hire expert CodeCombat players?"
|
want_to_hire_our_players: "Want to hire expert CodeCombat players?"
|
||||||
|
@ -867,6 +868,7 @@
|
||||||
source_document: "Source Document"
|
source_document: "Source Document"
|
||||||
document: "Document" # note to diplomats: not a physical document, a document in MongoDB, ie a record in a database
|
document: "Document" # note to diplomats: not a physical document, a document in MongoDB, ie a record in a database
|
||||||
sprite_sheet: "Sprite Sheet"
|
sprite_sheet: "Sprite Sheet"
|
||||||
|
candidate_sessions: "Candidate Sessions"
|
||||||
|
|
||||||
delta:
|
delta:
|
||||||
added: "Added"
|
added: "Added"
|
||||||
|
|
|
@ -98,13 +98,28 @@ class CocoModel extends Backbone.Model
|
||||||
@trigger "save", @
|
@trigger "save", @
|
||||||
return super attrs, options
|
return super attrs, options
|
||||||
|
|
||||||
|
patch: (options) ->
|
||||||
|
return false unless @_revertAttributes
|
||||||
|
options ?= {}
|
||||||
|
options.patch = true
|
||||||
|
|
||||||
|
attrs = {_id: @id}
|
||||||
|
keys = []
|
||||||
|
for key in _.keys @attributes
|
||||||
|
unless _.isEqual @attributes[key], @_revertAttributes[key]
|
||||||
|
attrs[key] = @attributes[key]
|
||||||
|
keys.push key
|
||||||
|
|
||||||
|
return unless keys.length
|
||||||
|
console.debug 'Patching', @get('name') or @, keys
|
||||||
|
@save(attrs, options)
|
||||||
|
|
||||||
fetch: ->
|
fetch: ->
|
||||||
@jqxhr = super(arguments...)
|
@jqxhr = super(arguments...)
|
||||||
@loading = true
|
@loading = true
|
||||||
@jqxhr
|
@jqxhr
|
||||||
|
|
||||||
markToRevert: ->
|
markToRevert: ->
|
||||||
console.debug "Saving _revertAttributes for #{@constructor.className}: '#{@get('name')}'"
|
|
||||||
if @type() is 'ThangType'
|
if @type() is 'ThangType'
|
||||||
@_revertAttributes = _.clone @attributes # No deep clones for these!
|
@_revertAttributes = _.clone @attributes # No deep clones for these!
|
||||||
else
|
else
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif
|
||||||
color: #555
|
color: #555
|
||||||
|
|
||||||
ul.links, ul.projects
|
ul.links, ul.projects, ul.sessions
|
||||||
margin: 0
|
margin: 0
|
||||||
padding: 0
|
padding: 0
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,19 @@ block content
|
||||||
span(data-i18n="account_profile.contact") Contact
|
span(data-i18n="account_profile.contact") Contact
|
||||||
| #{profile.name.split(' ')[0]}
|
| #{profile.name.split(' ')[0]}
|
||||||
|
|
||||||
|
if !editing && sessions.length
|
||||||
|
h3(data-i18n="account_profile.player_code") Player Code
|
||||||
|
ul.sessions
|
||||||
|
each session in sessions
|
||||||
|
li
|
||||||
|
- var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + "&session=" + session._id;
|
||||||
|
a(href=sessionLink)
|
||||||
|
span= session.levelName
|
||||||
|
if session.team
|
||||||
|
span #{session.team}
|
||||||
|
if session.codeLanguage != 'javascript'
|
||||||
|
span - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]}
|
||||||
|
|
||||||
.middle-column.full-height-column
|
.middle-column.full-height-column
|
||||||
.sub-column
|
.sub-column
|
||||||
#name-container.editable-section
|
#name-container.editable-section
|
||||||
|
|
|
@ -57,9 +57,9 @@ block content
|
||||||
strong= act.count
|
strong= act.count
|
||||||
|
|
|
|
||||||
br
|
br
|
||||||
span= moment(activity.login.first).fromNow()
|
span= moment(act.first).fromNow()
|
||||||
br
|
br
|
||||||
span= moment(activity.login.last).fromNow()
|
span= moment(act.last).fromNow()
|
||||||
else
|
else
|
||||||
td 0
|
td 0
|
||||||
td(data-employer-age=(new Date() - new Date(employer.get('signedEmployerAgreement').date)) / 86400 / 1000)= moment(employer.get('signedEmployerAgreement').date).fromNow()
|
td(data-employer-age=(new Date() - new Date(employer.get('signedEmployerAgreement').date)) / 86400 / 1000)= moment(employer.get('signedEmployerAgreement').date).fromNow()
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
View = require 'views/kinds/RootView'
|
View = require 'views/kinds/RootView'
|
||||||
template = require 'templates/account/profile'
|
template = require 'templates/account/profile'
|
||||||
User = require 'models/User'
|
User = require 'models/User'
|
||||||
|
LevelSession = require 'models/LevelSession'
|
||||||
|
CocoCollection = require 'collections/CocoCollection'
|
||||||
{me} = require 'lib/auth'
|
{me} = require 'lib/auth'
|
||||||
JobProfileContactView = require 'views/modal/job_profile_contact_modal'
|
JobProfileContactView = require 'views/modal/job_profile_contact_modal'
|
||||||
JobProfileView = require 'views/account/job_profile_view'
|
JobProfileView = require 'views/account/job_profile_view'
|
||||||
forms = require 'lib/forms'
|
forms = require 'lib/forms'
|
||||||
|
|
||||||
|
class LevelSessionsCollection extends CocoCollection
|
||||||
|
url: -> "/db/user/#{@userID}/level.sessions/employer"
|
||||||
|
model: LevelSession
|
||||||
|
constructor: (@userID) ->
|
||||||
|
super()
|
||||||
|
|
||||||
module.exports = class ProfileView extends View
|
module.exports = class ProfileView extends View
|
||||||
id: "profile-view"
|
id: "profile-view"
|
||||||
template: template
|
template: template
|
||||||
|
@ -42,9 +50,7 @@ module.exports = class ProfileView extends View
|
||||||
if User.isObjectID @userID
|
if User.isObjectID @userID
|
||||||
@finishInit()
|
@finishInit()
|
||||||
else
|
else
|
||||||
console.log "getting", @userID
|
|
||||||
$.ajax "/db/user/#{@userID}/nameToID", success: (@userID) =>
|
$.ajax "/db/user/#{@userID}/nameToID", success: (@userID) =>
|
||||||
console.log " got", @userID
|
|
||||||
@finishInit() unless @destroyed
|
@finishInit() unless @destroyed
|
||||||
@render()
|
@render()
|
||||||
|
|
||||||
|
@ -63,6 +69,7 @@ module.exports = class ProfileView extends View
|
||||||
$.post "/db/user/#{@userID}/track/viewed_by_employer" unless me.isAdmin()
|
$.post "/db/user/#{@userID}/track/viewed_by_employer" unless me.isAdmin()
|
||||||
else
|
else
|
||||||
@user = User.getByID(@userID)
|
@user = User.getByID(@userID)
|
||||||
|
@sessions = @supermodel.loadCollection(new LevelSessionsCollection(@userID), 'candidate_sessions').model
|
||||||
|
|
||||||
onLinkedInLoaded: =>
|
onLinkedInLoaded: =>
|
||||||
@linkedinLoaded = true
|
@linkedinLoaded = true
|
||||||
|
@ -80,11 +87,11 @@ module.exports = class ProfileView extends View
|
||||||
@renderLinkedInButton()
|
@renderLinkedInButton()
|
||||||
else
|
else
|
||||||
@waitingForLinkedIn = true
|
@waitingForLinkedIn = true
|
||||||
|
|
||||||
importLinkedIn: =>
|
importLinkedIn: =>
|
||||||
overwriteConfirm = confirm("Importing LinkedIn data will overwrite your current work experience, skills, name, descriptions, and education. Continue?")
|
overwriteConfirm = confirm("Importing LinkedIn data will overwrite your current work experience, skills, name, descriptions, and education. Continue?")
|
||||||
unless overwriteConfirm then return
|
unless overwriteConfirm then return
|
||||||
application.linkedinHandler.getProfileData (err, profileData) =>
|
application.linkedinHandler.getProfileData (err, profileData) =>
|
||||||
console.log profileData
|
|
||||||
@processLinkedInProfileData profileData
|
@processLinkedInProfileData profileData
|
||||||
jobProfileSchema: -> @user.schema().properties.jobProfile.properties
|
jobProfileSchema: -> @user.schema().properties.jobProfile.properties
|
||||||
|
|
||||||
|
@ -217,6 +224,8 @@ module.exports = class ProfileView extends View
|
||||||
links = ($.extend(true, {}, link) for link in links)
|
links = ($.extend(true, {}, link) for link in links)
|
||||||
link.icon = @iconForLink link for link in links
|
link.icon = @iconForLink link for link in links
|
||||||
context.profileLinks = _.sortBy links, (link) -> not link.icon # icons first
|
context.profileLinks = _.sortBy links, (link) -> not link.icon # icons first
|
||||||
|
context.sessions = (s.attributes for s in @sessions.models when (s.get('submitted') or s.get('level-id') is 'gridmancer'))
|
||||||
|
context.sessions.sort (a, b) -> (b.playtime ? 0) - (a.playtime ? 0)
|
||||||
context
|
context
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
|
@ -303,7 +312,7 @@ module.exports = class ProfileView extends View
|
||||||
errors = @user.validate()
|
errors = @user.validate()
|
||||||
return @showErrors errors if errors
|
return @showErrors errors if errors
|
||||||
jobProfile = @user.get('jobProfile')
|
jobProfile = @user.get('jobProfile')
|
||||||
jobProfile.updated = (new Date()).toISOString()
|
jobProfile.updated = (new Date()).toISOString() if @user is me
|
||||||
@user.set 'jobProfile', jobProfile
|
@user.set 'jobProfile', jobProfile
|
||||||
return unless res = @user.save()
|
return unless res = @user.save()
|
||||||
res.error =>
|
res.error =>
|
||||||
|
|
|
@ -113,7 +113,7 @@ module.exports = class SettingsView extends View
|
||||||
|
|
||||||
return unless me.hasLocalChanges()
|
return unless me.hasLocalChanges()
|
||||||
|
|
||||||
res = me.save()
|
res = me.patch()
|
||||||
return unless res
|
return unless res
|
||||||
save = $('#save-button', @$el).text($.i18n.t('common.saving', defaultValue: 'Saving...'))
|
save = $('#save-button', @$el).text($.i18n.t('common.saving', defaultValue: 'Saving...'))
|
||||||
.removeClass('btn-danger').addClass('btn-success').show()
|
.removeClass('btn-danger').addClass('btn-success').show()
|
||||||
|
|
|
@ -36,7 +36,7 @@ module.exports = class ContributeClassView extends View
|
||||||
subscription = el.attr('name')
|
subscription = el.attr('name')
|
||||||
|
|
||||||
me.setEmailSubscription subscription+'News', checked
|
me.setEmailSubscription subscription+'News', checked
|
||||||
me.save()
|
me.patch()
|
||||||
@openModalView new SignupModalView() if me.get 'anonymous'
|
@openModalView new SignupModalView() if me.get 'anonymous'
|
||||||
el.parent().find('.saved-notification').finish().show('fast').delay(3000).fadeOut(2000)
|
el.parent().find('.saved-notification').finish().show('fast').delay(3000).fadeOut(2000)
|
||||||
|
|
||||||
|
|
|
@ -52,6 +52,7 @@ module.exports = class EmployersView extends View
|
||||||
@listenToOnce @candidates, 'all', @renderCandidatesAndSetupScrolling
|
@listenToOnce @candidates, 'all', @renderCandidatesAndSetupScrolling
|
||||||
|
|
||||||
renderCandidatesAndSetupScrolling: =>
|
renderCandidatesAndSetupScrolling: =>
|
||||||
|
|
||||||
@render()
|
@render()
|
||||||
$(".nano").nanoScroller()
|
$(".nano").nanoScroller()
|
||||||
if window.history?.state?.lastViewedCandidateID
|
if window.history?.state?.lastViewedCandidateID
|
||||||
|
|
|
@ -150,7 +150,7 @@ module.exports = class RootView extends CocoView
|
||||||
|
|
||||||
saveLanguage: (newLang) ->
|
saveLanguage: (newLang) ->
|
||||||
me.set('preferredLanguage', newLang)
|
me.set('preferredLanguage', newLang)
|
||||||
res = me.save()
|
res = me.patch()
|
||||||
return unless res
|
return unless res
|
||||||
res.error ->
|
res.error ->
|
||||||
errors = JSON.parse(res.responseText)
|
errors = JSON.parse(res.responseText)
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = class DiplomatSuggestionView extends View
|
||||||
|
|
||||||
subscribeAsDiplomat: ->
|
subscribeAsDiplomat: ->
|
||||||
me.setEmailSubscription 'diplomatNews', true
|
me.setEmailSubscription 'diplomatNews', true
|
||||||
me.save()
|
me.patch()
|
||||||
$("#email_translator").prop("checked", 1)
|
$("#email_translator").prop("checked", 1)
|
||||||
@hide()
|
@hide()
|
||||||
return
|
return
|
||||||
|
|
|
@ -40,7 +40,7 @@ module.exports = class WizardSettingsModal extends View
|
||||||
forms.applyErrorsToForm(@$el, res)
|
forms.applyErrorsToForm(@$el, res)
|
||||||
return
|
return
|
||||||
|
|
||||||
res = me.save()
|
res = me.patch()
|
||||||
return unless res
|
return unless res
|
||||||
save = $('#save-button', @$el).text($.i18n.t('common.saving', defaultValue: 'Saving...'))
|
save = $('#save-button', @$el).text($.i18n.t('common.saving', defaultValue: 'Saving...'))
|
||||||
.addClass('btn-info').show().removeClass('btn-danger')
|
.addClass('btn-info').show().removeClass('btn-danger')
|
||||||
|
|
|
@ -10,14 +10,6 @@ ModelModal = require 'views/modal/model_modal'
|
||||||
|
|
||||||
HIGHEST_SCORE = 1000000
|
HIGHEST_SCORE = 1000000
|
||||||
|
|
||||||
class LevelSessionsCollection extends CocoCollection
|
|
||||||
url: ''
|
|
||||||
model: LevelSession
|
|
||||||
|
|
||||||
constructor: (levelID) ->
|
|
||||||
super()
|
|
||||||
@url = "/db/level/#{levelID}/all_sessions"
|
|
||||||
|
|
||||||
module.exports = class LadderTabView extends CocoView
|
module.exports = class LadderTabView extends CocoView
|
||||||
id: 'ladder-tab-view'
|
id: 'ladder-tab-view'
|
||||||
template: require 'templates/play/ladder/ladder_tab'
|
template: require 'templates/play/ladder/ladder_tab'
|
||||||
|
|
|
@ -43,7 +43,7 @@ module.exports = class LadderView extends RootView
|
||||||
|
|
||||||
onLoaded: ->
|
onLoaded: ->
|
||||||
@teams = teamDataFromLevel @level
|
@teams = teamDataFromLevel @level
|
||||||
@render()
|
super()
|
||||||
|
|
||||||
getRenderData: ->
|
getRenderData: ->
|
||||||
ctx = super()
|
ctx = super()
|
||||||
|
|
|
@ -79,7 +79,7 @@ module.exports = class EditorConfigModal extends View
|
||||||
Backbone.Mediator.publish 'tome:change-config'
|
Backbone.Mediator.publish 'tome:change-config'
|
||||||
Backbone.Mediator.publish 'tome:change-language', language: newLanguage unless newLanguage is oldLanguage
|
Backbone.Mediator.publish 'tome:change-language', language: newLanguage unless newLanguage is oldLanguage
|
||||||
@session.save() unless newLanguage is oldLanguage
|
@session.save() unless newLanguage is oldLanguage
|
||||||
me.save()
|
me.patch()
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
super()
|
super()
|
||||||
|
|
|
@ -81,7 +81,7 @@ module.exports = class VictoryModal extends View
|
||||||
if enough and not me.get('hourOfCodeComplete')
|
if enough and not me.get('hourOfCodeComplete')
|
||||||
$('body').append($("<img src='http://code.org/api/hour/finish_codecombat.png' style='visibility: hidden;'>"))
|
$('body').append($("<img src='http://code.org/api/hour/finish_codecombat.png' style='visibility: hidden;'>"))
|
||||||
me.set 'hourOfCodeComplete', true
|
me.set 'hourOfCodeComplete', true
|
||||||
me.save()
|
me.patch()
|
||||||
window.tracker?.trackEvent 'Hour of Code Finish', {}
|
window.tracker?.trackEvent 'Hour of Code Finish', {}
|
||||||
# Show the "I'm done" button if they get to the end, unless it's been over two hours
|
# Show the "I'm done" button if they get to the end, unless it's been over two hours
|
||||||
tooMuch = elapsed >= 120 * 60 * 1000
|
tooMuch = elapsed >= 120 * 60 * 1000
|
||||||
|
|
|
@ -355,7 +355,7 @@ module.exports = class PlaybackView extends View
|
||||||
onToggleMusic: (e) ->
|
onToggleMusic: (e) ->
|
||||||
e?.preventDefault()
|
e?.preventDefault()
|
||||||
me.set('music', not me.get('music'))
|
me.set('music', not me.get('music'))
|
||||||
me.save()
|
me.patch()
|
||||||
$(document.activeElement).blur()
|
$(document.activeElement).blur()
|
||||||
|
|
||||||
destroy: ->
|
destroy: ->
|
||||||
|
|
|
@ -97,7 +97,7 @@ module.exports = class CastButtonView extends View
|
||||||
return unless delay
|
return unless delay
|
||||||
@autocastDelay = delay = parseInt delay
|
@autocastDelay = delay = parseInt delay
|
||||||
me.set('autocastDelay', delay)
|
me.set('autocastDelay', delay)
|
||||||
me.save()
|
me.patch()
|
||||||
spell.view.setAutocastDelay delay for spellKey, spell of @spells
|
spell.view.setAutocastDelay delay for spellKey, spell of @spells
|
||||||
@castOptions.find('a').each ->
|
@castOptions.find('a').each ->
|
||||||
$(@).toggleClass('selected', parseInt($(@).attr('data-delay')) is delay)
|
$(@).toggleClass('selected', parseInt($(@).attr('data-delay')) is delay)
|
||||||
|
|
|
@ -24,7 +24,7 @@ module.exports = class Spell
|
||||||
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
|
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
|
||||||
teamSpells = @session.get('teamSpells')
|
teamSpells = @session.get('teamSpells')
|
||||||
team = @session.get('team') ? 'humans'
|
team = @session.get('team') ? 'humans'
|
||||||
@useTranspiledCode = @permissions.readwrite.length and ((teamSpells and not _.contains(teamSpells[team], @spellKey)) or (@session.get('creator') isnt me.id) or @spectateView)
|
@useTranspiledCode = @permissions.readwrite.length and ((teamSpells and not _.contains(teamSpells[team], @spellKey)) or (@session.get('creator') isnt me.id and not (me.isAdmin() or 'employer' in me.get('permissions'))) or @spectateView)
|
||||||
#console.log @spellKey, "using transpiled code?", @useTranspiledCode
|
#console.log @spellKey, "using transpiled code?", @useTranspiledCode
|
||||||
@source = @originalSource = p.source
|
@source = @originalSource = p.source
|
||||||
@parameters = p.parameters
|
@parameters = p.parameters
|
||||||
|
|
|
@ -93,7 +93,7 @@ module.exports = class PlayLevelView extends View
|
||||||
|
|
||||||
setUpHourOfCode: ->
|
setUpHourOfCode: ->
|
||||||
me.set 'hourOfCode', true
|
me.set 'hourOfCode', true
|
||||||
me.save()
|
me.patch()
|
||||||
$('body').append($("<img src='http://code.org/api/hour/begin_codecombat.png' style='visibility: hidden;'>"))
|
$('body').append($("<img src='http://code.org/api/hour/begin_codecombat.png' style='visibility: hidden;'>"))
|
||||||
application.tracker?.trackEvent 'Hour of Code Begin', {}
|
application.tracker?.trackEvent 'Hour of Code Begin', {}
|
||||||
|
|
||||||
|
|
|
@ -107,6 +107,7 @@ module.exports = TestView = class TestView extends CocoView
|
||||||
# TODO Stubbify more things
|
# TODO Stubbify more things
|
||||||
# * document.location
|
# * document.location
|
||||||
# * firebase
|
# * firebase
|
||||||
|
# * all the services that load in main.html
|
||||||
|
|
||||||
afterEach ->
|
afterEach ->
|
||||||
# TODO Clean up more things
|
# TODO Clean up more things
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
mongoose = require('mongoose')
|
mongoose = require('mongoose')
|
||||||
plugins = require('../plugins/plugins')
|
|
||||||
jsonschema = require('../../app/schemas/models/achievement')
|
jsonschema = require('../../app/schemas/models/achievement')
|
||||||
log = require 'winston'
|
log = require 'winston'
|
||||||
|
|
||||||
|
@ -29,7 +28,9 @@ AchievementSchema.pre('save', (next) ->
|
||||||
next()
|
next()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
module.exports = Achievement = mongoose.model('Achievement', AchievementSchema)
|
||||||
|
|
||||||
|
plugins = require('../plugins/plugins')
|
||||||
|
|
||||||
AchievementSchema.plugin(plugins.NamedPlugin)
|
AchievementSchema.plugin(plugins.NamedPlugin)
|
||||||
AchievementSchema.plugin(plugins.SearchablePlugin, {searchable: ['name']})
|
AchievementSchema.plugin(plugins.SearchablePlugin, {searchable: ['name']})
|
||||||
|
|
||||||
module.exports = Achievement = mongoose.model('Achievement', AchievementSchema)
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ LevelComponentHandler = class LevelComponentHandler extends Handler
|
||||||
'description'
|
'description'
|
||||||
'code'
|
'code'
|
||||||
'js'
|
'js'
|
||||||
'language'
|
'codeLanguage'
|
||||||
'dependencies'
|
'dependencies'
|
||||||
'propertyDocumentation'
|
'propertyDocumentation'
|
||||||
'configSchema'
|
'configSchema'
|
||||||
|
|
|
@ -17,7 +17,7 @@ class LevelSessionHandler extends Handler
|
||||||
|
|
||||||
formatEntity: (req, document) ->
|
formatEntity: (req, document) ->
|
||||||
documentObject = super(req, document)
|
documentObject = super(req, document)
|
||||||
if req.user.isAdmin() or req.user.id is document.creator
|
if req.user.isAdmin() or req.user.id is document.creator or ('employer' in req.user.get('permissions'))
|
||||||
return documentObject
|
return documentObject
|
||||||
else
|
else
|
||||||
return _.omit documentObject, ['submittedCode','code']
|
return _.omit documentObject, ['submittedCode','code']
|
||||||
|
@ -34,6 +34,7 @@ class LevelSessionHandler extends Handler
|
||||||
|
|
||||||
hasAccessToDocument: (req, document, method=null) ->
|
hasAccessToDocument: (req, document, method=null) ->
|
||||||
return true if req.method is 'GET' and document.get('totalScore')
|
return true if req.method is 'GET' and document.get('totalScore')
|
||||||
|
return true if ('employer' in req.user.get('permissions')) and (method ? req.method).toLowerCase() is 'get'
|
||||||
super(arguments...)
|
super(arguments...)
|
||||||
|
|
||||||
module.exports = new LevelSessionHandler()
|
module.exports = new LevelSessionHandler()
|
||||||
|
|
|
@ -7,7 +7,7 @@ LevelSystemHandler = class LevelSystemHandler extends Handler
|
||||||
'description'
|
'description'
|
||||||
'code'
|
'code'
|
||||||
'js'
|
'js'
|
||||||
'language'
|
'codeLanguage'
|
||||||
'dependencies'
|
'dependencies'
|
||||||
'propertyDocumentation'
|
'propertyDocumentation'
|
||||||
'configSchema'
|
'configSchema'
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
mongoose = require('mongoose')
|
mongoose = require('mongoose')
|
||||||
Achievement = require('../achievements/Achievement')
|
Achievement = require('../achievements/Achievement')
|
||||||
EarnedAchievement = require '../achievements/EarnedAchievement'
|
EarnedAchievement = require '../achievements/EarnedAchievement'
|
||||||
User = require '../users/User'
|
|
||||||
LocalMongo = require '../../app/lib/LocalMongo'
|
LocalMongo = require '../../app/lib/LocalMongo'
|
||||||
util = require '../../app/lib/utils'
|
util = require '../../app/lib/utils'
|
||||||
log = require 'winston'
|
log = require 'winston'
|
||||||
|
@ -19,6 +18,8 @@ loadAchievements = ->
|
||||||
loadAchievements()
|
loadAchievements()
|
||||||
|
|
||||||
module.exports = AchievablePlugin = (schema, options) ->
|
module.exports = AchievablePlugin = (schema, options) ->
|
||||||
|
User = require '../users/User'
|
||||||
|
|
||||||
checkForAchievement = (doc) ->
|
checkForAchievement = (doc) ->
|
||||||
collectionName = doc.constructor.modelName
|
collectionName = doc.constructor.modelName
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
mongoose = require('mongoose')
|
mongoose = require('mongoose')
|
||||||
User = require('../users/User')
|
|
||||||
textSearch = require('mongoose-text-search')
|
textSearch = require('mongoose-text-search')
|
||||||
|
|
||||||
module.exports.MigrationPlugin = (schema, migrations) ->
|
module.exports.MigrationPlugin = (schema, migrations) ->
|
||||||
|
|
|
@ -62,7 +62,6 @@ module.exports.setup = (app) ->
|
||||||
req.logIn(user, (err) ->
|
req.logIn(user, (err) ->
|
||||||
return next(err) if (err)
|
return next(err) if (err)
|
||||||
activity = req.user.trackActivity 'login', 1
|
activity = req.user.trackActivity 'login', 1
|
||||||
console.log "updating", activity
|
|
||||||
user.update {activity: activity}, (err) ->
|
user.update {activity: activity}, (err) ->
|
||||||
return next(err) if (err)
|
return next(err) if (err)
|
||||||
res.send(UserHandler.formatEntity(req, req.user))
|
res.send(UserHandler.formatEntity(req, req.user))
|
||||||
|
|
|
@ -189,6 +189,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
return @avatar(req, res, args[0]) if args[1] is 'avatar'
|
return @avatar(req, res, args[0]) if args[1] is 'avatar'
|
||||||
return @getNamesByIDs(req, res) if args[1] is 'names'
|
return @getNamesByIDs(req, res) if args[1] is 'names'
|
||||||
return @nameToID(req, res, args[0]) if args[1] is 'nameToID'
|
return @nameToID(req, res, args[0]) if args[1] is 'nameToID'
|
||||||
|
return @getLevelSessionsForEmployer(req, res, args[0]) if args[1] is 'level.sessions' and args[2] is 'employer'
|
||||||
return @getLevelSessions(req, res, args[0]) if args[1] is 'level.sessions'
|
return @getLevelSessions(req, res, args[0]) if args[1] is 'level.sessions'
|
||||||
return @getCandidates(req, res) if args[1] is 'candidates'
|
return @getCandidates(req, res) if args[1] is 'candidates'
|
||||||
return @getEmployers(req, res) if args[1] is 'employers'
|
return @getEmployers(req, res) if args[1] is 'employers'
|
||||||
|
@ -227,9 +228,18 @@ UserHandler = class UserHandler extends Handler
|
||||||
res.redirect photoURL
|
res.redirect photoURL
|
||||||
res.end()
|
res.end()
|
||||||
|
|
||||||
|
getLevelSessionsForEmployer: (req, res, userID) ->
|
||||||
|
return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions'))
|
||||||
|
query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']}
|
||||||
|
projection = 'levelName levelID team playtime codeLanguage submitted' # code totalScore
|
||||||
|
LevelSession.find(query).select(projection).exec (err, documents) =>
|
||||||
|
return @sendDatabaseError(res, err) if err
|
||||||
|
documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents)
|
||||||
|
@sendSuccess(res, documents)
|
||||||
|
|
||||||
getLevelSessions: (req, res, userID) ->
|
getLevelSessions: (req, res, userID) ->
|
||||||
return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin()
|
return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin()
|
||||||
query = {'creator': userID}
|
query = creator: userID
|
||||||
projection = null
|
projection = null
|
||||||
if req.query.project
|
if req.query.project
|
||||||
projection = {}
|
projection = {}
|
||||||
|
|
|
@ -93,7 +93,10 @@ sendMain = (req, res) ->
|
||||||
log.error "Error modifying main.html: #{err}" if err
|
log.error "Error modifying main.html: #{err}" if err
|
||||||
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
|
# insert the user object directly into the html so the application can have it immediately. Sanitize </script>
|
||||||
data = data.replace('"userObjectTag"', JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/'))
|
data = data.replace('"userObjectTag"', JSON.stringify(UserHandler.formatEntity(req, req.user)).replace(/\//g, '\\/'))
|
||||||
res.send data
|
res.header "Cache-Control", "no-cache, no-store, must-revalidate"
|
||||||
|
res.header "Pragma", "no-cache"
|
||||||
|
res.header "Expires", 0
|
||||||
|
res.send 200, data
|
||||||
|
|
||||||
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
setupFacebookCrossDomainCommunicationRoute = (app) ->
|
||||||
app.get '/channel.html', (req, res) ->
|
app.get '/channel.html', (req, res) ->
|
||||||
|
|
80
test/app/lib/FacebookHandler.spec.coffee
Normal file
80
test/app/lib/FacebookHandler.spec.coffee
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
FacebookHandler = require 'lib/FacebookHandler'
|
||||||
|
|
||||||
|
mockAuthEvent =
|
||||||
|
response:
|
||||||
|
authResponse:
|
||||||
|
accessToken: "aksdhjflkqjrj245234b52k345q344le4j4k5l45j45s4dkljvdaskl"
|
||||||
|
userID: "4301938"
|
||||||
|
expiresIn: 5138
|
||||||
|
signedRequest: "akjsdhfjkhea.3423nkfkdsejnfkd"
|
||||||
|
status: "connected"
|
||||||
|
|
||||||
|
# Whatev, it's all public info anyway
|
||||||
|
mockMe =
|
||||||
|
id: "4301938"
|
||||||
|
email: "scott@codecombat.com"
|
||||||
|
first_name: "Scott"
|
||||||
|
gender: "male"
|
||||||
|
last_name: "Erickson"
|
||||||
|
link: "https://www.facebook.com/scott.erickson.779"
|
||||||
|
locale: "en_US"
|
||||||
|
name: "Scott Erickson"
|
||||||
|
timezone: -7
|
||||||
|
updated_time: "2014-05-21T04:58:06+0000"
|
||||||
|
username: "scott.erickson.779"
|
||||||
|
verified: true
|
||||||
|
work: [
|
||||||
|
{
|
||||||
|
employer:
|
||||||
|
id: "167559910060759"
|
||||||
|
name: "CodeCombat"
|
||||||
|
|
||||||
|
location:
|
||||||
|
id: "114952118516947"
|
||||||
|
name: "San Francisco, California"
|
||||||
|
|
||||||
|
start_date: "2013-02-28"
|
||||||
|
}
|
||||||
|
{
|
||||||
|
end_date: "2013-01-31"
|
||||||
|
employer:
|
||||||
|
id: "39198748555"
|
||||||
|
name: "Skritter"
|
||||||
|
|
||||||
|
location:
|
||||||
|
id: "106109576086811"
|
||||||
|
name: "Oberlin, Ohio"
|
||||||
|
|
||||||
|
start_date: "2008-06-01"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
window.FB ?= {
|
||||||
|
api: ->
|
||||||
|
}
|
||||||
|
|
||||||
|
describe 'lib/FacebookHandler.coffee', ->
|
||||||
|
it 'on facebook-logged-in, gets data from FB and sends a patch to the server', ->
|
||||||
|
me.clear({silent:true})
|
||||||
|
me.markToRevert()
|
||||||
|
me.set({_id: '12345'})
|
||||||
|
|
||||||
|
spyOn FB, 'api'
|
||||||
|
|
||||||
|
new FacebookHandler()
|
||||||
|
Backbone.Mediator.publish 'facebook-logged-in', mockAuthEvent
|
||||||
|
|
||||||
|
expect(FB.api).toHaveBeenCalled()
|
||||||
|
apiArgs = FB.api.calls.argsFor(0)
|
||||||
|
expect(apiArgs[0]).toBe('/me')
|
||||||
|
apiArgs[1](mockMe) # sending the 'response'
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request).toBeDefined()
|
||||||
|
params = JSON.parse request.params
|
||||||
|
expect(params.firstName).toBe(mockMe.first_name)
|
||||||
|
expect(params.lastName).toBe(mockMe.last_name)
|
||||||
|
expect(params.gender).toBe(mockMe.gender)
|
||||||
|
expect(params.email).toBe(mockMe.email)
|
||||||
|
expect(params.facebookID).toBe(mockMe.id)
|
||||||
|
expect(request.method).toBe('PATCH')
|
||||||
|
expect(_.string.startsWith(request.url, '/db/user/12345')).toBeTruthy()
|
84
test/app/models/CocoModel.spec.coffee
Normal file
84
test/app/models/CocoModel.spec.coffee
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
CocoModel = require 'models/CocoModel'
|
||||||
|
|
||||||
|
class BlandClass extends CocoModel
|
||||||
|
@className: 'Bland'
|
||||||
|
@schema: {
|
||||||
|
type: 'object'
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
number: {type: 'number'}
|
||||||
|
object: {type: 'object'}
|
||||||
|
string: {type: 'string'}
|
||||||
|
_id: {type: 'string'}
|
||||||
|
}
|
||||||
|
urlRoot: '/db/bland'
|
||||||
|
|
||||||
|
describe 'CocoModel', ->
|
||||||
|
describe 'save', ->
|
||||||
|
|
||||||
|
it 'saves to db/<urlRoot>', ->
|
||||||
|
b = new BlandClass({})
|
||||||
|
res = b.save()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(res).toBeDefined()
|
||||||
|
expect(request.url).toBe(b.urlRoot)
|
||||||
|
expect(request.method).toBe('POST')
|
||||||
|
|
||||||
|
it 'does not save if the data is invalid based on the schema', ->
|
||||||
|
b = new BlandClass({number: 'NaN'})
|
||||||
|
res = b.save()
|
||||||
|
expect(res).toBe(false)
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request).toBeUndefined()
|
||||||
|
|
||||||
|
it 'uses PUT when _id is included', ->
|
||||||
|
b = new BlandClass({_id: 'test'})
|
||||||
|
b.save()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request.method).toBe('PUT')
|
||||||
|
|
||||||
|
describe 'patch', ->
|
||||||
|
it 'PATCHes only properties that have changed', ->
|
||||||
|
b = new BlandClass({_id: 'test', number:1})
|
||||||
|
b.loaded = true
|
||||||
|
b.set('string', 'string')
|
||||||
|
b.patch()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
params = JSON.parse request.params
|
||||||
|
expect(params.string).toBeDefined()
|
||||||
|
expect(params.number).toBeUndefined()
|
||||||
|
|
||||||
|
it 'collates all changes made over several sets', ->
|
||||||
|
b = new BlandClass({_id: 'test', number:1})
|
||||||
|
b.loaded = true
|
||||||
|
b.set('string', 'string')
|
||||||
|
b.set('object', {4:5})
|
||||||
|
b.patch()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
params = JSON.parse request.params
|
||||||
|
expect(params.string).toBeDefined()
|
||||||
|
expect(params.object).toBeDefined()
|
||||||
|
expect(params.number).toBeUndefined()
|
||||||
|
|
||||||
|
it 'does not include data from previous patches', ->
|
||||||
|
b = new BlandClass({_id: 'test', number:1})
|
||||||
|
b.loaded = true
|
||||||
|
b.set('object', {1:2})
|
||||||
|
b.patch()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
attrs = JSON.stringify(b.attributes) # server responds with all
|
||||||
|
request.response({status: 200, responseText: attrs})
|
||||||
|
|
||||||
|
b.set('number', 3)
|
||||||
|
b.patch()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
params = JSON.parse request.params
|
||||||
|
expect(params.object).toBeUndefined()
|
||||||
|
|
||||||
|
it 'does nothing when there\'s nothing to patch', ->
|
||||||
|
b = new BlandClass({_id: 'test', number:1})
|
||||||
|
b.loaded = true
|
||||||
|
b.set('number', 1)
|
||||||
|
b.patch()
|
||||||
|
request = jasmine.Ajax.requests.mostRecent()
|
||||||
|
expect(request).toBeUndefined()
|
|
@ -9,6 +9,10 @@ jasmine.getEnv().addReporter(new jasmine.SpecReporter({
|
||||||
displaySuccessfulSpec: true,
|
displaySuccessfulSpec: true,
|
||||||
displayFailedSpec: true
|
displayFailedSpec: true
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
rep = new jasmine.JsApiReporter()
|
||||||
|
jasmine.getEnv().addReporter(rep)
|
||||||
|
|
||||||
GLOBAL._ = require('lodash')
|
GLOBAL._ = require('lodash')
|
||||||
_.str = require('underscore.string')
|
_.str = require('underscore.string')
|
||||||
_.mixin(_.str.exports())
|
_.mixin(_.str.exports())
|
||||||
|
@ -149,3 +153,13 @@ _drop = (done) ->
|
||||||
chunks = mongoose.connection.db.collection('media.chunks')
|
chunks = mongoose.connection.db.collection('media.chunks')
|
||||||
chunks.remove {}, ->
|
chunks.remove {}, ->
|
||||||
done()
|
done()
|
||||||
|
|
||||||
|
tickInterval = null
|
||||||
|
tick = ->
|
||||||
|
# When you want jasmine-node to exit after running the tests,
|
||||||
|
# you have to close the connection first.
|
||||||
|
if rep.finished
|
||||||
|
mongoose.disconnect()
|
||||||
|
clearTimeout tickInterval
|
||||||
|
|
||||||
|
tickInterval = setInterval tick, 1000
|
|
@ -6,9 +6,8 @@ urlLogin = getURL('/auth/login')
|
||||||
urlReset = getURL('/auth/reset')
|
urlReset = getURL('/auth/reset')
|
||||||
|
|
||||||
describe '/auth/whoami', ->
|
describe '/auth/whoami', ->
|
||||||
http = require 'http'
|
|
||||||
it 'returns 200', (done) ->
|
it 'returns 200', (done) ->
|
||||||
http.get(getURL('/auth/whoami'), (response) ->
|
request.get(getURL('/auth/whoami'), (err, response) ->
|
||||||
expect(response).toBeDefined()
|
expect(response).toBeDefined()
|
||||||
expect(response.statusCode).toBe(200)
|
expect(response.statusCode).toBe(200)
|
||||||
done()
|
done()
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
require '../common'
|
require '../common'
|
||||||
|
|
||||||
describe '/file', ->
|
# Doesn't work on Travis. Need to figure out why, probably by having the
|
||||||
|
# url not depend on some external resource.
|
||||||
|
|
||||||
|
xdescribe '/file', ->
|
||||||
url = getURL('/file')
|
url = getURL('/file')
|
||||||
files = []
|
files = []
|
||||||
options = {
|
options = {
|
||||||
uri:url
|
uri:url
|
||||||
json: {
|
json: {
|
||||||
url: 'http://scotterickson.info/images/where-are-you.jpg'
|
# url: 'http://scotterickson.info/images/where-are-you.jpg'
|
||||||
|
url: 'http://fc07.deviantart.net/fs37/f/2008/283/5/1/Chu_Chu_Pikachu_by_angelishi.gif'
|
||||||
filename: 'where-are-you.jpg'
|
filename: 'where-are-you.jpg'
|
||||||
mimetype: 'image/jpeg'
|
mimetype: 'image/jpeg'
|
||||||
description: 'None!'
|
description: 'None!'
|
||||||
|
@ -20,7 +24,8 @@ describe '/file', ->
|
||||||
filename: 'ittybitty.data'
|
filename: 'ittybitty.data'
|
||||||
mimetype: 'application/octet-stream'
|
mimetype: 'application/octet-stream'
|
||||||
description: 'rando-info'
|
description: 'rando-info'
|
||||||
my_buffer_url: 'http://scotterickson.info/images/where-are-you.jpg'
|
# my_buffer_url: 'http://scotterickson.info/images/where-are-you.jpg'
|
||||||
|
my_buffer_url: 'http://fc07.deviantart.net/fs37/f/2008/283/5/1/Chu_Chu_Pikachu_by_angelishi.gif'
|
||||||
}
|
}
|
||||||
|
|
||||||
it 'preparing test : deletes all the files first', (done) ->
|
it 'preparing test : deletes all the files first', (done) ->
|
||||||
|
|
|
@ -18,13 +18,3 @@ describe 'Level', ->
|
||||||
level.save (err) ->
|
level.save (err) ->
|
||||||
throw err if err
|
throw err if err
|
||||||
done()
|
done()
|
||||||
|
|
||||||
it 'loads again after being saved', (done) ->
|
|
||||||
url = getURL('/db/level/'+level._id)
|
|
||||||
request.get url, (err, res, body) ->
|
|
||||||
expect(res.statusCode).toBe(200)
|
|
||||||
sameLevel = JSON.parse(body)
|
|
||||||
expect(sameLevel.name).toEqual(level.get 'name')
|
|
||||||
expect(sameLevel.description).toEqual(level.get 'description')
|
|
||||||
expect(sameLevel.permissions).toEqual(simplePermissions)
|
|
||||||
done()
|
|
||||||
|
|
Loading…
Reference in a new issue