update due dates and availability info for quizzes on index page
fixes CNVS-9679 test plan: As a teacher: - The availability date should display in six different formats - Blank (when there is no availability dates) - "Available" (when the assignment is unlocked, and there is no lock date) - "Not available until <date>" (when the assignment is not unlocked yet) - "Available until <date>" (when the assignment is unlocked and has a lock date) - "Closed" (when the locked date has passed) - "Multiple Availability" (when there are multiple availability dates) - Add different variations on availability dates for quizzes - Check that the format appears correct - Generally availability and due dates should work the same between quizzes and assignments As a student: - The format of availability / due dates should generally work similarly to that of a teacher except: - It should never show "Multiple Availability" for due dates - It should never show "Multiple Availability" for availability dates Change-Id: If68c15049f854ff42def76239e2dcfd4901fcc20 Reviewed-on: https://gerrit.instructure.com/26792 Tested-by: Jenkins <jenkins@instructure.com> Reviewed-by: Josh Simpson <jsimpson@instructure.com> QA-Review: Caleb Guanzon <cguanzon@instructure.com> Product-Review: Derek DeVries <ddevries@instructure.com>
This commit is contained in:
parent
980004aa49
commit
008a784bd1
|
@ -1,13 +1,16 @@
|
|||
define [
|
||||
'jquery'
|
||||
'underscore'
|
||||
'Backbone'
|
||||
'compiled/models/Assignment'
|
||||
'compiled/models/DateGroup'
|
||||
'compiled/collections/AssignmentOverrideCollection'
|
||||
'compiled/collections/DateGroupCollection'
|
||||
'str/pluralize'
|
||||
'i18n!quizzes'
|
||||
'jquery.ajaxJSON'
|
||||
'jquery.instructure_misc_helpers' # $.underscore
|
||||
], ($, Backbone, Assignment, AssignmentOverrideCollection, pluralize, I18n) ->
|
||||
], ($, _, Backbone, Assignment, DateGroup, AssignmentOverrideCollection, DateGroupCollection, pluralize, I18n) ->
|
||||
|
||||
class Quiz extends Backbone.Model
|
||||
resourceName: 'quizzes'
|
||||
|
@ -28,6 +31,7 @@ define [
|
|||
@initUnpublishable()
|
||||
@initQuestionsCount()
|
||||
@initPointsCount()
|
||||
@initAllDates()
|
||||
|
||||
# initialize attributes
|
||||
initAssignment: ->
|
||||
|
@ -64,6 +68,10 @@ define [
|
|||
text = I18n.t('assignment_points_possible', 'pt', count: pts) if pts isnt null
|
||||
@set 'possible_points_label', text
|
||||
|
||||
initAllDates: ->
|
||||
if (allDates = @get('all_dates'))?
|
||||
@set 'all_dates', new DateGroupCollection(allDates)
|
||||
|
||||
# publishing
|
||||
|
||||
publish: =>
|
||||
|
@ -76,3 +84,44 @@ define [
|
|||
|
||||
disabledMessage: ->
|
||||
I18n.t('cant_unpublish_when_students_submit', "Can't unpublish if there are student submissions")
|
||||
|
||||
# methods needed by views
|
||||
|
||||
dueAt: (date) =>
|
||||
return @get 'due_at' unless arguments.length > 0
|
||||
@set 'due_at', date
|
||||
|
||||
unlockAt: (date) =>
|
||||
return @get 'unlock_at' unless arguments.length > 0
|
||||
@set 'unlock_at', date
|
||||
|
||||
lockAt: (date) =>
|
||||
return @get 'lock_at' unless arguments.length > 0
|
||||
@set 'lock_at', date
|
||||
|
||||
htmlUrl: =>
|
||||
@get 'url'
|
||||
|
||||
defaultDates: =>
|
||||
group = new DateGroup
|
||||
due_at: @get("due_at")
|
||||
unlock_at: @get("unlock_at")
|
||||
lock_at: @get("lock_at")
|
||||
|
||||
multipleDueDates: =>
|
||||
dateGroups = @get("all_dates")
|
||||
dateGroups && dateGroups.length > 1
|
||||
|
||||
allDates: =>
|
||||
groups = @get("all_dates")
|
||||
models = (groups and groups.models) or []
|
||||
result = _.map models, (group) -> group.toJSON()
|
||||
|
||||
toView: =>
|
||||
fields = [
|
||||
'htmlUrl', 'multipleDueDates', 'allDates', 'dueAt', 'lockAt', 'unlockAt'
|
||||
]
|
||||
hash = id: @get 'id'
|
||||
for field in fields
|
||||
hash[field] = @[field]()
|
||||
hash
|
|
@ -5,11 +5,11 @@ define [
|
|||
'compiled/views/PublishIconView'
|
||||
'jst/quizzes/QuizItemGroupView'
|
||||
'compiled/views/quizzes/QuizItemView'
|
||||
], ($, _, CollectionView, PublishIconView, template, quizItemView) ->
|
||||
], ($, _, CollectionView, PublishIconView, template, QuizItemView) ->
|
||||
|
||||
class ItemGroupView extends CollectionView
|
||||
template: template
|
||||
itemView: quizItemView
|
||||
itemView: QuizItemView
|
||||
|
||||
tagName: 'div'
|
||||
className: 'item-group-condensed'
|
||||
|
@ -36,6 +36,3 @@ define [
|
|||
renderItem: (model) =>
|
||||
return if model.get 'hidden'
|
||||
super
|
||||
|
||||
createItemView: (model) ->
|
||||
new @itemView model: model, publishIconView: new PublishIconView(model: model)
|
||||
|
|
|
@ -3,9 +3,11 @@ define [
|
|||
'jquery'
|
||||
'underscore'
|
||||
'Backbone'
|
||||
'compiled/views/PublishIconView'
|
||||
'compiled/views/assignments/DateDueColumnView'
|
||||
'compiled/views/assignments/DateAvailableColumnView'
|
||||
'jst/quizzes/QuizItemView'
|
||||
'jst/_vddTooltip'
|
||||
], (I18n, $, _, Backbone, template) ->
|
||||
], (I18n, $, _, Backbone, PublishIconView, DateDueColumnView, DateAvailableColumnView, template) ->
|
||||
|
||||
class ItemView extends Backbone.View
|
||||
|
||||
|
@ -14,7 +16,9 @@ define [
|
|||
tagName: 'li'
|
||||
className: 'quiz'
|
||||
|
||||
@child 'publishIconView', '[data-view=publish-icon]'
|
||||
@child 'publishIconView', '[data-view=publish-icon]'
|
||||
@child 'dateDueColumnView', '[data-view=date-due]'
|
||||
@child 'dateAvailableColumnView', '[data-view=date-available]'
|
||||
|
||||
events:
|
||||
'click': 'clickRow'
|
||||
|
@ -25,9 +29,19 @@ define [
|
|||
multipleDates: I18n.t('multiple_due_dates', 'Multiple Dates')
|
||||
|
||||
initialize: (options) ->
|
||||
@initializeChildViews()
|
||||
@observeModel()
|
||||
super
|
||||
|
||||
initializeChildViews: ->
|
||||
@publishIconView = false
|
||||
|
||||
if @canManage()
|
||||
@publishIconView = new PublishIconView(model: @model)
|
||||
|
||||
@dateDueColumnView = new DateDueColumnView(model: @model)
|
||||
@dateAvailableColumnView = new DateAvailableColumnView(model: @model)
|
||||
|
||||
# make clicks follow through to url for entire row
|
||||
clickRow: (e) =>
|
||||
target = $(e.target)
|
||||
|
@ -55,6 +69,9 @@ define [
|
|||
upatePublishState: =>
|
||||
@$('.ig-row').toggleClass('ig-published', @model.get('published'))
|
||||
|
||||
canManage: ->
|
||||
ENV.PERMISSIONS.manage
|
||||
|
||||
toJSON: ->
|
||||
base = _.extend(@model.toJSON(), @options)
|
||||
if @model.get("multiple_due_dates")
|
||||
|
|
|
@ -55,13 +55,12 @@ class QuizzesController < ApplicationController
|
|||
|
||||
@quiz_options = @quizzes.each_with_object({}) do |q, hash|
|
||||
hash[q.id] = {
|
||||
:can_update => is_authorized_action?(q, @current_user, :update),
|
||||
:can_unpublish => q.can_unpublish?,
|
||||
:multiple_due_dates => q.multiple_due_dates_apply_to?(@current_user),
|
||||
:due_at => q.overridden_for(@current_user).due_at,
|
||||
:due_dates => OverrideTooltipPresenter.new(q, @current_user).due_date_summary,
|
||||
:unlock_at => q.all_dates_visible_to(@current_user).first[:unlock_at]
|
||||
:can_update => is_authorized_action?(q, @current_user, :update),
|
||||
:can_unpublish => q.can_unpublish?
|
||||
}
|
||||
hash[q.id][:all_dates] = if is_authorized_action?(q, @current_user, :update)
|
||||
q.dates_hash_visible_to(@current_user)
|
||||
end
|
||||
end
|
||||
|
||||
# legacy
|
||||
|
|
|
@ -27,7 +27,7 @@ li.quiz
|
|||
|
||||
.ig-details
|
||||
right: 110px
|
||||
width: 415px
|
||||
width: 425px
|
||||
|
||||
#quiz_show
|
||||
.alert
|
||||
|
|
|
@ -14,26 +14,10 @@
|
|||
</a>
|
||||
|
||||
<div class="ig-details row-fluid">
|
||||
<div class="span4 ellipses description">
|
||||
{{#if multiple_due_dates}}
|
||||
<strong>{{#t "quiz_due"}}Due{{/t}}</strong>
|
||||
{{> vddTooltip}}
|
||||
|
||||
{{else}}
|
||||
{{#if due_at}}
|
||||
<strong>{{#t "quiz_due"}}Due{{/t}}</strong> {{tDateToString due_at "date_at_time"}}
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="span3 ellipses">{{question_count_label}}</div>
|
||||
|
||||
<div class="span3 ellipses">
|
||||
{{#if unlock_at}}
|
||||
<strong>{{#t "quiz_available"}}Available{{/t}}</strong> {{tDateToString unlock_at "short"}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="span4 ellipses date-available" data-view="date-available"></div>
|
||||
<div class="span4 ellipses date-due" data-view="date-due"></div>
|
||||
<div class="span2 ellipses">{{possible_points_label}}</div>
|
||||
<div class="span2 ellipses">{{question_count_label}}</div>
|
||||
</div>
|
||||
|
||||
{{#if can_update}}
|
||||
|
|
|
@ -2,9 +2,10 @@ define [
|
|||
'jquery'
|
||||
'compiled/models/Quiz'
|
||||
'compiled/models/Assignment'
|
||||
'compiled/models/DateGroup'
|
||||
'compiled/collections/AssignmentOverrideCollection'
|
||||
'jquery.ajaxJSON'
|
||||
], ($, Quiz, Assignment, AssignmentOverrideCollection) ->
|
||||
], ($, Quiz, Assignment, DateGroup, AssignmentOverrideCollection) ->
|
||||
|
||||
module 'Quiz',
|
||||
setup: ->
|
||||
|
@ -109,3 +110,75 @@ define [
|
|||
test '#unpublish sets published attribute to false', ->
|
||||
@quiz.unpublish()
|
||||
ok !@quiz.get('published')
|
||||
|
||||
|
||||
# multiple due dates
|
||||
|
||||
module "Quiz#multipleDueDates"
|
||||
|
||||
test "checks for multiple due dates from assignment overrides", ->
|
||||
quiz = new Quiz all_dates: [{title: "Winter"}, {title: "Summer"}]
|
||||
ok quiz.multipleDueDates()
|
||||
|
||||
test "checks for no multiple due dates from quiz overrides", ->
|
||||
quiz = new Quiz
|
||||
ok !quiz.multipleDueDates()
|
||||
|
||||
module "Quiz#allDates"
|
||||
|
||||
test "gets the due dates from the assignment overrides", ->
|
||||
dueAt = new Date("2013-08-20 11:13:00")
|
||||
dates = [
|
||||
new DateGroup due_at: dueAt, title: "Everyone"
|
||||
]
|
||||
quiz = new Quiz all_dates: dates
|
||||
allDates = quiz.allDates()
|
||||
first = allDates[0]
|
||||
|
||||
equal first.dueAt+"", dueAt+""
|
||||
equal first.dueFor, "Everyone"
|
||||
|
||||
test "gets empty due dates when there are no dates", ->
|
||||
quiz = new Quiz
|
||||
deepEqual quiz.allDates(), []
|
||||
|
||||
|
||||
# toView
|
||||
|
||||
module "Quiz#toView"
|
||||
|
||||
test "returns the quiz's dueAt", ->
|
||||
date = Date.now()
|
||||
quiz = new Quiz name: 'foo'
|
||||
quiz.dueAt date
|
||||
json = quiz.toView()
|
||||
deepEqual json.dueAt, date
|
||||
|
||||
test "returns quiz's lockAt", ->
|
||||
lockAt = Date.now()
|
||||
quiz = new Quiz name: 'foo'
|
||||
quiz.lockAt lockAt
|
||||
json = quiz.toView()
|
||||
deepEqual json.lockAt, lockAt
|
||||
|
||||
test "includes quiz's unlockAt", ->
|
||||
unlockAt = Date.now()
|
||||
quiz = new Quiz name: 'foo'
|
||||
quiz.unlockAt unlockAt
|
||||
json = quiz.toView()
|
||||
deepEqual json.unlockAt, unlockAt
|
||||
|
||||
test "includes htmlUrl", ->
|
||||
quiz = new Quiz url: 'http://example.com/quizzes/1'
|
||||
json = quiz.toView()
|
||||
deepEqual json.htmlUrl, 'http://example.com/quizzes/1'
|
||||
|
||||
test "includes multipleDueDates", ->
|
||||
quiz = new Quiz all_dates: [{title: "Summer"}, {title: "Winter"}]
|
||||
json = quiz.toView()
|
||||
deepEqual json.multipleDueDates, true
|
||||
|
||||
test "includes allDates", ->
|
||||
quiz = new Quiz all_dates: [{title: "Summer"}, {title: "Winter"}]
|
||||
json = quiz.toView()
|
||||
equal json.allDates.length, 2
|
||||
|
|
|
@ -737,14 +737,23 @@ describe "quizzes" do
|
|||
it "should show a summary of due dates if there are multiple" do
|
||||
create_quiz_with_default_due_dates
|
||||
get "/courses/#{@course.id}/quizzes"
|
||||
f('.ig-details .description').should_not include_text "Multiple Dates"
|
||||
f('.ig-details .date-due').should_not include_text "Multiple Dates"
|
||||
f('.ig-details .date-available').should_not include_text "Multiple Dates"
|
||||
|
||||
add_due_date_override(@quiz)
|
||||
|
||||
get "/courses/#{@course.id}/quizzes"
|
||||
f('.ig-details .description').should include_text "Multiple Dates"
|
||||
driver.mouse.move_to f('.ig-details .description a')
|
||||
f('.ig-details .date-due').should include_text "Multiple Dates"
|
||||
driver.mouse.move_to f('.ig-details .date-due a')
|
||||
wait_for_ajaximations
|
||||
tooltip = fj('.vdd_tooltip_content:visible')
|
||||
tooltip = fj('.ui-tooltip:visible')
|
||||
tooltip.should include_text 'New Section'
|
||||
tooltip.should include_text 'Everyone else'
|
||||
|
||||
f('.ig-details .date-available').should include_text "Multiple Dates"
|
||||
driver.mouse.move_to f('.ig-details .date-available a')
|
||||
wait_for_ajaximations
|
||||
tooltip = fj('.ui-tooltip:visible')
|
||||
tooltip.should include_text 'New Section'
|
||||
tooltip.should include_text 'Everyone else'
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue