mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2025-02-17 00:40:56 -05:00
Implement HeroSelectModal for demo flow
Add Campaign factory First basic tests for HeroSelectModal in demo flow Implement HeroSelectModal for demo flow Improve tests Disable empty test Fix text inconsistency around 'me' Just listen once Add HeroSelectModal events test Don't reuse destroyed modal Fix inconsistent modal close behavior Fix tests
This commit is contained in:
parent
7cd49b438b
commit
fd45c9d473
8 changed files with 111 additions and 2 deletions
|
@ -97,6 +97,7 @@ module.exports = TestView = class TestView extends RootView
|
|||
|
||||
jasmine.Ajax.install()
|
||||
beforeEach ->
|
||||
me.clear()
|
||||
jasmine.Ajax.requests.reset()
|
||||
Backbone.Mediator.init()
|
||||
Backbone.Mediator.setValidationEnabled false
|
||||
|
|
|
@ -222,6 +222,7 @@ module.exports = class CocoView extends Backbone.View
|
|||
window.currentModal = modalView
|
||||
@getRootView().stopListeningToShortcuts(true)
|
||||
Backbone.Mediator.publish 'modal:opened', {}
|
||||
modalView
|
||||
|
||||
modalClosed: =>
|
||||
visibleModal.willDisappear() if visibleModal
|
||||
|
|
|
@ -50,9 +50,13 @@ module.exports = class ModalView extends CocoView
|
|||
$el = @$el.find('.modal-body') unless $el
|
||||
super($el)
|
||||
|
||||
# TODO: Combine hide/onHidden such that backbone 'hide/hidden.bs.modal' events and our 'hide/hidden' events are more 1-to-1
|
||||
# For example:
|
||||
# pressing 'esc' or using `currentModal.hide()` triggers 'hide', 'hide.bs.modal', 'hidden', 'hidden.bs.modal'
|
||||
# clicking outside the modal triggers 'hide.bs.modal', 'hidden', 'hidden.bs.modal' (but not 'hide')
|
||||
hide: ->
|
||||
@trigger 'hide'
|
||||
@$el.removeClass('fade').modal 'hide'
|
||||
@$el.removeClass('fade').modal 'hide' unless @destroyed
|
||||
|
||||
onHidden: ->
|
||||
@trigger 'hidden'
|
||||
|
|
|
@ -9,6 +9,7 @@ User = require 'models/User'
|
|||
CourseInstance = require 'models/CourseInstance'
|
||||
RootView = require 'views/core/RootView'
|
||||
template = require 'templates/courses/teacher-courses-view'
|
||||
HeroSelectModal = require 'views/courses/HeroSelectModal'
|
||||
|
||||
module.exports = class TeacherCoursesView extends RootView
|
||||
id: 'teacher-courses-view'
|
||||
|
@ -66,4 +67,10 @@ module.exports = class TeacherCoursesView extends RootView
|
|||
language = form.find('.language-select').val()
|
||||
window.tracker?.trackEvent 'Classes Guides Play Level', category: 'Teachers', courseID: courseID, language: language, levelSlug: levelSlug, ['Mixpanel']
|
||||
url = "/play/level/#{levelSlug}?course=#{courseID}&codeLanguage=#{language}"
|
||||
application.router.navigate(url, { trigger: true })
|
||||
firstLevelSlug = @campaigns.get(@courses.at(0).get('campaignID')).getLevels().at(0).get('slug')
|
||||
if levelSlug is firstLevelSlug
|
||||
@listenToOnce @openModalView(new HeroSelectModal()),
|
||||
'hidden': ->
|
||||
application.router.navigate(url, { trigger: true })
|
||||
else
|
||||
application.router.navigate(url, { trigger: true })
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
Level = require 'models/Level'
|
||||
Course = require 'models/Course'
|
||||
Courses = require 'collections/Courses'
|
||||
Campaign = require 'models/Campaign'
|
||||
User = require 'models/User'
|
||||
Classroom = require 'models/Classroom'
|
||||
LevelSession = require 'models/LevelSession'
|
||||
|
@ -19,16 +20,34 @@ module.exports = {
|
|||
_id: _id
|
||||
name: _.string.humanize(_id)
|
||||
releasePhase: 'released'
|
||||
concepts: []
|
||||
}, attrs)
|
||||
|
||||
attrs.campaignID ?= sources.campaign?.id or _.uniqueId('campaign_')
|
||||
return new Course(attrs)
|
||||
|
||||
makeCampaign: (attrs, sources={}) ->
|
||||
_id = _.uniqueId('campaign_')
|
||||
attrs = _.extend({}, {
|
||||
_id
|
||||
name: _.string.humanize(_id)
|
||||
levels: [@makeLevel(), @makeLevel()]
|
||||
}, attrs)
|
||||
|
||||
if sources.levels
|
||||
levelsMap = {}
|
||||
sources.levels.each (level) ->
|
||||
levelsMap[level.id] = level
|
||||
attrs.levels = levelsMap
|
||||
|
||||
return new Campaign(attrs)
|
||||
|
||||
makeLevel: (attrs) ->
|
||||
_id = _.uniqueId('level_')
|
||||
attrs = _.extend({}, {
|
||||
_id: _id
|
||||
name: _.string.humanize(_id)
|
||||
slug: _.string.dasherize(_id)
|
||||
original: _id+'_original'
|
||||
version:
|
||||
major: 0
|
||||
|
|
|
@ -13,6 +13,7 @@ describe 'CoursesView', ->
|
|||
|
||||
describe 'Change Hero button', ->
|
||||
beforeEach (done) ->
|
||||
me.set(factories.makeUser({ role: 'student' }).attributes)
|
||||
view = new CoursesView()
|
||||
classrooms = new Classrooms([factories.makeClassroom()])
|
||||
courseInstances = new CourseInstances([factories.makeCourseInstance()])
|
||||
|
|
|
@ -35,3 +35,16 @@ describe 'HeroSelectModal', ->
|
|||
expect(request.method).toBe("PUT")
|
||||
expect(JSON.parse(request.params).heroConfig?.thangType).toBe(hero2.get('original'))
|
||||
done()
|
||||
|
||||
it 'triggers its events properly', (done) ->
|
||||
spyOn(modal, 'trigger')
|
||||
modal.render()
|
||||
modal.$('.hero-option:nth-child(2)').click()
|
||||
request = jasmine.Ajax.requests.mostRecent()
|
||||
request.respondWith({ status: 200, responseText: me.attributes })
|
||||
expect(modal.trigger).toHaveBeenCalled()
|
||||
expect(modal.trigger.calls.argsFor(0)[0]).toBe('hero-select:success')
|
||||
expect(modal.trigger).not.toHaveBeenCalledWith('hide')
|
||||
modal.$('.select-hero-btn').click()
|
||||
expect(modal.trigger).toHaveBeenCalledWith('hide')
|
||||
done()
|
||||
|
|
63
test/app/views/courses/TeacherCoursesView.spec.coffee
Normal file
63
test/app/views/courses/TeacherCoursesView.spec.coffee
Normal file
|
@ -0,0 +1,63 @@
|
|||
TeacherCoursesView = require 'views/courses/TeacherCoursesView'
|
||||
HeroSelectModal = require 'views/courses/HeroSelectModal'
|
||||
Classrooms = require 'collections/Classrooms'
|
||||
Courses = require 'collections/Courses'
|
||||
Campaigns = require 'collections/Campaigns'
|
||||
Levels = require 'collections/Levels'
|
||||
auth = require 'core/auth'
|
||||
factories = require 'test/app/factories'
|
||||
|
||||
describe 'TeacherCoursesView', ->
|
||||
|
||||
modal = null
|
||||
view = null
|
||||
|
||||
describe 'Play Level form', ->
|
||||
beforeEach (done) ->
|
||||
me.set(factories.makeUser({ role: 'teacher' }).attributes)
|
||||
view = new TeacherCoursesView()
|
||||
classrooms = new Classrooms([factories.makeClassroom()])
|
||||
levels1 = new Levels([ factories.makeLevel({ name: 'Dungeons of Kithgard' }), factories.makeLevel(), factories.makeLevel() ])
|
||||
levels2 = new Levels([ factories.makeLevel(), factories.makeLevel(), factories.makeLevel() ])
|
||||
campaigns = new Campaigns([factories.makeCampaign({}, { levels: levels1 }), factories.makeCampaign({}, { levels: levels2 })])
|
||||
courses = new Courses([factories.makeCourse({}, {campaign: campaigns.at(0)}), factories.makeCourse({}, {campaign: campaigns.at(1)})])
|
||||
view.ownedClassrooms.fakeRequests[0].respondWith({ status: 200, responseText: classrooms.stringify() })
|
||||
view.campaigns.fakeRequests[0].respondWith({ status: 200, responseText: campaigns.stringify() })
|
||||
view.courses.fakeRequests[0].respondWith({ status: 200, responseText: courses.stringify() })
|
||||
view.render()
|
||||
done()
|
||||
|
||||
it 'opens HeroSelectModal for the first level of the first course', (done) ->
|
||||
spyOn(view, 'openModalView').and.callFake (modal) -> modal
|
||||
spyOn(application.router, 'navigate')
|
||||
view.$('.play-level-button').first().click()
|
||||
expect(view.openModalView).toHaveBeenCalled()
|
||||
expect(application.router.navigate).not.toHaveBeenCalled()
|
||||
args = view.openModalView.calls.argsFor(0)
|
||||
modalView = args[0]
|
||||
expect(modalView instanceof HeroSelectModal).toBe(true)
|
||||
modalView.trigger('hero-select:success')
|
||||
expect(application.router.navigate).not.toHaveBeenCalled()
|
||||
modalView.trigger('hide')
|
||||
modalView.trigger('hidden')
|
||||
_.defer ->
|
||||
expect(application.router.navigate).toHaveBeenCalled()
|
||||
done()
|
||||
|
||||
it "doesn't open HeroSelectModal for other levels", ->
|
||||
spyOn(view, 'openModalView')
|
||||
spyOn(application.router, 'navigate')
|
||||
secondLevelSlug = view.$('.level-select:first option:nth-child(2)').val()
|
||||
view.$('.level-select').first().val(secondLevelSlug)
|
||||
view.$('.play-level-button').first().click()
|
||||
expect(view.openModalView).not.toHaveBeenCalled()
|
||||
expect(application.router.navigate).toHaveBeenCalled()
|
||||
|
||||
it "doesn't open HeroSelectModal for other courses", ->
|
||||
spyOn(view, 'openModalView')
|
||||
spyOn(application.router, 'navigate')
|
||||
view.$('.play-level-button').get(1).click()
|
||||
expect(view.openModalView).not.toHaveBeenCalled()
|
||||
expect(application.router.navigate).toHaveBeenCalled()
|
||||
|
||||
it "remembers the selected hero" # TODO
|
Loading…
Reference in a new issue