mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-29 18:45:48 -05:00
Merge branch 'master' into production
This commit is contained in:
commit
416cd3b894
14 changed files with 104 additions and 39 deletions
|
@ -236,6 +236,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
return requests[index];
|
return requests[index];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.all = function() {
|
||||||
|
return requests.slice(0);
|
||||||
|
};
|
||||||
|
|
||||||
this.filter = function(url_to_match) {
|
this.filter = function(url_to_match) {
|
||||||
if (requests.length == 0) return [];
|
if (requests.length == 0) return [];
|
||||||
var matching_requests = [];
|
var matching_requests = [];
|
||||||
|
|
|
@ -43,7 +43,9 @@ block content
|
||||||
i.icon-eye-close
|
i.icon-eye-close
|
||||||
span(data-i18n='account_profile.not_featured') Not Featured
|
span(data-i18n='account_profile.not_featured') Not Featured
|
||||||
if me.isAdmin() && !myProfile
|
if me.isAdmin() && !myProfile
|
||||||
button.btn.edit-settings-button#enter-espionage-mode 007
|
button.btn#enter-espionage-mode 007
|
||||||
|
if me.isAdmin()
|
||||||
|
button.btn#open-model-modal Raw
|
||||||
|
|
||||||
if profile && allowedToViewJobProfile
|
if profile && allowedToViewJobProfile
|
||||||
div(class="job-profile-container" + (editing ? " editable-profile" : ""))
|
div(class="job-profile-container" + (editing ? " editable-profile" : ""))
|
||||||
|
|
|
@ -4,6 +4,8 @@ block modal-header
|
||||||
|
|
||||||
block modal-body-content
|
block modal-body-content
|
||||||
for model in models
|
for model in models
|
||||||
|
.model-container(data-model-id=model.id)
|
||||||
h3= model.type() + ': ' + model.id
|
h3= model.type() + ': ' + model.id
|
||||||
.model-treema(data-model-id=model.id)
|
.model-treema(data-model-id=model.id)
|
||||||
|
btn.btn.btn-success.save-model(data-i18n="common.save") Save
|
||||||
hr
|
hr
|
||||||
|
|
|
@ -8,6 +8,7 @@ JobProfileContactView = require 'views/modal/job_profile_contact_modal'
|
||||||
JobProfileView = require 'views/account/job_profile_view'
|
JobProfileView = require 'views/account/job_profile_view'
|
||||||
UserRemark = require 'models/UserRemark'
|
UserRemark = require 'models/UserRemark'
|
||||||
forms = require 'lib/forms'
|
forms = require 'lib/forms'
|
||||||
|
ModelModal = require 'views/modal/model_modal'
|
||||||
|
|
||||||
class LevelSessionsCollection extends CocoCollection
|
class LevelSessionsCollection extends CocoCollection
|
||||||
url: -> "/db/user/#{@userID}/level.sessions/employer"
|
url: -> "/db/user/#{@userID}/level.sessions/employer"
|
||||||
|
@ -37,6 +38,7 @@ module.exports = class ProfileView extends View
|
||||||
'click #save-notes-button': 'onJobProfileNotesChanged'
|
'click #save-notes-button': 'onJobProfileNotesChanged'
|
||||||
'click #contact-candidate': 'onContactCandidate'
|
'click #contact-candidate': 'onContactCandidate'
|
||||||
'click #enter-espionage-mode': 'enterEspionageMode'
|
'click #enter-espionage-mode': 'enterEspionageMode'
|
||||||
|
'click #open-model-modal': 'openModelModal'
|
||||||
'click .editable-profile .profile-photo': 'onEditProfilePhoto'
|
'click .editable-profile .profile-photo': 'onEditProfilePhoto'
|
||||||
'click .editable-profile .project-image': 'onEditProjectImage'
|
'click .editable-profile .project-image': 'onEditProjectImage'
|
||||||
'click .editable-profile .editable-display': 'onEditSection'
|
'click .editable-profile .editable-display': 'onEditSection'
|
||||||
|
@ -252,7 +254,7 @@ module.exports = class ProfileView extends View
|
||||||
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
|
||||||
if @sessions
|
if @sessions
|
||||||
context.sessions = (s.attributes for s in @sessions.models when (s.get('submitted') or s.get('level-id') is 'gridmancer'))
|
context.sessions = (s.attributes for s in @sessions.models when (s.get('submitted') or (s.get('levelID') is 'gridmancer') and s.get('code')?.thoktar?.plan?.length isnt 942)) # no default code
|
||||||
context.sessions.sort (a, b) -> (b.playtime ? 0) - (a.playtime ? 0)
|
context.sessions.sort (a, b) -> (b.playtime ? 0) - (a.playtime ? 0)
|
||||||
else
|
else
|
||||||
context.sessions = []
|
context.sessions = []
|
||||||
|
@ -340,6 +342,9 @@ module.exports = class ProfileView extends View
|
||||||
espionageSuccess: (model) ->
|
espionageSuccess: (model) ->
|
||||||
window.location.reload()
|
window.location.reload()
|
||||||
|
|
||||||
|
openModelModal: (e) ->
|
||||||
|
@openModalView new ModelModal models: [@user]
|
||||||
|
|
||||||
onJobProfileNotesChanged: (e) =>
|
onJobProfileNotesChanged: (e) =>
|
||||||
notes = @$el.find("#job-profile-notes").val()
|
notes = @$el.find("#job-profile-notes").val()
|
||||||
@user.set 'jobProfileNotes', notes
|
@user.set 'jobProfileNotes', notes
|
||||||
|
|
|
@ -25,6 +25,7 @@ module.exports = class LevelComponentEditView extends View
|
||||||
super options
|
super options
|
||||||
@levelComponent = @supermodel.getModelByOriginalAndMajorVersion LevelComponent, options.original, options.majorVersion or 0
|
@levelComponent = @supermodel.getModelByOriginalAndMajorVersion LevelComponent, options.original, options.majorVersion or 0
|
||||||
console.log "Couldn't get levelComponent for", options, "from", @supermodel.models unless @levelComponent
|
console.log "Couldn't get levelComponent for", options, "from", @supermodel.models unless @levelComponent
|
||||||
|
@onEditorChange = _.debounce @onEditorChange, 1500
|
||||||
|
|
||||||
getRenderData: (context={}) ->
|
getRenderData: (context={}) ->
|
||||||
context = super(context)
|
context = super(context)
|
||||||
|
@ -95,6 +96,7 @@ module.exports = class LevelComponentEditView extends View
|
||||||
@editor.on('change', @onEditorChange)
|
@editor.on('change', @onEditorChange)
|
||||||
|
|
||||||
onEditorChange: =>
|
onEditorChange: =>
|
||||||
|
return if @destroyed
|
||||||
@levelComponent.set 'code', @editor.getValue()
|
@levelComponent.set 'code', @editor.getValue()
|
||||||
Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent
|
Backbone.Mediator.publish 'level-component-edited', levelComponent: @levelComponent
|
||||||
null
|
null
|
||||||
|
|
|
@ -150,12 +150,6 @@ module.exports = class CocoView extends Backbone.View
|
||||||
@lastToggleModalCall = 0
|
@lastToggleModalCall = 0
|
||||||
|
|
||||||
toggleModal: (e) ->
|
toggleModal: (e) ->
|
||||||
if new Date().getTime() - CocoView.lastToggleModalCall < 5
|
|
||||||
# Defensive move. This function has had a history of messing things up.
|
|
||||||
console.error 'toggleModal is getting called too often!'
|
|
||||||
return
|
|
||||||
CocoView.lastToggleModalCall = new Date().getTime()
|
|
||||||
|
|
||||||
if $(e.currentTarget).prop('target') is '_blank'
|
if $(e.currentTarget).prop('target') is '_blank'
|
||||||
return true
|
return true
|
||||||
# special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value.
|
# special handler for opening modals that are dynamically loaded, rather than static in the page. It works (or should work) like Bootstrap's modals, except use coco-modal for the data-toggle value.
|
||||||
|
@ -163,6 +157,7 @@ module.exports = class CocoView extends Backbone.View
|
||||||
return unless elem.data('toggle') is 'coco-modal'
|
return unless elem.data('toggle') is 'coco-modal'
|
||||||
target = elem.data('target')
|
target = elem.data('target')
|
||||||
view = application.router.getView(target, '_modal') # could set up a system for loading cached modals, if told to
|
view = application.router.getView(target, '_modal') # could set up a system for loading cached modals, if told to
|
||||||
|
e.stopPropagation()
|
||||||
@openModalView(view)
|
@openModalView(view)
|
||||||
|
|
||||||
openModalView: (modalView, softly=false) ->
|
openModalView: (modalView, softly=false) ->
|
||||||
|
|
|
@ -6,6 +6,8 @@ module.exports = class ModelModal extends View
|
||||||
template: template
|
template: template
|
||||||
plain: true
|
plain: true
|
||||||
|
|
||||||
|
events: 'click .save-model': 'onSaveModel'
|
||||||
|
|
||||||
constructor: (options) ->
|
constructor: (options) ->
|
||||||
super options
|
super options
|
||||||
@models = options.models
|
@models = options.models
|
||||||
|
@ -20,6 +22,7 @@ module.exports = class ModelModal extends View
|
||||||
|
|
||||||
afterRender: ->
|
afterRender: ->
|
||||||
return unless @supermodel.finished()
|
return unless @supermodel.finished()
|
||||||
|
@modelTreemas = {}
|
||||||
for model in @models
|
for model in @models
|
||||||
data = $.extend true, {}, model.attributes
|
data = $.extend true, {}, model.attributes
|
||||||
schema = $.extend true, {}, model.schema()
|
schema = $.extend true, {}, model.schema()
|
||||||
|
@ -31,6 +34,7 @@ module.exports = class ModelModal extends View
|
||||||
modelTreema?.build()
|
modelTreema?.build()
|
||||||
modelTreema?.open()
|
modelTreema?.open()
|
||||||
@openTastyTreemas modelTreema, model
|
@openTastyTreemas modelTreema, model
|
||||||
|
@modelTreemas[model.id] = modelTreema
|
||||||
|
|
||||||
openTastyTreemas: (modelTreema, model) ->
|
openTastyTreemas: (modelTreema, model) ->
|
||||||
# To save on quick inspection, let's auto-open the properties we're most likely to want to see.
|
# To save on quick inspection, let's auto-open the properties we're most likely to want to see.
|
||||||
|
@ -45,3 +49,23 @@ module.exports = class ModelModal extends View
|
||||||
}[team]
|
}[team]
|
||||||
for dessert in desserts
|
for dessert in desserts
|
||||||
child.childrenTreemas[dessert]?.open()
|
child.childrenTreemas[dessert]?.open()
|
||||||
|
|
||||||
|
onSaveModel: (e) ->
|
||||||
|
container = $(e.target).closest('.model-container')
|
||||||
|
model = _.find @models, id: container.data('model-id')
|
||||||
|
treema = @modelTreemas[model.id]
|
||||||
|
for key, val of treema.data when not _.isEqual val, model.get key
|
||||||
|
console.log "Updating", key, "from", model.get(key), "to", val
|
||||||
|
model.set key, val
|
||||||
|
for key, val of model.attributes when treema.get(key) is undefined and not _.string.startsWith key, '_'
|
||||||
|
console.log "Deleting", key, "which was", val, "but man, that ain't going to work, now is it?"
|
||||||
|
model.unset key
|
||||||
|
if errors = model.validate()
|
||||||
|
return console.warn model, "failed validation with errors:", errors
|
||||||
|
return unless res = model.patch()
|
||||||
|
res.error =>
|
||||||
|
return if @destroyed
|
||||||
|
console.error model, "failed to save with error:", res.responseText
|
||||||
|
res.success (model, response, options) =>
|
||||||
|
return if @destroyed
|
||||||
|
@hide()
|
||||||
|
|
|
@ -18,23 +18,19 @@ module.exports = class Spell
|
||||||
@supermodel = options.supermodel
|
@supermodel = options.supermodel
|
||||||
@skipProtectAPI = options.skipProtectAPI
|
@skipProtectAPI = options.skipProtectAPI
|
||||||
@worker = options.worker
|
@worker = options.worker
|
||||||
p = options.programmableMethod
|
|
||||||
|
|
||||||
|
p = options.programmableMethod
|
||||||
|
@languages = p.languages ? {}
|
||||||
|
@languages.javascript ?= p.source
|
||||||
@name = p.name
|
@name = p.name
|
||||||
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
|
@permissions = read: p.permissions?.read ? [], readwrite: p.permissions?.readwrite ? [] # teams
|
||||||
teamSpells = @session.get('teamSpells')
|
@setLanguage if @canWrite() then options.language else 'javascript'
|
||||||
team = @session.get('team') ? 'humans'
|
@useTranspiledCode = @shouldUseTranspiledCode()
|
||||||
@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)
|
|
||||||
if @useTranspiledCode
|
@source = @originalSource
|
||||||
console.log "#{@spellKey} is using transpiled code because permissions.readwrite is #{@permissions.readwrite}
|
|
||||||
#{if @spectateView then ', we are spectating' else ''}
|
|
||||||
#{if teamSpells and not _.contains(teamSpells[team], @spellKey) then ', teamSpells[' + team + '] does not have ' + @spellKey + ' (just ' + teamSpells[team] + ')' else ''}
|
|
||||||
#{if @session.get('creator') isnt me.id then ', and the session was created by ' + @session.get('creator') + ' but I am ' + me.id else ''}"
|
|
||||||
@source = @originalSource = p.source
|
|
||||||
@parameters = p.parameters
|
@parameters = p.parameters
|
||||||
if @permissions.readwrite.length and sessionSource = @session.getSourceFor(@spellKey)
|
if @permissions.readwrite.length and sessionSource = @session.getSourceFor(@spellKey)
|
||||||
@source = sessionSource
|
@source = sessionSource
|
||||||
@language = if @canWrite() then options.language else 'javascript'
|
|
||||||
@thangs = {}
|
@thangs = {}
|
||||||
@view = new SpellView {spell: @, session: @session, worker: @worker}
|
@view = new SpellView {spell: @, session: @session, worker: @worker}
|
||||||
@view.render() # Get it ready and code loaded in advance
|
@view.render() # Get it ready and code loaded in advance
|
||||||
|
@ -49,6 +45,9 @@ module.exports = class Spell
|
||||||
@thangs = null
|
@thangs = null
|
||||||
@worker = null
|
@worker = null
|
||||||
|
|
||||||
|
setLanguage: (@language) ->
|
||||||
|
@originalSource = @languages[language] ? @languages.javascript
|
||||||
|
|
||||||
addThang: (thang) ->
|
addThang: (thang) ->
|
||||||
if @thangs[thang.id]
|
if @thangs[thang.id]
|
||||||
@thangs[thang.id].thang = thang
|
@thangs[thang.id].thang = thang
|
||||||
|
@ -155,3 +154,14 @@ module.exports = class Spell
|
||||||
|
|
||||||
toString: ->
|
toString: ->
|
||||||
"<Spell: #{@spellKey}>"
|
"<Spell: #{@spellKey}>"
|
||||||
|
|
||||||
|
shouldUseTranspiledCode: ->
|
||||||
|
# Determine whether this code has already been transpiled, or whether it's raw source needing transpilation.
|
||||||
|
return false unless @permissions.readwrite.length # Only player-writable code will be stored transpiled.
|
||||||
|
return true if @spectateView # Use transpiled code for both teams if we're just spectating.
|
||||||
|
teamSpells = @session.get('teamSpells')
|
||||||
|
team = @session.get('team') ? 'humans'
|
||||||
|
return true if teamSpells and not _.contains(teamSpells[team], @spellKey) # Use transpiled for enemy spells.
|
||||||
|
# Players without permissions can't view the raw code.
|
||||||
|
return true if @session.get('creator') isnt me.id and not (me.isAdmin() or 'employer' in me.get('permissions'))
|
||||||
|
false
|
||||||
|
|
|
@ -619,8 +619,11 @@ module.exports = class SpellView extends View
|
||||||
@ace.setKeyboardHandler @keyBindings[aceConfig.keyBindings ? 'default']
|
@ace.setKeyboardHandler @keyBindings[aceConfig.keyBindings ? 'default']
|
||||||
|
|
||||||
onChangeLanguage: (e) ->
|
onChangeLanguage: (e) ->
|
||||||
if @spell.canWrite()
|
return unless @spell.canWrite()
|
||||||
@aceSession.setMode @editModes[e.language]
|
@aceSession.setMode @editModes[e.language]
|
||||||
|
wasDefault = @getSource() is @spell.originalSource
|
||||||
|
@spell.setLanguage e.language
|
||||||
|
@reloadCode true if wasDefault
|
||||||
|
|
||||||
dismiss: ->
|
dismiss: ->
|
||||||
@spell.hasChangedSignificantly @getSource(), null, (hasChanged) =>
|
@spell.hasChangedSignificantly @getSource(), null, (hasChanged) =>
|
||||||
|
|
|
@ -58,7 +58,13 @@ checkDependencies deps[@] basicDependenciesErrorHandling
|
||||||
if command -v node >/dev/null 2>&1; then
|
if command -v node >/dev/null 2>&1; then
|
||||||
checkNodeVersion
|
checkNodeVersion
|
||||||
fi
|
fi
|
||||||
#install git repository
|
|
||||||
git clone $repositoryUrl coco
|
#check if a git repository already exists here
|
||||||
#python ./coco/scripts/devSetup/setup.py
|
if [ -d .git ]; then
|
||||||
echo "Now copy and paste 'sudo python ./coco/scripts/devSetup/setup.py' into the terminal!"
|
echo "A git repository already exists here!"
|
||||||
|
else
|
||||||
|
#install git repository
|
||||||
|
git clone $repositoryUrl coco
|
||||||
|
#python ./coco/scripts/devSetup/setup.py
|
||||||
|
echo "Now copy and paste 'sudo python ./coco/scripts/devSetup/setup.py' into the terminal!"
|
||||||
|
fi
|
||||||
|
|
|
@ -33,6 +33,8 @@ class SystemConfiguration(object):
|
||||||
return 64
|
return 64
|
||||||
else:
|
else:
|
||||||
if self.operating_system == u"mac":
|
if self.operating_system == u"mac":
|
||||||
|
if os.uname()[4] == u"x86_64":
|
||||||
|
return 64
|
||||||
raise NotSupportedError(u"Your processor is determined to have a maxSize of" + str(sys.maxsize) +
|
raise NotSupportedError(u"Your processor is determined to have a maxSize of" + str(sys.maxsize) +
|
||||||
u",\n which doesn't correspond with a 64-bit architecture.")
|
u",\n which doesn't correspond with a 64-bit architecture.")
|
||||||
return 32
|
return 32
|
||||||
|
|
|
@ -24,7 +24,7 @@ candidateProperties = [
|
||||||
|
|
||||||
UserHandler = class UserHandler extends Handler
|
UserHandler = class UserHandler extends Handler
|
||||||
modelClass: User
|
modelClass: User
|
||||||
|
jsonSchema: schema
|
||||||
editableProperties: [
|
editableProperties: [
|
||||||
'name', 'photoURL', 'password', 'anonymous', 'wizardColor1', 'volume',
|
'name', 'photoURL', 'password', 'anonymous', 'wizardColor1', 'volume',
|
||||||
'firstName', 'lastName', 'gender', 'facebookID', 'gplusID', 'emails',
|
'firstName', 'lastName', 'gender', 'facebookID', 'gplusID', 'emails',
|
||||||
|
@ -32,15 +32,11 @@ UserHandler = class UserHandler extends Handler
|
||||||
'wizard', 'aceConfig', 'autocastDelay', 'lastLevel', 'jobProfile'
|
'wizard', 'aceConfig', 'autocastDelay', 'lastLevel', 'jobProfile'
|
||||||
]
|
]
|
||||||
|
|
||||||
jsonSchema: schema
|
|
||||||
|
|
||||||
constructor: ->
|
|
||||||
super(arguments...)
|
|
||||||
@editableProperties.push('permissions') unless config.isProduction
|
|
||||||
|
|
||||||
getEditableProperties: (req, document) ->
|
getEditableProperties: (req, document) ->
|
||||||
props = super req, document
|
props = super req, document
|
||||||
props.push 'jobProfileApproved', 'jobProfileNotes' if req.user.isAdmin()
|
props.push 'permissions' unless config.isProduction
|
||||||
|
props.push 'jobProfileApproved', 'jobProfileNotes' if req.user.isAdmin() # Admins naturally edit these
|
||||||
|
props.push privateProperties... if req.user.isAdmin() # Admins are mad with power
|
||||||
props
|
props
|
||||||
|
|
||||||
formatEntity: (req, document) ->
|
formatEntity: (req, document) ->
|
||||||
|
@ -233,7 +229,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
getLevelSessionsForEmployer: (req, res, userID) ->
|
getLevelSessionsForEmployer: (req, res, userID) ->
|
||||||
return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions'))
|
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']}
|
query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']}
|
||||||
projection = 'levelName levelID team playtime codeLanguage submitted' # code totalScore
|
projection = 'levelName levelID team playtime codeLanguage submitted code totalScore'
|
||||||
LevelSession.find(query).select(projection).exec (err, documents) =>
|
LevelSession.find(query).select(projection).exec (err, documents) =>
|
||||||
return @sendDatabaseError(res, err) if err
|
return @sendDatabaseError(res, err) if err
|
||||||
documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents)
|
documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents)
|
||||||
|
@ -344,7 +340,7 @@ UserHandler = class UserHandler extends Handler
|
||||||
|
|
||||||
getEmployers: (req, res) ->
|
getEmployers: (req, res) ->
|
||||||
return @sendUnauthorizedError(res) unless req.user.isAdmin()
|
return @sendUnauthorizedError(res) unless req.user.isAdmin()
|
||||||
query = {employerAt: {$exists: true}}
|
query = {employerAt: {$exists: true, $ne: ''}}
|
||||||
selection = 'name firstName lastName email activity signedEmployerAgreement photoURL employerAt'
|
selection = 'name firstName lastName email activity signedEmployerAgreement photoURL employerAt'
|
||||||
User.find(query).select(selection).lean().exec (err, documents) =>
|
User.find(query).select(selection).lean().exec (err, documents) =>
|
||||||
return @sendDatabaseError res, err if err
|
return @sendDatabaseError res, err if err
|
||||||
|
|
14
test/app/views/editor/level/EditorLevelView.spec.coffee
Normal file
14
test/app/views/editor/level/EditorLevelView.spec.coffee
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
EditorLevelView = require 'views/editor/level/edit'
|
||||||
|
|
||||||
|
emptyLevel = {"_id":"53a0a1e2d9048dbc3a793c81","name":"Emptiness","description":"Tis nothing..","documentation":{"generalArticles":[],"specificArticles":[]},"scripts":[],"thangs":[],"systems":[],"victory":{},"version":{"minor":0,"major":0,"isLatestMajor":true,"isLatestMinor":true},"index":"5388f9ac9a904d0000d94f87","slug":"emptiness","creator":"5388f9ac9a904d0000d94f87","original":"53a0a1e2d9048dbc3a793c81","watchers":["5388f9ac9a904d0000d94f87"],"__v":0,"created":"2014-06-17T20:15:30.207Z","permissions":[{"access":"owner","target":"5388f9ac9a904d0000d94f87"}]}
|
||||||
|
|
||||||
|
describe 'EditorLevelView', ->
|
||||||
|
describe 'revert button', ->
|
||||||
|
it 'opens just one modal when you click it', ->
|
||||||
|
view = new EditorLevelView({}, 'something')
|
||||||
|
request = jasmine.Ajax.requests.first()
|
||||||
|
request.response {status:200, responseText: JSON.stringify(emptyLevel)}
|
||||||
|
view.render()
|
||||||
|
spyOn(view, 'openModalView')
|
||||||
|
view.$el.find('#revert-button').click()
|
||||||
|
expect(view.openModalView.calls.count()).toBe(1)
|
Loading…
Reference in a new issue