pop up new tab if assignment rldb setting is enabled

closes QUIZ-7266

test plan:
- create a N.Q assignment
- in rails console, set require_lockdown_browser to true for the
  assignment:
  assignment.settings = {
    'lockdown_browser' => {
      'require_lockdown_browser' => true
    }
  }
  assignment.save!
- from Canvas Assignments Page, click the assignemnt will pop up
  a new tab
- with N.Q on Canvas Quizzes Page FF on, clicking on the N.Q
  quiz will pop up a new tab

Change-Id: Icda1b96a05dd44b7b45c85e6f9ad2b1cd05e9a6a
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/222173
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Tyler Burraston <tburraston@instructure.com>
QA-Review: Mark McDermott <mmcdermott@instructure.com>
Product-Review: Han Yan <hyan@instructure.com>
This commit is contained in:
Han Yan 2020-01-06 21:53:30 -06:00
parent 71c596dca0
commit f61498c7e8
11 changed files with 223 additions and 5 deletions

View File

@ -34,6 +34,9 @@ import { matchingToolUrls } from './LtiAssignmentHelpers'
isAdmin = () ->
_.includes(ENV.current_user_roles, 'admin')
isStudent = () ->
_.includes(ENV.current_user_roles, 'student')
export default class Assignment extends Model
@mixin DefaultUrlMixin
resourceName: 'assignments'
@ -682,3 +685,6 @@ export default class Assignment extends Model
showGradersAnonymousToGradersCheckbox: =>
@moderatedGrading() && @get('grader_comments_visible_to_graders')
quizzesRespondusEnabled: =>
@get('require_lockdown_browser') && @isQuizLTIAssignment() && isStudent()

View File

@ -380,7 +380,8 @@ Quiz.prototype.defaults = {
lock_at: null,
unpublishable: true,
points_possible: null,
post_to_sis: false
post_to_sis: false,
require_lockdown_browser: false
}
function __guard__(value, transform) {

View File

@ -85,7 +85,6 @@ export default class AssignmentListItemView extends Backbone.View
initialize: ->
super
@initializeChildViews()
# we need the following line in order to access this view later
@model.assignmentView = @
@ -221,6 +220,8 @@ export default class AssignmentListItemView extends Backbone.View
data.cyoe = CyoeHelper.getItemData(data.id, @isGraded() && (!@model.isQuiz() || data.is_quiz_assignment))
data.return_to = encodeURIComponent window.location.pathname
data.quizzesRespondusEnabled = @model.quizzesRespondusEnabled()
data.DIRECT_SHARE_ENABLED = !!ENV.DIRECT_SHARE_ENABLED
if data.canManage

View File

@ -250,6 +250,10 @@ export default class ItemView extends Backbone.View {
return ENV.PERMISSIONS.manage
}
isStudent() {
return ENV.current_user_roles.includes('student')
}
canDuplicate() {
const userIsAdmin = _.includes(ENV.current_user_roles, 'admin')
const canManage = this.canManage()
@ -339,6 +343,10 @@ export default class ItemView extends Backbone.View {
base.showDueDate = this.model.multipleDueDates() || this.model.singleSectionDueDate()
base.name = this.model.name()
base.isQuizzesNext = this.model.isQuizzesNext()
base.quizzesRespondusEnabled =
this.isStudent() &&
this.model.get('require_lockdown_browser') &&
this.model.get('quiz_type') === 'quizzes.next'
base.is_locked =
this.model.get('is_master_course_child_content') &&

View File

@ -61,7 +61,7 @@
<span class="screenreader-only">{{objectTypeDisplayName}}</span>
</div>
<div class="ig-info">
<a href="{{htmlUrl}}" class="ig-title" aria-live="polite">
<a href="{{htmlUrl}}" class="ig-title" aria-live="polite" {{#if quizzesRespondusEnabled}}target="_blank"{{/if}}>
{{name}}
</a>
<div class="ig-details">

View File

@ -61,7 +61,7 @@
</div>
<div class="ig-info">
<a href="{{url}}" class="ig-title">
<a href="{{url}}" {{#if quizzesRespondusEnabled}}target="_blank"{{/if}} class="ig-title">
{{title_label}}
</a>
<div class="ig-details">

View File

@ -372,6 +372,8 @@ module Api::V1::Assignment
hash['anonymous_grading'] = value_to_boolean(assignment.anonymous_grading)
hash['anonymize_students'] = assignment.anonymize_students?
hash['require_lockdown_browser'] = assignment.settings&.dig('lockdown_browser', 'require_lockdown_browser') || false
hash
end

View File

@ -1484,3 +1484,44 @@ QUnit.module('Assignment#showGradersAnonymousToGradersCheckbox', hooks => {
equal(assignment.showGradersAnonymousToGradersCheckbox(), true)
})
})
QUnit.module('Assignment#quizzesRespondusEnabled', hooks => {
let assignment
hooks.beforeEach(() => {
assignment = new Assignment()
fakeENV.setup({current_user_roles: []})
})
hooks.afterEach(() => {
fakeENV.teardown()
})
test('returns false if the assignment is not RLDB enabled', () => {
fakeENV.setup({current_user_roles: ['student']})
assignment.set('require_lockdown_browser', false)
assignment.set('is_quiz_lti_assignment', true)
equal(assignment.quizzesRespondusEnabled(), false)
})
test('returns false if the assignment is not a N.Q assignment', () => {
fakeENV.setup({current_user_roles: ['student']})
assignment.set('require_lockdown_browser', true)
assignment.set('is_quiz_lti_assignment', false)
equal(assignment.quizzesRespondusEnabled(), false)
})
test('returns false if the user is not a student', () => {
fakeENV.setup({current_user_roles: ['teacher']})
assignment.set('require_lockdown_browser', true)
assignment.set('is_quiz_lti_assignment', true)
equal(assignment.quizzesRespondusEnabled(), false)
})
test('returns true if the assignment is a RLDB enabled N.Q', () => {
fakeENV.setup({current_user_roles: ['student']})
assignment.set('require_lockdown_browser', true)
assignment.set('is_quiz_lti_assignment', true)
equal(assignment.quizzesRespondusEnabled(), true)
})
})

View File

@ -1452,3 +1452,61 @@ test('renders assignment icon for other assignments', () => {
const view = createView(model)
equal(view.$('i.icon-assignment').length, 1)
})
QUnit.module('Assignment#quizzesRespondusEnabled', hooks => {
hooks.beforeEach(() => {
fakeENV.setup({current_user_roles: []})
})
hooks.afterEach(() => {
fakeENV.teardown()
})
test('returns false if the assignment is not RLDB enabled', () => {
fakeENV.setup({current_user_roles: ['student']})
const model = buildAssignment({
id: 1,
require_lockdown_browser: false,
is_quiz_lti_assignment: true
})
const view = createView(model)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, false)
})
test('returns false if the assignment is not a N.Q assignment', () => {
fakeENV.setup({current_user_roles: ['student']})
const model = buildAssignment({
id: 1,
require_lockdown_browser: true,
is_quiz_lti_assignment: false
})
const view = createView(model)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, false)
})
test('returns false if the user is not a student', () => {
fakeENV.setup({current_user_roles: ['teacher']})
const model = buildAssignment({
id: 1,
require_lockdown_browser: true,
is_quiz_lti_assignment: true
})
const view = createView(model)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, false)
})
test('returns true if the assignment is a RLDB enabled N.Q', () => {
fakeENV.setup({current_user_roles: ['student']})
const model = buildAssignment({
id: 1,
require_lockdown_browser: true,
is_quiz_lti_assignment: true
})
const view = createView(model)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, true)
})
})

View File

@ -593,3 +593,61 @@ QUnit.module('direct share', hooks => {
equal(ReactDOM.render.lastCall.args[0].props.open, false)
})
})
QUnit.module('Quiz#quizzesRespondusEnabled', hooks => {
hooks.beforeEach(() => {
fakeENV.setup({current_user_roles: []})
})
hooks.afterEach(() => {
fakeENV.teardown()
})
test('returns false if the assignment is not RLDB enabled', () => {
fakeENV.setup({current_user_roles: ['student']})
const quiz = createQuiz({
id: 1,
quiz_type: 'quizzes.next',
require_lockdown_browser: false
})
const view = createView(quiz)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, false)
})
test('returns false if the assignment is not a N.Q assignment', () => {
fakeENV.setup({current_user_roles: ['student']})
const quiz = createQuiz({
id: 1,
quiz_type: 'practice',
require_lockdown_browser: true
})
const view = createView(quiz)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, false)
})
test('returns false if the user is not a student', () => {
fakeENV.setup({current_user_roles: ['teacher']})
const quiz = createQuiz({
id: 1,
quiz_type: 'quizzes.next',
require_lockdown_browser: true
})
const view = createView(quiz)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, false)
})
test('returns true if the assignment is a RLDB enabled N.Q', () => {
fakeENV.setup({current_user_roles: ['student']})
const quiz = createQuiz({
id: 1,
quiz_type: 'quizzes.next',
require_lockdown_browser: true
})
const view = createView(quiz)
const json = view.toJSON()
equal(json.quizzesRespondusEnabled, true)
})
})

View File

@ -197,7 +197,6 @@ describe "Api::V1::Assignment" do
expect(json).not_to have_key "needs_grading_count"
end
context 'rubrics' do
before do
rubric_model({
@ -247,6 +246,50 @@ describe "Api::V1::Assignment" do
expect(json['rubric_settings']['hide_points']).to eq true
end
end
describe 'N.Q respondus setting' do
context 'when N.Q respondus setting is on' do
before do
assignment.settings = {
'lockdown_browser' => {
'require_lockdown_browser' => true
}
}
assignment.save!
end
it 'serializes require_lockdown_browser to be true' do
json = api.assignment_json(assignment, user, session, {})
expect(json.key?('require_lockdown_browser')).to be_present
expect(json['require_lockdown_browser']).to be_truthy
end
end
context 'when N.Q respondus setting is off' do
before do
assignment.settings = {
'lockdown_browser' => {
'require_lockdown_browser' => false
}
}
assignment.save!
end
it 'serializes require_lockdown_browser to be false' do
json = api.assignment_json(assignment, user, session, {})
expect(json.key?('require_lockdown_browser')).to be_present
expect(json['require_lockdown_browser']).to be_falsy
end
end
context 'when N.Q respondus setting is off (default)' do
it 'serializes require_lockdown_browser to be false' do
json = api.assignment_json(assignment, user, session, {})
expect(json.key?('require_lockdown_browser')).to be_present
expect(json['require_lockdown_browser']).to be_falsy
end
end
end
end
describe "*_settings_hash methods" do