Teacher can create annotation assignment
refs EVAL-1363 test plan: - enable annotated_document_submissions flag - create new assignment - check "annotated document" under "Online Entry Options" - select a document - assignment should successfully save - assignment record should have annotatable_attachment_id field flag=annotated_document_submissions Change-Id: I5e90ca9c8f0b0501719cfe9e9d946be66fa899c5 Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/258184 Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com> Reviewed-by: Adrian Packel <apackel@instructure.com> Reviewed-by: Spencer Olson <solson@instructure.com> QA-Review: Kai Bjorkman <kbjorkman@instructure.com> Product-Review: Jody Sailor
This commit is contained in:
parent
88be9d1986
commit
b19db4b7eb
|
@ -238,6 +238,9 @@ export default class Assignment extends Model
|
|||
acceptsOnlineUpload: =>
|
||||
!! _.includes @_submissionTypes(), 'online_upload'
|
||||
|
||||
acceptsAnnotatedDocument: =>
|
||||
!! _.includes @_submissionTypes(), 'annotated_document'
|
||||
|
||||
acceptsOnlineURL: =>
|
||||
!! _.includes @_submissionTypes(), 'online_url'
|
||||
|
||||
|
@ -250,7 +253,7 @@ export default class Assignment extends Model
|
|||
isOnlineSubmission: =>
|
||||
_.some @_submissionTypes(), (thing) ->
|
||||
thing in ['online', 'online_text_entry',
|
||||
'media_recording', 'online_url', 'online_upload']
|
||||
'media_recording', 'online_url', 'online_upload', 'annotated_document']
|
||||
|
||||
postToSIS: (postToSisBoolean) =>
|
||||
return @get 'post_to_sis' unless arguments.length > 0
|
||||
|
@ -557,6 +560,7 @@ export default class Assignment extends Model
|
|||
|
||||
toView: =>
|
||||
fields = [
|
||||
'acceptsAnnotatedDocument',
|
||||
'acceptsMediaRecording', 'acceptsOnlineTextEntries', 'acceptsOnlineURL',
|
||||
'acceptsOnlineUpload', 'allDates', 'allowedExtensions', 'anonymousGrading',
|
||||
'anonymousInstructorAnnotations', 'anonymousPeerReviews', 'assignmentGroupId',
|
||||
|
|
|
@ -50,6 +50,7 @@ import 'jqueryui/dialog'
|
|||
import 'jquery.toJSON'
|
||||
import '../../jquery.rails_flash_notifications'
|
||||
import '../../behaviors/tooltip'
|
||||
import {FileBrowserWrapper} from 'jsx/assignments/EditAssignment'
|
||||
|
||||
###
|
||||
xsslint safeString.identifier srOnly
|
||||
|
@ -69,9 +70,11 @@ export default class EditView extends ValidatedFormView
|
|||
ONLINE_SUBMISSION_TYPES = '#assignment_online_submission_types'
|
||||
NAME = '[name="name"]'
|
||||
ALLOW_FILE_UPLOADS = '#assignment_online_upload'
|
||||
ALLOW_ANNOTATED_DOCUMENT = '#assignment_annotated_document'
|
||||
ALLOW_TEXT_ENTRY = '#assignment_text_entry'
|
||||
RESTRICT_FILE_UPLOADS = '#assignment_restrict_file_extensions'
|
||||
RESTRICT_FILE_UPLOADS_OPTIONS = '#restrict_file_extensions_container'
|
||||
ANNOTATED_DOCUMENT_OPTIONS = '#annotated_document_chooser_container'
|
||||
ALLOWED_EXTENSIONS = '#allowed_extensions_container'
|
||||
TURNITIN_ENABLED = '#assignment_turnitin_enabled'
|
||||
VERICITE_ENABLED = '#assignment_vericite_enabled'
|
||||
|
@ -115,8 +118,10 @@ export default class EditView extends ValidatedFormView
|
|||
els["#{ONLINE_SUBMISSION_TYPES}"] = '$onlineSubmissionTypes'
|
||||
els["#{NAME}"] = '$name'
|
||||
els["#{ALLOW_FILE_UPLOADS}"] = '$allowFileUploads'
|
||||
els["#{ALLOW_ANNOTATED_DOCUMENT}"] = '$allowAnnotatedDocument'
|
||||
els["#{RESTRICT_FILE_UPLOADS}"] = '$restrictFileUploads'
|
||||
els["#{RESTRICT_FILE_UPLOADS_OPTIONS}"] = '$restrictFileUploadsOptions'
|
||||
els["#{ANNOTATED_DOCUMENT_OPTIONS}"] = '$annotatedDocumentOptions'
|
||||
els["#{ALLOWED_EXTENSIONS}"] = '$allowedExtensions'
|
||||
els["#{TURNITIN_ENABLED}"] = '$turnitinEnabled'
|
||||
els["#{VERICITE_ENABLED}"] = '$vericiteEnabled'
|
||||
|
@ -159,6 +164,7 @@ export default class EditView extends ValidatedFormView
|
|||
events["change #{TURNITIN_ENABLED}"] = 'toggleAdvancedTurnitinSettings'
|
||||
events["change #{VERICITE_ENABLED}"] = 'toggleAdvancedTurnitinSettings'
|
||||
events["change #{ALLOW_FILE_UPLOADS}"] = 'toggleRestrictFileUploads'
|
||||
events["change #{ALLOW_ANNOTATED_DOCUMENT}"] = 'toggleAnnotatedDocument'
|
||||
events["click #{EXTERNAL_TOOLS_URL}_find"] = 'showExternalToolsDialog'
|
||||
events["change #assignment_points_possible"] = 'handlePointsChange'
|
||||
events["change #{PEER_REVIEWS_BOX}"] = 'togglePeerReviewsAndGroupCategoryEnabled'
|
||||
|
@ -322,6 +328,29 @@ export default class EditView extends ValidatedFormView
|
|||
toggleRestrictFileUploads: =>
|
||||
@$restrictFileUploadsOptions.toggleAccessibly @$allowFileUploads.prop('checked')
|
||||
|
||||
toggleAnnotatedDocument: =>
|
||||
@$annotatedDocumentOptions.toggleAccessibly @$allowAnnotatedDocument.prop('checked')
|
||||
|
||||
documentChooserContainer = document.querySelector('#annotated_document_chooser_container')
|
||||
|
||||
if @$allowAnnotatedDocument.prop('checked')
|
||||
fileBrowserProps = {
|
||||
useContextAssets: true,
|
||||
allowUpload: true,
|
||||
selectFile: (fileInfo) =>
|
||||
document.getElementById('annotated_document_id').value = fileInfo.id
|
||||
$.screenReaderFlashMessageExclusive(
|
||||
I18n.t('selected %{filename}', {filename: fileInfo.name})
|
||||
)
|
||||
}
|
||||
|
||||
ReactDOM.render(
|
||||
React.createElement(FileBrowserWrapper, fileBrowserProps),
|
||||
documentChooserContainer
|
||||
)
|
||||
else
|
||||
ReactDOM.unmountComponentAtNode(documentChooserContainer)
|
||||
|
||||
toggleAdvancedTurnitinSettings: (ev) =>
|
||||
ev.preventDefault()
|
||||
@$advancedTurnitinSettings.toggleAccessibly (@$turnitinEnabled.prop('checked') || @$vericiteEnabled.prop('checked'))
|
||||
|
@ -520,6 +549,7 @@ export default class EditView extends ValidatedFormView
|
|||
lockedItems: @lockedItems
|
||||
anonymousGradingEnabled: ENV?.ANONYMOUS_GRADING_ENABLED or false
|
||||
anonymousInstructorAnnotationsEnabled: ENV?.ANONYMOUS_INSTRUCTOR_ANNOTATIONS_ENABLED or false
|
||||
annotatedDocumentSubmissionsEnabled: ENV?.ANNOTATED_DOCUMENT_SUBMISSIONS or false
|
||||
|
||||
_attachEditorToDescription: =>
|
||||
return if @lockedItems.content
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright (C) 2021 - present Instructure, Inc.
|
||||
*
|
||||
* This file is part of Canvas.
|
||||
*
|
||||
* Canvas is free software: you can redistribute it and/or modify it under
|
||||
* the terms of the GNU Affero General Public License as published by the Free
|
||||
* Software Foundation, version 3 of the License.
|
||||
*
|
||||
* Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
* A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
* details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import React, {Suspense} from 'react'
|
||||
import ErrorBoundary from 'jsx/shared/components/ErrorBoundary'
|
||||
import errorShipUrl from 'jsx/shared/svg/ErrorShip.svg'
|
||||
import GenericErrorPage from 'jsx/shared/components/GenericErrorPage/index'
|
||||
import LoadingIndicator from 'jsx/shared/LoadingIndicator'
|
||||
|
||||
const FileBrowser = React.lazy(() => import('jsx/shared/rce/FileBrowser'))
|
||||
|
||||
export function FileBrowserWrapper(props) {
|
||||
return (
|
||||
<ErrorBoundary
|
||||
errorComponent={
|
||||
<GenericErrorPage
|
||||
imageUrl={errorShipUrl}
|
||||
errorCategory="FileBrowser on Create Assignment page"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<Suspense fallback={<LoadingIndicator />}>
|
||||
<FileBrowser {...props} />
|
||||
</Suspense>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}
|
|
@ -26,15 +26,17 @@ export default class ErrorBoundary extends React.Component {
|
|||
}
|
||||
|
||||
static getDerivedStateFromError(error) {
|
||||
// Update state so the next render will show the fallback UI.
|
||||
return {hasError: true, error}
|
||||
}
|
||||
|
||||
componentDidCatch(error, errorInfo) {
|
||||
console.error(error, errorInfo)
|
||||
}
|
||||
|
||||
state = {hasError: false, error: null}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
// You can render any custom fallback UI
|
||||
return React.cloneElement(this.props.errorComponent, {errorSubject: this.state.error.message})
|
||||
}
|
||||
|
||||
|
|
|
@ -7,14 +7,13 @@
|
|||
<div class="form-column-right">
|
||||
<div class="border border-trbl border-round">
|
||||
{{!-- Submission type accepted --}}
|
||||
<select id="assignment_submission_type"
|
||||
name="submission_type"
|
||||
<select id="assignment_submission_type" name="submission_type"
|
||||
aria-controls="assignment_online_submission_types,assignment_external_tool_settings,assignment_group_selector,assignment_peer_reviews_fields"
|
||||
{{disabledIfIncludes frozenAttributes "submission_types"}}>
|
||||
{{#if defaultToolName}}
|
||||
<option value="default_external_tool" {{selectedIf isDefaultTool}}>
|
||||
{{defaultToolName}}
|
||||
</option>
|
||||
<option value="default_external_tool" {{selectedIf isDefaultTool}}>
|
||||
{{defaultToolName}}
|
||||
</option>
|
||||
{{/if}}
|
||||
<option value="none" {{selectedIf defaultToNone}}>
|
||||
{{#t "submission_types.no_submission"}}No Submission{{/t}}
|
||||
|
@ -29,20 +28,19 @@
|
|||
{{#t "submission_types.external_tool"}}External Tool{{/t}}
|
||||
</option>
|
||||
{{#if submissionTypeSelectionTools}}
|
||||
{{#each submissionTypeSelectionTools}}
|
||||
<option value="external_tool_placement_{{this.id}}" {{selectedIf this.id ../selectedSubmissionTypeToolId}}>
|
||||
{{this.base_title}}
|
||||
</option>
|
||||
{{/each}}
|
||||
{{#each submissionTypeSelectionTools}}
|
||||
<option value="external_tool_placement_{{this.id}}" {{selectedIf this.id ../selectedSubmissionTypeToolId}}>
|
||||
{{this.base_title}}
|
||||
</option>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</select>
|
||||
{{#if submissionTypesFrozen }}
|
||||
<input type="hidden" name="submission_type" value="{{submissionType}}" />
|
||||
{{#if submissionTypesFrozen}}
|
||||
<input type="hidden" name="submission_type" value="{{submissionType}}" />
|
||||
{{/if}}
|
||||
|
||||
{{!-- Online submission types --}}
|
||||
<div id="assignment_online_submission_types"
|
||||
aria-enabled="{{isOnlineSubmission}}"
|
||||
<div id="assignment_online_submission_types" aria-enabled="{{isOnlineSubmission}}"
|
||||
style="{{hiddenUnless isOnlineSubmission}}">
|
||||
|
||||
<div class="subtitle">
|
||||
|
@ -53,79 +51,85 @@
|
|||
|
||||
<label class="checkbox" for="assignment_text_entry">
|
||||
{{checkbox "acceptsOnlineTextEntries"
|
||||
id="assignment_text_entry"
|
||||
name="online_submission_types[online_text_entry]"
|
||||
aria-label=(t "Online Submission Type - Text Entry")
|
||||
disabled=submissionTypesFrozen}}
|
||||
id="assignment_text_entry"
|
||||
name="online_submission_types[online_text_entry]"
|
||||
aria-label=(t "Online Submission Type - Text Entry")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.allow_text_entry"}}Text Entry{{/t}}
|
||||
</label>
|
||||
|
||||
<label class="checkbox" for="assignment_online_url">
|
||||
{{checkbox "acceptsOnlineURL"
|
||||
id="assignment_online_url"
|
||||
name="online_submission_types[online_url]"
|
||||
aria-label=(t "Online Submission Type - Website URL")
|
||||
disabled=submissionTypesFrozen}}
|
||||
id="assignment_online_url"
|
||||
name="online_submission_types[online_url]"
|
||||
aria-label=(t "Online Submission Type - Website URL")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.allow_url"}}Website URL{{/t}}
|
||||
</label>
|
||||
{{#if kalturaEnabled}}
|
||||
<label class="checkbox" for="assignment_media_recording">
|
||||
{{checkbox "acceptsMediaRecording"
|
||||
id="assignment_media_recording"
|
||||
name="online_submission_types[media_recording]"
|
||||
aria-label=(t "Online Submission Type - Media Recordings")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.allow_media_recordings"}}Media Recordings{{/t}}
|
||||
</label>
|
||||
<label class="checkbox" for="assignment_media_recording">
|
||||
{{checkbox "acceptsMediaRecording"
|
||||
id="assignment_media_recording"
|
||||
name="online_submission_types[media_recording]"
|
||||
aria-label=(t "Online Submission Type - Media Recordings")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.allow_media_recordings"}}Media Recordings{{/t}}
|
||||
</label>
|
||||
{{/if}}
|
||||
{{#if annotatedDocumentSubmissionsEnabled}}
|
||||
<label class="checkbox" for="assignment_annotated_document">
|
||||
{{checkbox "acceptsAnnotatedDocument"
|
||||
id="assignment_annotated_document"
|
||||
name="online_submission_types[annotated_document]"
|
||||
aria-controls="restrict_file_extensions_container"
|
||||
aria-label=(t "Online Submission Type - Annotated Document")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.allows_annotated_document"}}Annotated Document{{/t}}
|
||||
</label>
|
||||
<div id="annotated_document_chooser_container" class="nested" aria-expanded="{{acceptsAnnotatedDocument}}"
|
||||
style="{{hiddenUnless acceptsAnnotatedDocument}}; padding: 6px 0 6px 42px;">
|
||||
</div>
|
||||
<input type="hidden" name="annotated_document_id" id="annotated_document_id" />
|
||||
{{/if}}
|
||||
<label class="checkbox" for="assignment_online_upload">
|
||||
{{checkbox "acceptsOnlineUpload"
|
||||
id="assignment_online_upload"
|
||||
name="online_submission_types[online_upload]"
|
||||
aria-controls="restrict_file_extensions_container"
|
||||
aria-label=(t "Online Submission Type - File Uploads")
|
||||
disabled=submissionTypesFrozen}}
|
||||
id="assignment_online_upload"
|
||||
name="online_submission_types[online_upload]"
|
||||
aria-controls="restrict_file_extensions_container"
|
||||
aria-label=(t "Online Submission Type - File Uploads")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.allow_file_uploads"}}File Uploads{{/t}}
|
||||
</label>
|
||||
|
||||
{{!-- Online submission restrict file types? --}}
|
||||
<div id="restrict_file_extensions_container"
|
||||
class="nested"
|
||||
aria-expanded="{{acceptsOnlineUpload}}"
|
||||
<div id="restrict_file_extensions_container" class="nested" aria-expanded="{{acceptsOnlineUpload}}"
|
||||
style="{{hiddenUnless acceptsOnlineUpload}}">
|
||||
|
||||
<label class="checkbox" for="assignment_restrict_file_extensions">
|
||||
{{checkbox "restrictFileExtensions"
|
||||
id="assignment_restrict_file_extensions"
|
||||
name="restrict_file_extensions"
|
||||
aria-controls="allowed_extensions_container"
|
||||
aria-label=(t "Online Submission Type - File Uploads - Restrict Upload File Types")
|
||||
disabled=submissionTypesFrozen}}
|
||||
id="assignment_restrict_file_extensions"
|
||||
name="restrict_file_extensions"
|
||||
aria-controls="allowed_extensions_container"
|
||||
aria-label=(t "Online Submission Type - File Uploads - Restrict Upload File Types")
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "labels.restrict_file_extensions"}}
|
||||
Restrict Upload File Types
|
||||
Restrict Upload File Types
|
||||
{{/t}}
|
||||
</label>
|
||||
|
||||
{{!-- Online submission allowed extensions --}}
|
||||
<div id="allowed_extensions_container"
|
||||
aria-expanded="{{restrictFileExtensions}}"
|
||||
style="{{hiddenUnless restrictFileExtensions}}"
|
||||
class="nested">
|
||||
<div id="allowed_extensions_container" aria-expanded="{{restrictFileExtensions}}"
|
||||
style="{{hiddenUnless restrictFileExtensions}}" class="nested">
|
||||
<label for="assignment_allowed_extensions" class="hidden-readable">
|
||||
{{#t "labels.allowed_extensions"}}Allowed File Extensions{{/t}}
|
||||
</label>
|
||||
|
||||
<input id="assignment_allowed_extensions"
|
||||
name="allowed_extensions"
|
||||
type="text"
|
||||
maxlength="254"
|
||||
placeholder="{{#t "labels.allowed_extensions"}}Allowed File Extensions{{/t}}"
|
||||
aria-labelledby="explanation_nest"
|
||||
value="{{join allowedExtensions ","}}"
|
||||
{{disabledIfIncludes frozenAttributes "submission_types"}}/>
|
||||
<input id="assignment_allowed_extensions" name="allowed_extensions" type="text" maxlength="254" placeholder="{{#t "
|
||||
labels.allowed_extensions"}}Allowed File Extensions{{/t}}" aria-labelledby="explanation_nest"
|
||||
value="{{join allowedExtensions " ,"}}" {{disabledIfIncludes frozenAttributes "submission_types"}} />
|
||||
<div id="explanation_nest" class="explanation nest">
|
||||
{{#t "descriptions.allowed_extensions"}}
|
||||
Enter a list of accepted extensions, for example: doc,xls,txt
|
||||
Enter a list of accepted extensions, for example: doc,xls,txt
|
||||
{{/t}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -135,17 +139,15 @@
|
|||
<div style="{{hiddenUnless turnitinAvailable}}">
|
||||
<label for="assignment_turnitin_enabled" class="checkbox">
|
||||
{{checkbox "turnitinEnabled"
|
||||
id="assignment_turnitin_enabled"
|
||||
name="turnitin_enabled"
|
||||
aria-controls="advanced_turnitin_settings_link"
|
||||
disabled=submissionTypesFrozen}}
|
||||
id="assignment_turnitin_enabled"
|
||||
name="turnitin_enabled"
|
||||
aria-controls="advanced_turnitin_settings_link"
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "label.turnitin_enabled"}}Enable Turnitin Submissions{{/t}}
|
||||
</label>
|
||||
|
||||
<div class="nested">
|
||||
<a href="#"
|
||||
id="advanced_turnitin_settings_link"
|
||||
aria-expanded="{{turnitinEnabled}}"
|
||||
<a href="#" id="advanced_turnitin_settings_link" aria-expanded="{{turnitinEnabled}}"
|
||||
style="{{hiddenUnless turnitinEnabled}}">
|
||||
{{#t "advanced_turnitin_settings"}}Advanced Turnitin Settings{{/t}}
|
||||
</a>
|
||||
|
@ -155,16 +157,14 @@
|
|||
<div style="{{hiddenUnless vericiteAvailable}}">
|
||||
<label for="assignment_vericite_enabled" class="checkbox">
|
||||
{{checkbox "vericiteEnabled"
|
||||
id="assignment_vericite_enabled"
|
||||
name="vericite_enabled"
|
||||
aria-controls="advanced_turnitin_settings_link"
|
||||
disabled=submissionTypesFrozen}}
|
||||
id="assignment_vericite_enabled"
|
||||
name="vericite_enabled"
|
||||
aria-controls="advanced_turnitin_settings_link"
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "label.vericite_enabled"}}Enable VeriCite Submissions{{/t}}
|
||||
</label>
|
||||
<div class="nested">
|
||||
<a href="#"
|
||||
id="advanced_turnitin_settings_link"
|
||||
aria-expanded="{{vericiteEnabled}}"
|
||||
<a href="#" id="advanced_turnitin_settings_link" aria-expanded="{{vericiteEnabled}}"
|
||||
style="{{hiddenUnless vericiteEnabled}}">
|
||||
{{#t "advanced_vericite_settings"}}Advanced VeriCite Settings{{/t}}
|
||||
</a>
|
||||
|
@ -172,36 +172,43 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{!-- LTI launch button for getting additional data for external tool assignments (when selected via placement) --}}
|
||||
<div id="assignment_submission_type_selection_tool_launch_container" style="{{hiddenUnless selectedSubmissionTypeToolId}}">
|
||||
{{!-- LTI launch button for getting additional data for external tool assignments (when selected via placement)
|
||||
--}}
|
||||
<div id="assignment_submission_type_selection_tool_launch_container"
|
||||
style="{{hiddenUnless selectedSubmissionTypeToolId}}">
|
||||
<div class="pad-box">
|
||||
<div class="ic-Form-control">
|
||||
<button class="Button btn-primary" type="button" id="assignment_submission_type_selection_launch_button">
|
||||
<i class="icon-link sr-hide" />
|
||||
<span id="assignment_submission_type_selection_launch_button_text"></span>
|
||||
<i class="icon-link sr-hide" />
|
||||
<span id="assignment_submission_type_selection_launch_button_text"></span>
|
||||
</button>
|
||||
</div>
|
||||
<input type="hidden" id="assignment_submission_type_external_data" name="external_tool_tag_attributes[external_data]" value="{{externalToolDataStringified}}"/>
|
||||
{{!-- this is very specific to Mastery Connect currently. We could potentially make this a dynamic partial based on the type of external data --}}
|
||||
<input type="hidden" id="assignment_submission_type_external_data" name="external_tool_tag_attributes[external_data]"
|
||||
value="{{externalToolDataStringified}}" />
|
||||
{{!-- this is very specific to Mastery Connect currently. We could potentially make this a dynamic partial
|
||||
based on the type of external data --}}
|
||||
<div>
|
||||
<h2>
|
||||
<span id="mc_external_data_assessment">{{name}}</span>
|
||||
</h2>
|
||||
<div id="mc_external_data_points">{{externalToolData.points}} {{#if externalToolData.points}} {{#t}}Points{{/t}} {{/if}}</div>
|
||||
<div id="mc_external_data_points">{{externalToolData.points}} {{#if externalToolData.points}}
|
||||
{{#t}}Points{{/t}} {{/if}}</div>
|
||||
<div id="mc_external_data_objectives">{{externalToolData.objectives}}</div>
|
||||
<div> </div>
|
||||
<h3>
|
||||
<span id="mc_external_data_tracker">{{externalToolData.trackerName}}</span>
|
||||
</h3>
|
||||
<div id="mc_external_data_tracker_alignment">{{externalToolData.trackerAlignment}}</div>
|
||||
<div id="mc_external_data_students">{{externalToolData.studentCount}} {{externalToolDataStudentLabelText}}</div>
|
||||
<div id="mc_external_data_students">{{externalToolData.studentCount}} {{externalToolDataStudentLabelText}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="assignment_submission_type_selection_tool_dialog"></div>
|
||||
|
||||
{{!-- Default external tool configuration --}}
|
||||
<div id="default_external_tool_container" data-component="DefaultToolForm" style="{{hiddenUnless isNonPlacementExternalTool}}">
|
||||
<div id="default_external_tool_container" data-component="DefaultToolForm"
|
||||
style="{{hiddenUnless isNonPlacementExternalTool}}">
|
||||
</div>
|
||||
|
||||
{{!-- External tool submissions --}}
|
||||
|
@ -217,57 +224,48 @@
|
|||
{{#t}}Enter or find an External Tool URL{{/t}}
|
||||
</label>
|
||||
<input type="hidden" id="assignment_external_tool_tag_attributes_custom_params"
|
||||
name="external_tool_tag_attributes[custom_params]"
|
||||
value="{{externalToolCustomParamsStringified}}" />
|
||||
name="external_tool_tag_attributes[custom_params]" value="{{externalToolCustomParamsStringified}}" />
|
||||
<div class="ic-Input-group">
|
||||
<div class="ic-Input-group__add-on" aria-hidden="true">
|
||||
<i class="icon-link"></i>
|
||||
</div>
|
||||
<input id="assignment_external_tool_tag_attributes_url"
|
||||
class="ic-Input"
|
||||
name="external_tool_tag_attributes[url]"
|
||||
type="url"
|
||||
value="{{externalToolUrl}}"
|
||||
placeholder="http://www.example.com/launch"
|
||||
{{disabledIfIncludes frozenAttributes "submission_types"}}/>
|
||||
<input id="assignment_external_tool_tag_attributes_url" class="ic-Input" name="external_tool_tag_attributes[url]"
|
||||
type="url" value="{{externalToolUrl}}" placeholder="http://www.example.com/launch" {{disabledIfIncludes
|
||||
frozenAttributes "submission_types"}} />
|
||||
<button class="Button" id="assignment_external_tool_tag_attributes_url_find" type="button">
|
||||
{{#t}}Find{{/t}}
|
||||
</button>
|
||||
{{#if submissionTypesFrozen }}
|
||||
<input type="hidden" name="external_tool_tag_attributes[url]" value="{{externalToolUrl}}" />
|
||||
{{#if submissionTypesFrozen}}
|
||||
<input type="hidden" name="external_tool_tag_attributes[url]" value="{{externalToolUrl}}" />
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
<input id="assignment_external_tool_tag_attributes_content_type"
|
||||
name="external_tool_tag_attributes[content_type]"
|
||||
type="text"
|
||||
style="display: none"/>
|
||||
<input id="assignment_external_tool_tag_attributes_content_id"
|
||||
name="external_tool_tag_attributes[content_id]"
|
||||
type="text"
|
||||
style="display: none"/>
|
||||
name="external_tool_tag_attributes[content_type]" type="text" style="display: none" />
|
||||
<input id="assignment_external_tool_tag_attributes_content_id" name="external_tool_tag_attributes[content_id]"
|
||||
type="text" style="display: none" />
|
||||
</div>
|
||||
|
||||
{{#if groupCategoryId}}
|
||||
<div class="alert assignment-edit-external-tool-alert">
|
||||
{{#t "external_tool_group_warning"}}
|
||||
Group assignments can't use External Tools.
|
||||
The group setting will be unchecked when you save
|
||||
{{/t}}
|
||||
</div>
|
||||
<div class="alert assignment-edit-external-tool-alert">
|
||||
{{#t "external_tool_group_warning"}}
|
||||
Group assignments can't use External Tools.
|
||||
The group setting will be unchecked when you save
|
||||
{{/t}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{#unless isQuizLTIAssignment}}
|
||||
<div id="external_tool_new_tab_container" style="display: none;">
|
||||
<label for="assignment_external_tool_tag_attributes_new_tab" class="checkbox">
|
||||
{{checkbox "externalToolNewTab"
|
||||
id="assignment_external_tool_tag_attributes_new_tab"
|
||||
name="external_tool_tag_attributes[new_tab]"
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "label.external_tool_new_tab"}}Load This Tool In A New Tab{{/t}}
|
||||
</label>
|
||||
</div>
|
||||
<div id="external_tool_new_tab_container" style="display: none;">
|
||||
<label for="assignment_external_tool_tag_attributes_new_tab" class="checkbox">
|
||||
{{checkbox "externalToolNewTab"
|
||||
id="assignment_external_tool_tag_attributes_new_tab"
|
||||
name="external_tool_tag_attributes[new_tab]"
|
||||
disabled=submissionTypesFrozen}}
|
||||
{{#t "label.external_tool_new_tab"}}Load This Tool In A New Tab{{/t}}
|
||||
</label>
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
|
@ -0,0 +1,39 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# Copyright (C) 2021 - present Instructure, Inc.
|
||||
#
|
||||
# This file is part of Canvas.
|
||||
#
|
||||
# Canvas is free software: you can redistribute it and/or modify it under
|
||||
# the terms of the GNU Affero General Public License as published by the Free
|
||||
# Software Foundation, version 3 of the License.
|
||||
#
|
||||
# Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
# A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License along
|
||||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
class AddAnnotatableAttachmentIdToAssignments < ActiveRecord::Migration[5.2]
|
||||
tag :predeploy # this migration will run before new app code is deployed
|
||||
disable_ddl_transaction! # don't lock db, don't use transaction
|
||||
|
||||
def change
|
||||
add_reference :assignments,
|
||||
:annotatable_attachment,
|
||||
type: :bigint,
|
||||
foreign_key: {
|
||||
to_table: :attachments
|
||||
},
|
||||
index: false
|
||||
add_index :assignments,
|
||||
:annotatable_attachment_id,
|
||||
where: 'annotatable_attachment_id IS NOT NULL',
|
||||
algorithm: :concurrently,
|
||||
if_not_exists: true
|
||||
end
|
||||
end
|
|
@ -574,6 +574,7 @@ module Api::V1::Assignment
|
|||
"media_recording",
|
||||
"not_graded",
|
||||
"wiki_page",
|
||||
"annotated_document",
|
||||
""
|
||||
].freeze
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
import $ from 'jquery'
|
||||
import React from 'react'
|
||||
import _ from 'underscore'
|
||||
import RCELoader from 'jsx/shared/rce/serviceRCELoader'
|
||||
import SectionCollection from 'compiled/collections/SectionCollection'
|
||||
import Assignment from 'compiled/models/Assignment'
|
||||
|
@ -39,7 +38,7 @@ const s_params = 'some super secure params'
|
|||
const fixtures = document.getElementById('fixtures')
|
||||
const currentOrigin = window.location.origin
|
||||
|
||||
const nameLengthHelper = function(
|
||||
const nameLengthHelper = function (
|
||||
view,
|
||||
length,
|
||||
maxNameLengthRequiredForAccount,
|
||||
|
@ -52,7 +51,7 @@ const nameLengthHelper = function(
|
|||
ENV.MAX_NAME_LENGTH = maxNameLength
|
||||
return view.validateBeforeSave({name, post_to_sis: postToSis, grading_type: gradingType}, [])
|
||||
}
|
||||
const editView = function(assignmentOpts = {}) {
|
||||
const editView = function (assignmentOpts = {}) {
|
||||
const defaultAssignmentOpts = {
|
||||
name: 'Test Assignment',
|
||||
secure_params: s_params,
|
||||
|
@ -144,32 +143,32 @@ QUnit.module('EditView', {
|
|||
}
|
||||
})
|
||||
|
||||
test('should be accessible', function(assert) {
|
||||
test('should be accessible', function (assert) {
|
||||
const view = this.editView()
|
||||
const done = assert.async()
|
||||
assertions.isAccessible(view, done, {a11yReport: true})
|
||||
})
|
||||
|
||||
test('renders', function() {
|
||||
test('renders', function () {
|
||||
const view = this.editView()
|
||||
equal(view.$('#assignment_name').val(), 'Test Assignment')
|
||||
})
|
||||
|
||||
test('rejects missing group set for group assignment', function() {
|
||||
test('rejects missing group set for group assignment', function () {
|
||||
const view = this.editView()
|
||||
const data = {group_category_id: 'blank'}
|
||||
const errors = view.validateBeforeSave(data, [])
|
||||
equal(errors.newGroupCategory[0].message, 'Please create a group set')
|
||||
})
|
||||
|
||||
test('rejects a letter for points_possible', function() {
|
||||
test('rejects a letter for points_possible', function () {
|
||||
const view = this.editView()
|
||||
const data = {points_possible: 'a'}
|
||||
const errors = view.validateBeforeSave(data, [])
|
||||
equal(errors.points_possible[0].message, 'Points possible must be a number')
|
||||
})
|
||||
|
||||
test('validates presence of a final grader', function() {
|
||||
test('validates presence of a final grader', function () {
|
||||
const view = this.editView()
|
||||
sinon.spy(view, 'validateFinalGrader')
|
||||
view.validateBeforeSave({}, [])
|
||||
|
@ -177,7 +176,7 @@ test('validates presence of a final grader', function() {
|
|||
view.validateFinalGrader.restore()
|
||||
})
|
||||
|
||||
test('validates grader count', function() {
|
||||
test('validates grader count', function () {
|
||||
const view = this.editView()
|
||||
sinon.spy(view, 'validateGraderCount')
|
||||
view.validateBeforeSave({}, [])
|
||||
|
@ -185,7 +184,7 @@ test('validates grader count', function() {
|
|||
view.validateGraderCount.restore()
|
||||
})
|
||||
|
||||
test('does not allow group assignment for large rosters', function() {
|
||||
test('does not allow group assignment for large rosters', function () {
|
||||
ENV.IS_LARGE_ROSTER = true
|
||||
const view = this.editView()
|
||||
equal(view.$('#group_category_selector').length, 0)
|
||||
|
@ -201,20 +200,20 @@ test('does not allow group assignment for anonymously graded assignments', () =>
|
|||
strictEqual(hasGroupCategoryCheckbox.prop('disabled'), true)
|
||||
})
|
||||
|
||||
test('does not allow peer review for large rosters', function() {
|
||||
test('does not allow peer review for large rosters', function () {
|
||||
ENV.IS_LARGE_ROSTER = true
|
||||
const view = this.editView()
|
||||
equal(view.$('#assignment_peer_reviews_fields').length, 0)
|
||||
})
|
||||
|
||||
test('adds and removes student group', function() {
|
||||
test('adds and removes student group', function () {
|
||||
ENV.GROUP_CATEGORIES = [{id: 1, name: 'fun group'}]
|
||||
ENV.ASSIGNMENT_GROUPS = [{id: 1, name: 'assignment group 1'}]
|
||||
const view = this.editView()
|
||||
equal(view.assignment.toView().groupCategoryId, null)
|
||||
})
|
||||
|
||||
test('does not allow point value of -1 or less if grading type is letter', function() {
|
||||
test('does not allow point value of -1 or less if grading type is letter', function () {
|
||||
const view = this.editView()
|
||||
const data = {points_possible: '-1', grading_type: 'letter_grade'}
|
||||
const errors = view._validatePointsRequired(data, [])
|
||||
|
@ -224,7 +223,7 @@ test('does not allow point value of -1 or less if grading type is letter', funct
|
|||
)
|
||||
})
|
||||
|
||||
test('requires name to save assignment', function() {
|
||||
test('requires name to save assignment', function () {
|
||||
const view = this.editView()
|
||||
const data = {name: ''}
|
||||
const errors = view.validateBeforeSave(data, [])
|
||||
|
@ -233,7 +232,7 @@ test('requires name to save assignment', function() {
|
|||
equal(errors.name[0].message, 'Name is required!')
|
||||
})
|
||||
|
||||
test('has an error when a name has 257 chars', function() {
|
||||
test('has an error when a name has 257 chars', function () {
|
||||
const view = this.editView()
|
||||
const errors = nameLengthHelper(view, 257, false, 30, '1', 'points')
|
||||
ok(errors.name)
|
||||
|
@ -241,19 +240,19 @@ test('has an error when a name has 257 chars', function() {
|
|||
equal(errors.name[0].message, 'Name is too long, must be under 257 characters')
|
||||
})
|
||||
|
||||
test('allows assignment to save when a name has 256 chars, MAX_NAME_LENGTH is not required and post_to_sis is true', function() {
|
||||
test('allows assignment to save when a name has 256 chars, MAX_NAME_LENGTH is not required and post_to_sis is true', function () {
|
||||
const view = this.editView()
|
||||
const errors = nameLengthHelper(view, 256, false, 30, '1', 'points')
|
||||
equal(errors.length, 0)
|
||||
})
|
||||
|
||||
test('allows assignment to save when a name has 15 chars, MAX_NAME_LENGTH is 10 and is required, post_to_sis is true and grading_type is not_graded', function() {
|
||||
test('allows assignment to save when a name has 15 chars, MAX_NAME_LENGTH is 10 and is required, post_to_sis is true and grading_type is not_graded', function () {
|
||||
const view = this.editView()
|
||||
const errors = nameLengthHelper(view, 15, true, 10, '1', 'not_graded')
|
||||
equal(errors.length, 0)
|
||||
})
|
||||
|
||||
test('has an error when a name has 11 chars, MAX_NAME_LENGTH is 10 and required and post_to_sis is true', function() {
|
||||
test('has an error when a name has 11 chars, MAX_NAME_LENGTH is 10 and required and post_to_sis is true', function () {
|
||||
const view = this.editView()
|
||||
const errors = nameLengthHelper(view, 11, true, 10, '1', 'points')
|
||||
ok(errors.name)
|
||||
|
@ -261,19 +260,19 @@ test('has an error when a name has 11 chars, MAX_NAME_LENGTH is 10 and required
|
|||
equal(errors.name[0].message, 'Name is too long, must be under 11 characters')
|
||||
})
|
||||
|
||||
test('allows assignment to save when name has 11 chars, MAX_NAME_LENGTH is 10 and required, but post_to_sis is false', function() {
|
||||
test('allows assignment to save when name has 11 chars, MAX_NAME_LENGTH is 10 and required, but post_to_sis is false', function () {
|
||||
const view = this.editView()
|
||||
const errors = nameLengthHelper(view, 11, true, 10, '0', 'points')
|
||||
equal(errors.length, 0)
|
||||
})
|
||||
|
||||
test('allows assignment to save when name has 10 chars, MAX_NAME_LENGTH is 10 and required, and post_to_sis is true', function() {
|
||||
test('allows assignment to save when name has 10 chars, MAX_NAME_LENGTH is 10 and required, and post_to_sis is true', function () {
|
||||
const view = this.editView()
|
||||
const errors = nameLengthHelper(view, 10, true, 10, '1', 'points')
|
||||
equal(errors.length, 0)
|
||||
})
|
||||
|
||||
test("don't validate name if it is frozen", function() {
|
||||
test("don't validate name if it is frozen", function () {
|
||||
const view = this.editView()
|
||||
view.model.set('frozen_attributes', ['title'])
|
||||
|
||||
|
@ -281,7 +280,7 @@ test("don't validate name if it is frozen", function() {
|
|||
notOk(errors.name)
|
||||
})
|
||||
|
||||
test('renders a hidden secure_params field', function() {
|
||||
test('renders a hidden secure_params field', function () {
|
||||
const view = this.editView()
|
||||
const secure_params = view.$('#secure_params')
|
||||
|
||||
|
@ -289,7 +288,7 @@ test('renders a hidden secure_params field', function() {
|
|||
equal(secure_params.val(), s_params)
|
||||
})
|
||||
|
||||
test('does show error message on assignment point change with submissions', function() {
|
||||
test('does show error message on assignment point change with submissions', function () {
|
||||
const view = this.editView({has_submitted_submissions: true})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
notOk(view.$el.find('#point_change_warning:visible').attr('aria-expanded'))
|
||||
|
@ -301,7 +300,7 @@ test('does show error message on assignment point change with submissions', func
|
|||
notOk(view.$el.find('#point_change_warning:visible').attr('aria-expanded'))
|
||||
})
|
||||
|
||||
test('does show error message on assignment point change without submissions', function() {
|
||||
test('does show error message on assignment point change without submissions', function () {
|
||||
const view = this.editView({has_submitted_submissions: false})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
notOk(view.$el.find('#point_change_warning:visible').attr('aria-expanded'))
|
||||
|
@ -310,7 +309,7 @@ test('does show error message on assignment point change without submissions', f
|
|||
notOk(view.$el.find('#point_change_warning:visible').attr('aria-expanded'))
|
||||
})
|
||||
|
||||
test('does not allow point value of "" if grading type is letter', function() {
|
||||
test('does not allow point value of "" if grading type is letter', function () {
|
||||
const view = this.editView()
|
||||
const data = {points_possible: '', grading_type: 'letter_grade'}
|
||||
const errors = view._validatePointsRequired(data, [])
|
||||
|
@ -324,7 +323,7 @@ test('does not allow point value of "" if grading type is letter', function() {
|
|||
equal(view.getFormData().groupCategoryId, null)
|
||||
})
|
||||
|
||||
test('does not allow blank external tool url', function() {
|
||||
test('does not allow blank external tool url', function () {
|
||||
const view = this.editView()
|
||||
const data = {submission_type: 'external_tool'}
|
||||
const errors = view._validateExternalTool(data, [])
|
||||
|
@ -334,21 +333,21 @@ test('does not allow blank external tool url', function() {
|
|||
)
|
||||
})
|
||||
|
||||
test('does not allow blank default external tool url', function() {
|
||||
test('does not allow blank default external tool url', function () {
|
||||
const view = this.editView()
|
||||
const data = {submission_type: 'external_tool'}
|
||||
const errors = view._validateExternalTool(data, [])
|
||||
equal(errors['default-tool-launch-button'][0].message, 'External Tool URL cannot be left blank')
|
||||
})
|
||||
|
||||
test('does not validate allowed extensions if file uploads is not a submission type', function() {
|
||||
test('does not validate allowed extensions if file uploads is not a submission type', function () {
|
||||
const view = this.editView()
|
||||
const data = {submission_types: ['online_url'], allowed_extensions: []}
|
||||
const errors = view._validateAllowedExtensions(data, [])
|
||||
equal(errors.allowed_extensions, null)
|
||||
})
|
||||
|
||||
test('removes group_category_id if an external tool is selected', function() {
|
||||
test('removes group_category_id if an external tool is selected', function () {
|
||||
const view = this.editView()
|
||||
let data = {
|
||||
submission_type: 'external_tool',
|
||||
|
@ -358,54 +357,54 @@ test('removes group_category_id if an external tool is selected', function() {
|
|||
equal(data.group_category_id, null)
|
||||
})
|
||||
|
||||
test('renders escaped angle brackets properly', function() {
|
||||
test('renders escaped angle brackets properly', function () {
|
||||
const desc = '<p><E></p>'
|
||||
const view = this.editView({description: '<p><E></p>'})
|
||||
equal(view.$description.val().match(desc), desc)
|
||||
})
|
||||
|
||||
test('routes to discussion details normally', function() {
|
||||
test('routes to discussion details normally', function () {
|
||||
const view = this.editView({html_url: 'http://foo'})
|
||||
equal(view.locationAfterSave({}), 'http://foo')
|
||||
})
|
||||
|
||||
test('routes to return_to', function() {
|
||||
test('routes to return_to', function () {
|
||||
const view = this.editView({html_url: currentOrigin + '/foo'})
|
||||
equal(view.locationAfterSave({return_to: currentOrigin + '/bar'}), currentOrigin + '/bar')
|
||||
})
|
||||
|
||||
test('does not route to return_to with javascript protocol', function() {
|
||||
test('does not route to return_to with javascript protocol', function () {
|
||||
const view = this.editView({html_url: currentOrigin + '/foo'})
|
||||
// eslint-disable-next-line no-script-url
|
||||
equal(view.locationAfterSave({return_to: 'javascript:alert(1)'}), currentOrigin + '/foo')
|
||||
})
|
||||
|
||||
test('cancels to env normally', function() {
|
||||
test('cancels to env normally', function () {
|
||||
ENV.CANCEL_TO = currentOrigin + '/foo'
|
||||
const view = this.editView()
|
||||
equal(view.locationAfterCancel({}), currentOrigin + '/foo')
|
||||
})
|
||||
|
||||
test('cancels to return_to', function() {
|
||||
test('cancels to return_to', function () {
|
||||
ENV.CANCEL_TO = currentOrigin + '/foo'
|
||||
const view = this.editView()
|
||||
equal(view.locationAfterCancel({return_to: currentOrigin + '/bar'}), currentOrigin + '/bar')
|
||||
})
|
||||
|
||||
test('does not cancel to return_to with javascript protocol', function() {
|
||||
test('does not cancel to return_to with javascript protocol', function () {
|
||||
ENV.CANCEL_TO = currentOrigin + '/foo'
|
||||
const view = this.editView()
|
||||
// eslint-disable-next-line no-script-url
|
||||
equal(view.locationAfterCancel({return_to: 'javascript:alert(1)'}), currentOrigin + '/foo')
|
||||
})
|
||||
|
||||
test('does not follow a cross-origin return_to', function() {
|
||||
test('does not follow a cross-origin return_to', function () {
|
||||
ENV.CANCEL_TO = currentOrigin + '/foo'
|
||||
const view = this.editView()
|
||||
equal(view.locationAfterCancel({return_to: 'http://evil.com'}), currentOrigin + '/foo')
|
||||
})
|
||||
|
||||
test('disables fields when inClosedGradingPeriod', function() {
|
||||
test('disables fields when inClosedGradingPeriod', function () {
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
|
||||
|
@ -419,7 +418,7 @@ test('disables fields when inClosedGradingPeriod', function() {
|
|||
equal(view.$el.find('#has_group_category').attr('aria-readonly'), 'true')
|
||||
})
|
||||
|
||||
test('disables grading type field when frozen', function() {
|
||||
test('disables grading type field when frozen', function () {
|
||||
const view = this.editView({frozen_attributes: ['grading_type']})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
|
||||
|
@ -427,14 +426,14 @@ test('disables grading type field when frozen', function() {
|
|||
equal(view.$el.find('input[name="grading_type"]').attr('type'), 'hidden')
|
||||
})
|
||||
|
||||
test('does not disable post to sis when inClosedGradingPeriod', function() {
|
||||
test('does not disable post to sis when inClosedGradingPeriod', function () {
|
||||
ENV.POST_TO_SIS = true
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
notOk(view.$el.find('#assignment_post_to_sis').attr('disabled'))
|
||||
})
|
||||
|
||||
test('disableCheckbox is called for a disabled checkbox', function() {
|
||||
test('disableCheckbox is called for a disabled checkbox', function () {
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
$('<input type="checkbox" id="checkbox_fixture"/>').appendTo($(view.$el))
|
||||
|
@ -445,7 +444,7 @@ test('disableCheckbox is called for a disabled checkbox', function() {
|
|||
equal(disableCheckboxStub.called, true)
|
||||
})
|
||||
|
||||
test('ignoreClickHandler is called for a disabled radio', function() {
|
||||
test('ignoreClickHandler is called for a disabled radio', function () {
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
|
||||
|
@ -459,7 +458,7 @@ test('ignoreClickHandler is called for a disabled radio', function() {
|
|||
equal(ignoreClickHandlerStub.calledOnce, true)
|
||||
})
|
||||
|
||||
test('lockSelectValueHandler is called for a disabled select', function() {
|
||||
test('lockSelectValueHandler is called for a disabled select', function () {
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
view.$el.html('')
|
||||
$('<select id="select_fixture"><option selected>1</option></option>2</option></select>').appendTo(
|
||||
|
@ -473,7 +472,7 @@ test('lockSelectValueHandler is called for a disabled select', function() {
|
|||
equal(lockSelectValueHandlerStub.calledOnce, true)
|
||||
})
|
||||
|
||||
test('lockSelectValueHandler freezes selected value', function() {
|
||||
test('lockSelectValueHandler freezes selected value', function () {
|
||||
const view = this.editView({in_closed_grading_period: true})
|
||||
view.$el.html('')
|
||||
$('<select id="select_fixture"><option selected>1</option></option>2</option></select>').appendTo(
|
||||
|
@ -482,14 +481,11 @@ test('lockSelectValueHandler freezes selected value', function() {
|
|||
view.$el.appendTo($('#fixtures'))
|
||||
|
||||
const selectedValue = view.$el.find('#fixture_select').val()
|
||||
view.$el
|
||||
.find('#fixture_select')
|
||||
.val(2)
|
||||
.trigger('change')
|
||||
view.$el.find('#fixture_select').val(2).trigger('change')
|
||||
equal(view.$el.find('#fixture_select').val(), selectedValue)
|
||||
})
|
||||
|
||||
test('fields are enabled when not inClosedGradingPeriod', function() {
|
||||
test('fields are enabled when not inClosedGradingPeriod', function () {
|
||||
const view = this.editView()
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
|
||||
|
@ -503,14 +499,14 @@ test('fields are enabled when not inClosedGradingPeriod', function() {
|
|||
notOk(view.$el.find('#has_group_category').attr('aria-readonly'))
|
||||
})
|
||||
|
||||
test('rounds points_possible', function() {
|
||||
test('rounds points_possible', function () {
|
||||
const view = this.editView()
|
||||
view.$assignmentPointsPossible.val('1.234')
|
||||
const data = view.getFormData()
|
||||
equal(data.points_possible, 1.23)
|
||||
})
|
||||
|
||||
test('sets seconds of due_at to 59 if the new minute value is 59', function() {
|
||||
test('sets seconds of due_at to 59 if the new minute value is 59', function () {
|
||||
const view = this.editView({
|
||||
due_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:58:23'))
|
||||
})
|
||||
|
@ -519,7 +515,7 @@ test('sets seconds of due_at to 59 if the new minute value is 59', function() {
|
|||
strictEqual(view.getFormData().due_at, '2000-08-28T11:59:59.000Z')
|
||||
})
|
||||
|
||||
test('sets seconds of due_at to 00 if the new minute value is not 59', function() {
|
||||
test('sets seconds of due_at to 00 if the new minute value is not 59', function () {
|
||||
const view = this.editView({
|
||||
due_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:59:23'))
|
||||
})
|
||||
|
@ -531,7 +527,7 @@ test('sets seconds of due_at to 00 if the new minute value is not 59', function(
|
|||
// The UI doesn't allow editing the seconds value and always returns 00. If
|
||||
// the seconds value was set to something different prior to the update, keep
|
||||
// that value.
|
||||
test('keeps original due_at seconds if only the seconds value has changed', function() {
|
||||
test('keeps original due_at seconds if only the seconds value has changed', function () {
|
||||
const view = this.editView({
|
||||
due_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-29T11:59:23'))
|
||||
})
|
||||
|
@ -540,7 +536,7 @@ test('keeps original due_at seconds if only the seconds value has changed', func
|
|||
strictEqual(view.getFormData().due_at, '2000-08-29T11:59:23.000Z')
|
||||
})
|
||||
|
||||
test('keeps original due_at seconds if the date has not changed', function() {
|
||||
test('keeps original due_at seconds if the date has not changed', function () {
|
||||
const view = this.editView({
|
||||
due_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:59:23'))
|
||||
})
|
||||
|
@ -549,7 +545,7 @@ test('keeps original due_at seconds if the date has not changed', function() {
|
|||
strictEqual(view.getFormData().due_at, '2000-08-28T11:59:23.000Z')
|
||||
})
|
||||
|
||||
test('sets seconds of unlock_at to 59 if the new minute value is 59', function() {
|
||||
test('sets seconds of unlock_at to 59 if the new minute value is 59', function () {
|
||||
const view = this.editView({
|
||||
unlock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:58:23'))
|
||||
})
|
||||
|
@ -558,7 +554,7 @@ test('sets seconds of unlock_at to 59 if the new minute value is 59', function()
|
|||
strictEqual(view.getFormData().unlock_at, '2000-08-28T11:59:59.000Z')
|
||||
})
|
||||
|
||||
test('sets seconds of unlock_at to 00 if the new minute value is not 59', function() {
|
||||
test('sets seconds of unlock_at to 00 if the new minute value is not 59', function () {
|
||||
const view = this.editView({
|
||||
unlock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:59:23'))
|
||||
})
|
||||
|
@ -570,7 +566,7 @@ test('sets seconds of unlock_at to 00 if the new minute value is not 59', functi
|
|||
// The UI doesn't allow editing the seconds value and always returns 00. If
|
||||
// the seconds value was set to something different prior to the update, keep
|
||||
// that value.
|
||||
test('keeps original unlock_at seconds if only the seconds value has changed', function() {
|
||||
test('keeps original unlock_at seconds if only the seconds value has changed', function () {
|
||||
const view = this.editView({
|
||||
unlock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-29T11:59:23'))
|
||||
})
|
||||
|
@ -579,7 +575,7 @@ test('keeps original unlock_at seconds if only the seconds value has changed', f
|
|||
strictEqual(view.getFormData().unlock_at, '2000-08-29T11:59:23.000Z')
|
||||
})
|
||||
|
||||
test('keeps original unlock_at seconds if the date has not changed', function() {
|
||||
test('keeps original unlock_at seconds if the date has not changed', function () {
|
||||
const view = this.editView({
|
||||
unlock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:59:23'))
|
||||
})
|
||||
|
@ -588,7 +584,7 @@ test('keeps original unlock_at seconds if the date has not changed', function()
|
|||
strictEqual(view.getFormData().unlock_at, '2000-08-28T11:59:23.000Z')
|
||||
})
|
||||
|
||||
test('sets seconds of lock_at to 59 if the new minute value is 59', function() {
|
||||
test('sets seconds of lock_at to 59 if the new minute value is 59', function () {
|
||||
const view = this.editView({
|
||||
lock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:58:23'))
|
||||
})
|
||||
|
@ -597,7 +593,7 @@ test('sets seconds of lock_at to 59 if the new minute value is 59', function() {
|
|||
strictEqual(view.getFormData().lock_at, '2000-08-28T11:59:59.000Z')
|
||||
})
|
||||
|
||||
test('sets seconds of lock_at to 00 if the new minute value is not 59', function() {
|
||||
test('sets seconds of lock_at to 00 if the new minute value is not 59', function () {
|
||||
const view = this.editView({
|
||||
lock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:59:23'))
|
||||
})
|
||||
|
@ -609,7 +605,7 @@ test('sets seconds of lock_at to 00 if the new minute value is not 59', function
|
|||
// The UI doesn't allow editing the seconds value and always returns 00. If
|
||||
// the seconds value was set to something different prior to the update, keep
|
||||
// that value.
|
||||
test('keeps original lock_at seconds if only the seconds value has changed', function() {
|
||||
test('keeps original lock_at seconds if only the seconds value has changed', function () {
|
||||
const view = this.editView({
|
||||
lock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-29T11:59:23'))
|
||||
})
|
||||
|
@ -618,7 +614,7 @@ test('keeps original lock_at seconds if only the seconds value has changed', fun
|
|||
strictEqual(view.getFormData().lock_at, '2000-08-29T11:59:23.000Z')
|
||||
})
|
||||
|
||||
test('keeps original lock_at seconds if the date has not changed', function() {
|
||||
test('keeps original lock_at seconds if the date has not changed', function () {
|
||||
const view = this.editView({
|
||||
lock_at: $.unfudgeDateForProfileTimezone(new Date('2000-08-28T11:59:23'))
|
||||
})
|
||||
|
@ -658,7 +654,7 @@ QUnit.module('EditView: handleGroupCategoryChange', {
|
|||
}
|
||||
})
|
||||
|
||||
test('unchecks the group category checkbox if the anonymous grading checkbox is checked', function() {
|
||||
test('unchecks the group category checkbox if the anonymous grading checkbox is checked', function () {
|
||||
const view = this.editView()
|
||||
checkCheckbox('assignment_anonymous_grading')
|
||||
checkCheckbox('has_group_category')
|
||||
|
@ -667,7 +663,7 @@ test('unchecks the group category checkbox if the anonymous grading checkbox is
|
|||
strictEqual(groupCategoryCheckbox.checked, false)
|
||||
})
|
||||
|
||||
test('disables the anonymous grading checkbox if the group category checkbox is checked', function() {
|
||||
test('disables the anonymous grading checkbox if the group category checkbox is checked', function () {
|
||||
const view = this.editView()
|
||||
checkCheckbox('has_group_category')
|
||||
view.handleGroupCategoryChange()
|
||||
|
@ -675,7 +671,7 @@ test('disables the anonymous grading checkbox if the group category checkbox is
|
|||
strictEqual(anonymousGradingCheckbox.disabled, true)
|
||||
})
|
||||
|
||||
test('enables the anonymous grading checkbox if the group category checkbox is unchecked', function() {
|
||||
test('enables the anonymous grading checkbox if the group category checkbox is unchecked', function () {
|
||||
const view = this.editView()
|
||||
disableCheckbox('assignment_anonymous_grading')
|
||||
view.handleGroupCategoryChange()
|
||||
|
@ -683,7 +679,7 @@ test('enables the anonymous grading checkbox if the group category checkbox is u
|
|||
strictEqual(anonymousGradingCheckbox.disabled, false)
|
||||
})
|
||||
|
||||
test('calls togglePeerReviewsAndGroupCategoryEnabled', function() {
|
||||
test('calls togglePeerReviewsAndGroupCategoryEnabled', function () {
|
||||
const view = this.editView()
|
||||
sinon.spy(view, 'togglePeerReviewsAndGroupCategoryEnabled')
|
||||
view.handleGroupCategoryChange()
|
||||
|
@ -863,7 +859,7 @@ QUnit.module('EditView: group category inClosedGradingPeriod', {
|
|||
}
|
||||
})
|
||||
|
||||
test('lock down group category after students submit', function() {
|
||||
test('lock down group category after students submit', function () {
|
||||
let view = this.editView({has_submitted_submissions: true})
|
||||
ok(view.$('.group_category_locked_explanation').length)
|
||||
ok(view.$('#has_group_category').prop('disabled'))
|
||||
|
@ -905,7 +901,7 @@ QUnit.module('EditView: enableCheckbox', {
|
|||
}
|
||||
})
|
||||
|
||||
test('enables checkbox', function() {
|
||||
test('enables checkbox', function () {
|
||||
const view = this.editView()
|
||||
sandbox
|
||||
.stub(view.$('#assignment_peer_reviews'), 'parent')
|
||||
|
@ -916,7 +912,7 @@ test('enables checkbox', function() {
|
|||
notOk(view.$('#assignment_peer_reviews').prop('disabled'))
|
||||
})
|
||||
|
||||
test('does nothing if assignment is in closed grading period', function() {
|
||||
test('does nothing if assignment is in closed grading period', function () {
|
||||
const view = this.editView()
|
||||
sandbox.stub(view.assignment, 'inClosedGradingPeriod').returns(true)
|
||||
|
||||
|
@ -951,21 +947,21 @@ QUnit.module('EditView: setDefaultsIfNew', {
|
|||
}
|
||||
})
|
||||
|
||||
test('returns values from localstorage', function() {
|
||||
test('returns values from localstorage', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({submission_types: ['foo']})
|
||||
const view = this.editView()
|
||||
view.setDefaultsIfNew()
|
||||
deepEqual(view.assignment.get('submission_types'), ['foo'])
|
||||
})
|
||||
|
||||
test('returns string booleans as integers', function() {
|
||||
test('returns string booleans as integers', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({peer_reviews: '1'})
|
||||
const view = this.editView()
|
||||
view.setDefaultsIfNew()
|
||||
equal(view.assignment.get('peer_reviews'), 1)
|
||||
})
|
||||
|
||||
test('doesnt overwrite existing assignment settings', function() {
|
||||
test('doesnt overwrite existing assignment settings', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({assignment_group_id: 99})
|
||||
const view = this.editView()
|
||||
view.assignment.set('assignment_group_id', 22)
|
||||
|
@ -973,20 +969,20 @@ test('doesnt overwrite existing assignment settings', function() {
|
|||
equal(view.assignment.get('assignment_group_id'), 22)
|
||||
})
|
||||
|
||||
test('sets assignment submission type to online if not already set', function() {
|
||||
test('sets assignment submission type to online if not already set', function () {
|
||||
const view = this.editView()
|
||||
view.setDefaultsIfNew()
|
||||
deepEqual(view.assignment.get('submission_types'), ['online'])
|
||||
})
|
||||
|
||||
test('doesnt overwrite assignment submission type', function() {
|
||||
test('doesnt overwrite assignment submission type', function () {
|
||||
const view = this.editView()
|
||||
view.assignment.set('submission_types', ['external_tool'])
|
||||
view.setDefaultsIfNew()
|
||||
deepEqual(view.assignment.get('submission_types'), ['external_tool'])
|
||||
})
|
||||
|
||||
test('will overwrite empty arrays', function() {
|
||||
test('will overwrite empty arrays', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({submission_types: ['foo']})
|
||||
const view = this.editView()
|
||||
view.assignment.set('submission_types', [])
|
||||
|
@ -1021,7 +1017,7 @@ QUnit.module('EditView: setDefaultsIfNew: no localStorage', {
|
|||
}
|
||||
})
|
||||
|
||||
test('submission_type is online if no cache', function() {
|
||||
test('submission_type is online if no cache', function () {
|
||||
const view = this.editView()
|
||||
view.setDefaultsIfNew()
|
||||
deepEqual(view.assignment.get('submission_types'), ['online'])
|
||||
|
@ -1053,7 +1049,7 @@ QUnit.module('EditView: cacheAssignmentSettings', {
|
|||
}
|
||||
})
|
||||
|
||||
test('saves valid attributes to localstorage', function() {
|
||||
test('saves valid attributes to localstorage', function () {
|
||||
const view = this.editView()
|
||||
sandbox.stub(view, 'getFormData').returns({points_possible: 34})
|
||||
userSettings.contextSet('new_assignment_settings', {})
|
||||
|
@ -1061,7 +1057,7 @@ test('saves valid attributes to localstorage', function() {
|
|||
equal(34, userSettings.contextGet('new_assignment_settings').points_possible)
|
||||
})
|
||||
|
||||
test('rejects invalid attributes when caching', function() {
|
||||
test('rejects invalid attributes when caching', function () {
|
||||
const view = this.editView()
|
||||
sandbox.stub(view, 'getFormData').returns({invalid_attribute_example: 30})
|
||||
userSettings.contextSet('new_assignment_settings', {})
|
||||
|
@ -1101,19 +1097,19 @@ QUnit.module('EditView: Conditional Release', {
|
|||
}
|
||||
})
|
||||
|
||||
test('attaches conditional release editor', function() {
|
||||
test('attaches conditional release editor', function () {
|
||||
const view = this.editView()
|
||||
equal(1, view.$conditionalReleaseTarget.children().size())
|
||||
})
|
||||
|
||||
test('calls update on first switch', function() {
|
||||
test('calls update on first switch', function () {
|
||||
const view = this.editView()
|
||||
const stub = sandbox.stub(view.conditionalReleaseEditor, 'updateAssignment')
|
||||
view.updateConditionalRelease()
|
||||
ok(stub.calledOnce)
|
||||
})
|
||||
|
||||
test('calls update when modified once', function() {
|
||||
test('calls update when modified once', function () {
|
||||
const view = this.editView()
|
||||
const stub = sandbox.stub(view.conditionalReleaseEditor, 'updateAssignment')
|
||||
view.onChange()
|
||||
|
@ -1121,7 +1117,7 @@ test('calls update when modified once', function() {
|
|||
ok(stub.calledOnce)
|
||||
})
|
||||
|
||||
test('does not call update when not modified', function() {
|
||||
test('does not call update when not modified', function () {
|
||||
const view = this.editView()
|
||||
const stub = sandbox.stub(view.conditionalReleaseEditor, 'updateAssignment')
|
||||
view.updateConditionalRelease()
|
||||
|
@ -1130,7 +1126,7 @@ test('does not call update when not modified', function() {
|
|||
notOk(stub.called)
|
||||
})
|
||||
|
||||
test('validates conditional release', function() {
|
||||
test('validates conditional release', function () {
|
||||
const view = this.editView()
|
||||
ENV.ASSIGNMENT = view.assignment
|
||||
const stub = sandbox.stub(view.conditionalReleaseEditor, 'validateBeforeSave').returns('foo')
|
||||
|
@ -1138,15 +1134,11 @@ test('validates conditional release', function() {
|
|||
ok(errors.conditional_release === 'foo')
|
||||
})
|
||||
|
||||
test('calls save in conditional release', function(assert) {
|
||||
test('calls save in conditional release', function (assert) {
|
||||
const resolved = assert.async()
|
||||
const view = this.editView()
|
||||
const superPromise = $.Deferred()
|
||||
.resolve()
|
||||
.promise()
|
||||
const crPromise = $.Deferred()
|
||||
.resolve()
|
||||
.promise()
|
||||
const superPromise = $.Deferred().resolve().promise()
|
||||
const crPromise = $.Deferred().resolve().promise()
|
||||
const mockSuper = sinon.mock(EditView.__super__)
|
||||
mockSuper.expects('saveFormData').returns(superPromise)
|
||||
const stub = sandbox.stub(view.conditionalReleaseEditor, 'save').returns(crPromise)
|
||||
|
@ -1158,7 +1150,7 @@ test('calls save in conditional release', function(assert) {
|
|||
})
|
||||
})
|
||||
|
||||
test('focuses in conditional release editor if conditional save validation fails', function() {
|
||||
test('focuses in conditional release editor if conditional save validation fails', function () {
|
||||
const view = this.editView()
|
||||
const focusOnError = sandbox.stub(view.conditionalReleaseEditor, 'focusOnError')
|
||||
view.showErrors({conditional_release: {type: 'foo'}})
|
||||
|
@ -1191,7 +1183,7 @@ QUnit.module('Editview: Intra-Group Peer Review toggle', {
|
|||
}
|
||||
})
|
||||
|
||||
test('only appears for group assignments', function() {
|
||||
test('only appears for group assignments', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({
|
||||
peer_reviews: '1',
|
||||
group_category_id: 1,
|
||||
|
@ -1202,7 +1194,7 @@ test('only appears for group assignments', function() {
|
|||
ok(view.$('#intra_group_peer_reviews').is(':visible'))
|
||||
})
|
||||
|
||||
test('does not appear when reviews are being assigned manually', function() {
|
||||
test('does not appear when reviews are being assigned manually', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({
|
||||
peer_reviews: '1',
|
||||
group_category_id: 1
|
||||
|
@ -1212,7 +1204,7 @@ test('does not appear when reviews are being assigned manually', function() {
|
|||
notOk(view.$('#intra_group_peer_reviews').is(':visible'))
|
||||
})
|
||||
|
||||
test('toggle does not appear when there is no group', function() {
|
||||
test('toggle does not appear when there is no group', function () {
|
||||
sandbox.stub(userSettings, 'contextGet').returns({peer_reviews: '1'})
|
||||
const view = this.editView()
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
|
@ -1248,12 +1240,12 @@ QUnit.module('EditView: Assignment Configuration Tools', {
|
|||
}
|
||||
})
|
||||
|
||||
test('it attaches assignment configuration component', function() {
|
||||
test('it attaches assignment configuration component', function () {
|
||||
const view = this.editView()
|
||||
equal(view.$similarityDetectionTools.children().size(), 1)
|
||||
})
|
||||
|
||||
test('it is hidden if submission type is not online with a file upload', function() {
|
||||
test('it is hidden if submission type is not online with a file upload', function () {
|
||||
const view = this.editView()
|
||||
view.$el.appendTo($('#fixtures'))
|
||||
equal(view.$('#similarity_detection_tools').css('display'), 'none')
|
||||
|
@ -1288,7 +1280,7 @@ test('it is hidden if submission type is not online with a file upload', functio
|
|||
equal(view.$('#similarity_detection_tools').css('display'), 'block')
|
||||
})
|
||||
|
||||
test('it is hidden if the plagiarism_detection_platform flag is disabled', function() {
|
||||
test('it is hidden if the plagiarism_detection_platform flag is disabled', function () {
|
||||
ENV.PLAGIARISM_DETECTION_PLATFORM = false
|
||||
const view = this.editView()
|
||||
view.$('#assignment_submission_type').val('online')
|
||||
|
@ -1316,7 +1308,7 @@ QUnit.module('EditView: Assignment External Tools', {
|
|||
}
|
||||
})
|
||||
|
||||
test('it attaches assignment external tools component', function() {
|
||||
test('it attaches assignment external tools component', function () {
|
||||
const view = this.editView()
|
||||
equal(view.$assignmentExternalTools.children().size(), 1)
|
||||
})
|
||||
|
@ -1347,7 +1339,7 @@ QUnit.module('EditView: Quizzes 2', {
|
|||
}
|
||||
})
|
||||
|
||||
test('does not show the description textarea', function() {
|
||||
test('does not show the description textarea', function () {
|
||||
equal(this.view.$description.length, 0)
|
||||
})
|
||||
|
||||
|
@ -1355,7 +1347,7 @@ test('does not show the moderated grading checkbox', () => {
|
|||
equal(document.getElementById('assignment_moderated_grading'), null)
|
||||
})
|
||||
|
||||
test('does not show the load in new tab checkbox', function() {
|
||||
test('does not show the load in new tab checkbox', function () {
|
||||
equal(this.view.$externalToolsNewTab.length, 0)
|
||||
})
|
||||
|
||||
|
@ -1917,3 +1909,51 @@ QUnit.module('EditView#uncheckAndHideGraderAnonymousToGraders', hooks => {
|
|||
strictEqual(isHidden, true)
|
||||
})
|
||||
})
|
||||
|
||||
QUnit.module('EditView annotatable document submission', hooks => {
|
||||
let server
|
||||
let view
|
||||
|
||||
hooks.beforeEach(() => {
|
||||
fixtures.innerHTML = '<span data-component="ModeratedGradingFormFieldGroup"></span>'
|
||||
fakeENV.setup({
|
||||
AVAILABLE_MODERATORS: [],
|
||||
current_user_roles: ['teacher'],
|
||||
HAS_GRADED_SUBMISSIONS: false,
|
||||
LOCALE: 'en',
|
||||
MODERATED_GRADING_ENABLED: true,
|
||||
MODERATED_GRADING_MAX_GRADER_COUNT: 2,
|
||||
VALID_DATE_RANGE: {},
|
||||
use_rce_enhancements: true,
|
||||
COURSE_ID: 1,
|
||||
ANNOTATED_DOCUMENT_SUBMISSIONS: true
|
||||
})
|
||||
server = sinon.fakeServer.create()
|
||||
sandbox.fetch.mock('path:/api/v1/courses/1/lti_apps/launch_definitions', 200)
|
||||
RCELoader.RCE = null
|
||||
return RCELoader.loadRCE()
|
||||
})
|
||||
|
||||
hooks.afterEach(() => {
|
||||
server.restore()
|
||||
fakeENV.teardown()
|
||||
tinymce.remove() // Make sure we clean stuff up
|
||||
$('.ui-dialog').remove()
|
||||
$('ul[id^=ui-id-]').remove()
|
||||
$('.form-dialog').remove()
|
||||
document.getElementById('fixtures').innerHTML = ''
|
||||
})
|
||||
|
||||
test('does not render annotatable document option (flag missing)', function () {
|
||||
ENV.ANNOTATED_DOCUMENT_SUBMISSIONS = false
|
||||
view = editView()
|
||||
equal(view.$('#assignment_annotated_document').length, 0)
|
||||
})
|
||||
|
||||
test('renders annotatable document option (flag turned on)', function () {
|
||||
ENV.ANNOTATED_DOCUMENT_SUBMISSIONS = true
|
||||
view = editView()
|
||||
const label = view.$('#assignment_annotated_document').parent()
|
||||
ok(label.text().includes('Annotated Document'))
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue