Fix some invalid imports

These are all things that were improperly importing either:
* a “default” object when there was only named exports
* a named export when there is only a default export

They work now because we tell babel to transpile es modules down
to commonJS in the “env” preset in babelrc but we want to eventually
not do that and these will need to be fixed before then

Test plan:
* no functionality should actually change in the code generated by
  Webpack
* this build should pass
* but so should the build for the commit that follows this that
  sets the `“modules”: false` option for babel-preset-env in
  .babelrc

Change-Id: Ic6f49fb94ee0d0592ca5e34ef7ed0a5633c40d80
Reviewed-on: https://gerrit.instructure.com/167054
Tested-by: Jenkins
Reviewed-by: Steven Burnett <sburnett@instructure.com>
QA-Review: Ryan Shaw <ryan@instructure.com>
Product-Review: Ryan Shaw <ryan@instructure.com>
This commit is contained in:
Ryan Shaw 2018-10-05 16:52:48 -06:00
parent 3fddcf98e2
commit 52437a1137
45 changed files with 482 additions and 461 deletions

View File

@ -26,7 +26,7 @@ import 'jquery.instructure_misc_plugins' // ifExists, showIf
import 'jquery.loadingImg'
import 'vendor/jquery.scrollTo'
import 'jqueryui/datepicker'
import * as mathml from 'mathml'
import {isMathJaxLoaded, reloadElement, loadMathJax, isMathMLOnPage} from 'mathml'
let specialDatesAreHidden = false
@ -313,11 +313,11 @@ const bindToEditSyllabus = function () {
$course_syllabus.loadingImage('remove').html(data.course.syllabus_body)
$course_syllabus.data('syllabus_body', data.course.syllabus_body)
$course_syllabus_details.hide()
if (mathml.isMathMLOnPage()) {
if (mathml.isMathJaxLoaded()) {
mathml.reloadElement('content')
if (isMathMLOnPage()) {
if (isMathJaxLoaded()) {
reloadElement('content')
} else {
mathml.loadMathJax('MML_HTMLorMML.js')
loadMathJax('MML_HTMLorMML.js')
}
}
},

View File

@ -1,28 +0,0 @@
#
# Copyright (C) 2012 - 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/>.
#
define [
'../models/Folder'
], (Folder) ->
# `FoldersCollection` is actually defined inside of '../models/Folder'
# because RequireJS sucks at figuring out circular dependencies.
# I did exactly what http://requirejs.org/docs/api.html#circular said but the
# load order was still completely arbitrary. By defining them in the same file
# we control the load order exactly and things work--consistently.
return Folder.FoldersCollection

View File

@ -0,0 +1,26 @@
//
// Copyright (C) 2012 - 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 Folder from '../models/Folder'
// `FoldersCollection` is actually defined inside of '../models/Folder'
// because RequireJS sucks at figuring out circular dependencies.
// I did exactly what http://requirejs.org/docs/api.html#circular said but the
// load order was still completely arbitrary. By defining them in the same file
// we control the load order exactly and things work--consistently.
export default Folder.FoldersCollection

View File

@ -22,7 +22,7 @@ import ajax from 'ic-ajax'
import startApp from '../start_app'
import Ember from 'ember'
import fixtures from '../shared_ajax_fixtures'
import GradeCalculatorSpecHelper from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
import {createCourseGradesWithGradingPeriods} from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
import SRGBController from '../../controllers/screenreader_gradebook_controller'
import userSettings from '../../../../userSettings'
import CourseGradeCalculator from 'jsx/gradebook/CourseGradeCalculator'
@ -713,7 +713,7 @@ QUnit.module 'ScreenReader Gradebook', (suiteHooks) ->
}
]
weighted: true
exampleGrades = GradeCalculatorSpecHelper.createCourseGradesWithGradingPeriods()
exampleGrades = createCourseGradesWithGradingPeriods()
initializeApp()
asyncHelper.waitForRequests().then ->
sinon.stub(CourseGradeCalculator, 'calculate').returns(exampleGrades)

View File

@ -1,201 +0,0 @@
#
# Copyright (C) 2012 - 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/>.
define [
'require'
'../models/FilesystemObject'
'vendor/backbone-identity-map'
'../collections/PaginatedCollection'
'../collections/FilesCollection'
'../util/natcompare'
'jsx/shared/helpers/urlHelper'
], (require, FilesystemObject, identityMapMixin, PaginatedCollection, FilesCollection, natcompare, urlHelper) ->
Folder = identityMapMixin class __Folder extends FilesystemObject
defaults:
'name' : ''
initialize: (options) ->
@contentTypes ||= options?.contentTypes
@useVerifiers ||= options?.useVerifiers
@setUpFilesAndFoldersIfNeeded()
@on 'change:sort change:order', @setQueryStringParams
super
url: ->
if @isNew()
super
else
"/api/v1/folders/#{@id}"
parse: (response) ->
json = super
@contentTypes ||= response.contentTypes
@useVerifiers ||= response.useVerifiers
@setUpFilesAndFoldersIfNeeded()
@folders.url = response.folders_url
@files.url = response.files_url
json
setUpFilesAndFoldersIfNeeded: ->
unless @folders
@folders = new FoldersCollection [], parentFolder: this
unless @files
@files = new FilesCollection [], parentFolder: this
getSubtrees: ->
@folders
getItems: ->
@files
expand: (force=false, options={}) ->
@isExpanded = true
@trigger 'expanded'
return $.when() if @expandDfd || force
@isExpanding = true
@trigger 'beginexpanding'
@expandDfd = $.Deferred().done =>
@isExpanding = false
@trigger 'endexpanding'
selfHasntBeenFetched = @folders.url is @folders.constructor::url or @files.url is @files.constructor::url
fetchDfd = @fetch() if selfHasntBeenFetched || force
$.when(fetchDfd).done =>
foldersDfd = @folders.fetch() unless @get('folders_count') is 0
filesDfd = @files.fetch() if (@get('files_count') isnt 0) and !options.onlyShowSubtrees
$.when(foldersDfd, filesDfd).done(@expandDfd.resolve)
collapse: ->
@isExpanded = false
@trigger 'collapsed'
toggle: (options) ->
if @isExpanded
@collapse()
else
@expand(false, options)
previewUrl: ->
if @get('context_type') in ['Course', 'Group']
"/#{ @get('context_type').toLowerCase() + 's' }/#{ @get('context_id') }/files/{{id}}/preview"
isEmpty: ->
!!(@files.loadedAll and (@files.length is 0)) and (@folders.loadedAll and (@folders.length is 0))
# `full_name` will be something like "course files/some folder/another".
# For routing in the react app in the browser, we want something that will take that "course files"
# out. because urls will end up being /courses/2/files/folder/some folder/another
EVERYTHING_BEFORE_THE_FIRST_SLASH = /^[^\/]+\/?/
filesEnv = null
urlPath: ->
relativePath = (@get('full_name') or '').replace(EVERYTHING_BEFORE_THE_FIRST_SLASH, '')
relativePath = urlHelper.encodeSpecialChars(relativePath)
relativePath = relativePath.split('/').map((component) ->
encodeURIComponent(component)
).join('/')
filesEnv ||= require('../react_files/modules/filesEnv') # circular dep
# when we are viewing all files we need to pad the context_asset_string on the front of the url
# so it would be something like /files/folder/users_1/some/sub/folder
if filesEnv.showingAllContexts
assetString = "#{@get('context_type')?.toLowerCase()}s_#{@get('context_id')}"
relativePath = assetString + '/' + relativePath
relativePath
@resolvePath = (contextType, contextId, folderPath) ->
folderPath = urlHelper.decodeSpecialChars(folderPath)
url = "/api/v1/#{contextType}/#{contextId}/folders/by_path#{folderPath}"
$.getJSON(url).pipe (folders) ->
folders.map (folderAttrs) ->
new Folder(folderAttrs, {parse: true})
getSortProp = (model, sortProp) ->
# if we are sorting by name use 'display_name' for files and 'name' for folders.
if sortProp is 'name' and not (model instanceof Folder)
model.get('display_name')
else if sortProp is 'user'
model.get('user')?.display_name || ''
else if sortProp is 'usage_rights'
model.get('usage_rights')?.license_name || ''
else
model.get(sortProp)
##
# Special sorter for handling sorting with special properties
# It's been enhanced to sort naturally when certain sortProps
# are used.
childrenSorter: (sortProp='name', sortOrder='asc', a, b) ->
# Only use natural mode for instances we expect strings in.
naturalMode = sortProp in ['name', 'user', 'usage_rights']
# Get actual values for the properties we are sorting by.
a = getSortProp(a, sortProp)
b = getSortProp(b, sortProp)
if naturalMode
res = natcompare.strings(a, b)
else
res = if a is b
0
else if a > b or a is undefined
1
else if a < b or b is undefined
-1
else
throw new Error("wat? error sorting")
res = 0 - res if sortOrder is 'desc'
res
children: ({sort, order}) ->
(@folders.toArray().concat @files.toArray()).sort(@childrenSorter.bind(null, sort, order))
# FoldersCollection is defined inside of this file, and not where it
# should be, because RequireJS sucks at figuring out circular dependencies.
# '../collections/FoldersCollection' just grabs this and re-exports it.
Folder.FoldersCollection = class FoldersCollection extends PaginatedCollection
@optionProperty 'parentFolder'
model: Folder
parse: (response) ->
if response
response.forEach (folder) =>
folder.contentTypes = @parentFolder.contentTypes
folder.useVerifiers = @parentFolder.useVerifiers
super
return Folder

View File

@ -0,0 +1,253 @@
//
// Copyright (C) 2012 - 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 FilesystemObject from '../models/FilesystemObject'
import identityMapMixin from 'vendor/backbone-identity-map'
import PaginatedCollection from '../collections/PaginatedCollection'
import FilesCollection from '../collections/FilesCollection'
import natcompare from '../util/natcompare'
import urlHelper from 'jsx/shared/helpers/urlHelper'
// `full_name` will be something like "course files/some folder/another".
// For routing in the react app in the browser, we want something that will take that "course files"
// out. because urls will end up being /courses/2/files/folder/some folder/another
const EVERYTHING_BEFORE_THE_FIRST_SLASH = /^[^\/]+\/?/
let filesEnv = null
function getSortProp(model, sortProp) {
// if we are sorting by name use 'display_name' for files and 'name' for folders.
if (sortProp === 'name' && !(model instanceof Folder)) {
return model.get('display_name')
} else if (sortProp === 'user') {
return __guard__(model.get('user'), x => x.display_name) || ''
} else if (sortProp === 'usage_rights') {
return __guard__(model.get('usage_rights'), x1 => x1.license_name) || ''
} else {
return model.get(sortProp)
}
}
class __Folder extends FilesystemObject {
initialize(options) {
if (!this.contentTypes) this.contentTypes = options != null ? options.contentTypes : undefined
if (!this.useVerifiers) this.useVerifiers = options != null ? options.useVerifiers : undefined
this.setUpFilesAndFoldersIfNeeded()
this.on('change:sort change:order', this.setQueryStringParams)
return super.initialize(...arguments)
}
url() {
if (this.isNew()) {
return super.url(...arguments)
} else {
return `/api/v1/folders/${this.id}`
}
}
parse(response) {
const json = super.parse(...arguments)
if (!this.contentTypes) this.contentTypes = response.contentTypes
if (!this.useVerifiers) this.useVerifiers = response.useVerifiers
this.setUpFilesAndFoldersIfNeeded()
this.folders.url = response.folders_url
this.files.url = response.files_url
return json
}
setUpFilesAndFoldersIfNeeded() {
if (!this.folders) {
this.folders = new FoldersCollection([], {parentFolder: this})
}
if (!this.files) {
return (this.files = new FilesCollection([], {parentFolder: this}))
}
}
getSubtrees() {
return this.folders
}
getItems() {
return this.files
}
expand(force = false, options = {}) {
let fetchDfd
this.isExpanded = true
this.trigger('expanded')
if (this.expandDfd || force) {
return $.when()
}
this.isExpanding = true
this.trigger('beginexpanding')
this.expandDfd = $.Deferred().done(() => {
this.isExpanding = false
return this.trigger('endexpanding')
})
const selfHasntBeenFetched =
this.folders.url === this.folders.constructor.prototype.url ||
this.files.url === this.files.constructor.prototype.url
if (selfHasntBeenFetched || force) {
fetchDfd = this.fetch()
}
return $.when(fetchDfd).done(() => {
let filesDfd, foldersDfd
if (this.get('folders_count') !== 0) {
foldersDfd = this.folders.fetch()
}
if (this.get('files_count') !== 0 && !options.onlyShowSubtrees) {
filesDfd = this.files.fetch()
}
return $.when(foldersDfd, filesDfd).done(this.expandDfd.resolve)
})
}
collapse() {
this.isExpanded = false
return this.trigger('collapsed')
}
toggle(options) {
if (this.isExpanded) {
return this.collapse()
} else {
return this.expand(false, options)
}
}
previewUrl() {
let needle
if (((needle = this.get('context_type')), ['Course', 'Group'].includes(needle))) {
return `/${`${this.get('context_type').toLowerCase()}s`}/${this.get(
'context_id'
)}/files/{{id}}/preview`
}
}
isEmpty() {
return (
!!(this.files.loadedAll && this.files.length === 0) &&
(this.folders.loadedAll && this.folders.length === 0)
)
}
urlPath() {
let relativePath = (this.get('full_name') || '').replace(EVERYTHING_BEFORE_THE_FIRST_SLASH, '')
relativePath = urlHelper.encodeSpecialChars(relativePath)
relativePath = relativePath
.split('/')
.map(component => encodeURIComponent(component))
.join('/')
if (!filesEnv) filesEnv = require('../react_files/modules/filesEnv') // circular dep
// when we are viewing all files we need to pad the context_asset_string on the front of the url
// so it would be something like /files/folder/users_1/some/sub/folder
if (filesEnv.showingAllContexts) {
const assetString = `${__guard__(this.get('context_type'), x => x.toLowerCase())}s_${this.get(
'context_id'
)}`
relativePath = `${assetString}/${relativePath}`
}
return relativePath
}
// #
// Special sorter for handling sorting with special properties
// It's been enhanced to sort naturally when certain sortProps
// are used.
childrenSorter(sortProp = 'name', sortOrder = 'asc', a, b) {
// Only use natural mode for instances we expect strings in.
let res
const naturalMode = ['name', 'user', 'usage_rights'].includes(sortProp)
// Get actual values for the properties we are sorting by.
a = getSortProp(a, sortProp)
b = getSortProp(b, sortProp)
if (naturalMode) {
res = natcompare.strings(a, b)
} else {
res = (() => {
if (a === b) {
return 0
} else if (a > b || a === undefined) {
return 1
} else if (a < b || b === undefined) {
return -1
} else {
throw new Error('wat? error sorting')
}
})()
}
if (sortOrder === 'desc') {
res = 0 - res
}
return res
}
children({sort, order}) {
return this.folders
.toArray()
.concat(this.files.toArray())
.sort(this.childrenSorter.bind(null, sort, order))
}
}
__Folder.resolvePath = function(contextType, contextId, folderPath) {
folderPath = urlHelper.decodeSpecialChars(folderPath)
const url = `/api/v1/${contextType}/${contextId}/folders/by_path${folderPath}`
return $.getJSON(url).pipe(folders =>
folders.map(folderAttrs => new Folder(folderAttrs, {parse: true}))
)
}
__Folder.prototype.defaults = {name: ''}
const Folder = identityMapMixin(__Folder)
export default Folder
class FoldersCollection extends PaginatedCollection {
static initClass() {
this.optionProperty('parentFolder')
this.prototype.model = Folder
}
parse(response) {
if (response) {
response.forEach(folder => {
folder.contentTypes = this.parentFolder.contentTypes
return (folder.useVerifiers = this.parentFolder.useVerifiers)
})
}
return super.parse(...arguments)
}
}
FoldersCollection.initClass()
// FoldersCollection is defined inside of this file, and not where it
// should be, because RequireJS sucks at figuring out circular dependencies.
// '../collections/FoldersCollection' just grabs this and re-exports it.
Folder.FoldersCollection = FoldersCollection
function __guard__(value, transform) {
return typeof value !== 'undefined' && value !== null ? transform(value) : undefined
}

View File

@ -25,9 +25,9 @@ import IconBlueprintLine from '@instructure/ui-icons/lib/Line/IconBlueprint'
import IconPlusLine from '@instructure/ui-icons/lib/Line/IconPlus'
import IconSettingsLine from '@instructure/ui-icons/lib/Line/IconSettings'
import IconStatsLine from '@instructure/ui-icons/lib/Line/IconStats'
import {get} from 'axios'
import axios from 'axios'
import {uniqBy} from 'lodash'
import {flashMessage} from 'compiled/jquery.rails_flash_notifications'
import $ from 'compiled/jquery.rails_flash_notifications'
import I18n from 'i18n!account_course_user_search'
import UserLink from './UserLink'
import AddPeopleApp from '../../add_people/add_people_app'
@ -65,7 +65,7 @@ export default class CoursesListRow extends React.Component {
getSections = () =>
this.promiseToGetSections ||
(this.promiseToGetSections = get(
(this.promiseToGetSections = axios.get(
`/api/v1/courses/${this.props.id}/sections?per_page=100`
)).then(resp => resp.data)
@ -73,7 +73,7 @@ export default class CoursesListRow extends React.Component {
handleNewEnrollments = newEnrollments => {
if (newEnrollments && newEnrollments.length) {
flashMessage({
$.flashMessage({
html: I18n.t(
{
one: '%{user_name} successfully enrolled into *%{course_name}*.',

View File

@ -20,7 +20,7 @@ import React from 'react'
import ReactDOM from 'react-dom'
import DashboardCardBox from '../dashboard_card/DashboardCardBox'
import getDroppableDashboardCardBox from '../dashboard_card/getDroppableDashboardCardBox'
import {get} from 'axios'
import axios from 'axios'
let promiseToGetDashboardCards
@ -46,7 +46,7 @@ export default function loadCardDashboard () {
if (cachedCards) render(JSON.parse(cachedCards))
if (!promiseToGetDashboardCards) {
promiseToGetDashboardCards = get('/dashboard/dashboard_cards').then(({data}) => data)
promiseToGetDashboardCards = axios.get('/dashboard/dashboard_cards').then(({data}) => data)
promiseToGetDashboardCards.then((dashboardCards) =>
sessionStorage.setItem(sessionStorageKey, JSON.stringify(dashboardCards))
)

View File

@ -22,7 +22,6 @@ import GettingStartedCollaborations from '../collaborations/GettingStartedCollab
import CollaborationsNavigation from '../collaborations/CollaborationsNavigation'
import CollaborationsList from './CollaborationsList'
import LoadingSpinner from './LoadingSpinner'
import { dispatch } from './store/store'
class CollaborationsApp extends React.Component {
constructor (props) {

View File

@ -21,7 +21,7 @@ import ReactDOM from 'react-dom'
import PropTypes from 'prop-types'
import Collaboration from './Collaboration'
import LoadMore from '../shared/load-more'
import { dispatch } from './store/store'
import store from './store/store'
class CollaborationsList extends React.Component {
@ -32,7 +32,7 @@ import { dispatch } from './store/store'
loadMoreCollaborations () {
ReactDOM.findDOMNode(this.refs[`collaboration-${this.props.collaborationsState.list.length - 1}`]).focus();
dispatch(this.props.getCollaborations(this.props.collaborationsState.nextPage));
store.dispatch(this.props.getCollaborations(this.props.collaborationsState.nextPage));
}
render () {

View File

@ -19,12 +19,12 @@
import 'jquery.instructure_date_and_time'
import parseLinkHeader from '../../shared/parseLinkHeader';
const FETCH_HISTORY_START = 'FETCH_HISTORY_START';
const FETCH_HISTORY_SUCCESS = 'FETCH_HISTORY_SUCCESS';
const FETCH_HISTORY_FAILURE = 'FETCH_HISTORY_FAILURE';
const FETCH_HISTORY_NEXT_PAGE_START = 'FETCH_HISTORY_NEXT_PAGE_START';
const FETCH_HISTORY_NEXT_PAGE_SUCCESS = 'FETCH_HISTORY_NEXT_PAGE_SUCCESS';
const FETCH_HISTORY_NEXT_PAGE_FAILURE = 'FETCH_HISTORY_NEXT_PAGE_FAILURE';
export const FETCH_HISTORY_START = 'FETCH_HISTORY_START';
export const FETCH_HISTORY_SUCCESS = 'FETCH_HISTORY_SUCCESS';
export const FETCH_HISTORY_FAILURE = 'FETCH_HISTORY_FAILURE';
export const FETCH_HISTORY_NEXT_PAGE_START = 'FETCH_HISTORY_NEXT_PAGE_START';
export const FETCH_HISTORY_NEXT_PAGE_SUCCESS = 'FETCH_HISTORY_NEXT_PAGE_SUCCESS';
export const FETCH_HISTORY_NEXT_PAGE_FAILURE = 'FETCH_HISTORY_NEXT_PAGE_FAILURE';
function indexById (collection = []) {
return collection.reduce((acc, item) => {
@ -78,13 +78,13 @@ function formatHistoryItems (data) {
});
}
function fetchHistoryStart () {
export function fetchHistoryStart () {
return {
type: FETCH_HISTORY_START
};
}
function fetchHistorySuccess ({ events, linked: { assignments, users }}, { link }) {
export function fetchHistorySuccess ({ events, linked: { assignments, users }}, { link }) {
return {
type: FETCH_HISTORY_SUCCESS,
payload: {
@ -94,19 +94,19 @@ function fetchHistorySuccess ({ events, linked: { assignments, users }}, { link
};
}
function fetchHistoryFailure () {
export function fetchHistoryFailure () {
return {
type: FETCH_HISTORY_FAILURE
};
}
function fetchHistoryNextPageStart () {
export function fetchHistoryNextPageStart () {
return {
type: FETCH_HISTORY_NEXT_PAGE_START
};
}
function fetchHistoryNextPageSuccess ({ events, linked: { assignments, users }}, { link }) {
export function fetchHistoryNextPageSuccess ({ events, linked: { assignments, users }}, { link }) {
return {
type: FETCH_HISTORY_NEXT_PAGE_SUCCESS,
payload: {
@ -116,23 +116,8 @@ function fetchHistoryNextPageSuccess ({ events, linked: { assignments, users }},
};
}
function fetchHistoryNextPageFailure () {
export function fetchHistoryNextPageFailure () {
return {
type: FETCH_HISTORY_NEXT_PAGE_FAILURE
};
}
export default {
FETCH_HISTORY_START,
FETCH_HISTORY_SUCCESS,
FETCH_HISTORY_FAILURE,
FETCH_HISTORY_NEXT_PAGE_START,
FETCH_HISTORY_NEXT_PAGE_SUCCESS,
FETCH_HISTORY_NEXT_PAGE_FAILURE,
fetchHistoryStart,
fetchHistorySuccess,
fetchHistoryFailure,
fetchHistoryNextPageStart,
fetchHistoryNextPageSuccess,
fetchHistoryNextPageFailure,
};

View File

@ -17,7 +17,7 @@
*/
import AssignmentApi from '../../gradebook-history/api/AssignmentApi';
import HistoryActions from '../../gradebook-history/actions/HistoryActions';
import * as HistoryActions from '../../gradebook-history/actions/HistoryActions';
import HistoryApi from '../../gradebook-history/api/HistoryApi';
import UserApi from '../../gradebook-history/api/UserApi';
import environment from '../../gradebook-history/environment';

View File

@ -16,10 +16,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import HistoryActions from '../../gradebook-history/actions/HistoryActions';
import * as HistoryActions from '../../gradebook-history/actions/HistoryActions';
import HistoryApi from '../../gradebook-history/api/HistoryApi';
function getHistoryNextPage (url) {
export function getHistoryNextPage (url) {
return function (dispatch) {
dispatch(HistoryActions.fetchHistoryNextPageStart());
@ -31,8 +31,4 @@ function getHistoryNextPage (url) {
dispatch(HistoryActions.fetchHistoryNextPageFailure());
});
};
}
export default {
getHistoryNextPage
};
}

View File

@ -17,15 +17,13 @@
*/
import React from 'react'
import PropTypes from 'prop-types'
import { bool, func, shape, string } from 'prop-types'
import ReactDOM from 'react-dom'
import $ from 'jquery'
import I18n from 'i18n!modules'
import PostGradesDialog from '../../gradezilla/SISGradePassback/PostGradesDialog'
import classnames from 'classnames'
const { bool, func, shape, string } = PropTypes
// The PostGradesApp mounts a single "Sync Grades" button, which pops up
// the PostGradesDialog when clicked.
class PostGradesApp extends React.Component {

View File

@ -16,7 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Grid } from 'vendor/slickgrid';
import slickgrid from 'vendor/slickgrid';
import 'jqueryui/sortable';
import CellEditorFactory from './editors/CellEditorFactory'
import CellFormatterFactory from './formatters/CellFormatterFactory'
@ -53,7 +53,7 @@ export default class GradebookGrid {
this.gridData.columns.definitions[columnId]
));
this.grid = new Grid(this.options.$container, this.gridData.rows, columns, options);
this.grid = new slickgrid.Grid(this.options.$container, this.gridData.rows, columns, options);
const gridSupportOptions = {
activeBorderColor: this.options.activeBorderColor,

View File

@ -19,7 +19,7 @@
import axios from 'axios';
import { camelize, underscore } from 'convert_case';
const DEFAULT_LATE_POLICY_DATA = Object.freeze({
export const DEFAULT_LATE_POLICY_DATA = Object.freeze({
lateSubmissionDeductionEnabled: false,
lateSubmissionDeduction: 0,
lateSubmissionInterval: 'day',
@ -35,7 +35,7 @@ function camelizeLatePolicyResponseData (latePolicyResponseData) {
return { latePolicy: camelizedData };
}
function fetchLatePolicy (courseId) {
export function fetchLatePolicy (courseId) {
const url = `/api/v1/courses/${courseId}/late_policy`;
return axios.get(url)
.then(response => (
@ -52,7 +52,7 @@ function fetchLatePolicy (courseId) {
});
}
function createLatePolicy (courseId, latePolicyData) {
export function createLatePolicy (courseId, latePolicyData) {
const url = `/api/v1/courses/${courseId}/late_policy`;
const data = { late_policy: underscore(latePolicyData) };
return axios.post(url, data).then(response => (
@ -60,7 +60,7 @@ function createLatePolicy (courseId, latePolicyData) {
));
}
function updateLatePolicy (courseId, latePolicyData) {
export function updateLatePolicy (courseId, latePolicyData) {
const url = `/api/v1/courses/${courseId}/late_policy`;
const data = { late_policy: underscore(latePolicyData) };
return axios.patch(url, data);

View File

@ -24,7 +24,7 @@ import Button from '@instructure/ui-buttons/lib/components/Button'
import Menu, { MenuItem, MenuItemSeparator } from '@instructure/ui-menu/lib/components/Menu'
import Text from '@instructure/ui-elements/lib/components/Text'
import GradebookExportManager from '../../../gradezilla/shared/GradebookExportManager'
import { AppLaunch } from '../../../gradezilla/SISGradePassback/PostGradesApp'
import PostGradesApp from '../../../gradezilla/SISGradePassback/PostGradesApp'
import tz from 'timezone'
import DateHelper from '../../../shared/helpers/dateHelper'
import I18n from 'i18n!gradebook'
@ -195,7 +195,7 @@ const { arrayOf, bool, func, object, shape, string } = PropTypes;
launchPostGrades () {
const { store, returnFocusTo } = this.props.postGradesFeature;
setTimeout(() => AppLaunch(store, returnFocusTo), 10);
setTimeout(() => PostGradesApp.AppLaunch(store, returnFocusTo), 10);
}
renderPostGradesTools () {

View File

@ -18,7 +18,7 @@
import Color from 'tinycolor2';
const defaultColors = {
export const defaultColors = {
salmon: '#FFE8E5',
orange: '#FEF0E5',
yellow: '#FEF7E5',
@ -39,19 +39,13 @@ const defaultStatusColors = {
resubmitted: defaultColors.green
};
function statusColors (userColors = {}) {
export function statusColors (userColors = {}) {
return {
...defaultStatusColors,
...userColors
};
}
function darken (color, percent) {
export function darken (color, percent) {
return Color(color).darken(percent);
}
export default {
defaultColors,
statusColors,
darken
};

View File

@ -18,7 +18,7 @@
import I18n from 'i18n!gradebook';
const statuses = [
export const statuses = [
'late',
'missing',
'resubmitted',
@ -26,7 +26,7 @@ const statuses = [
'excused'
];
const statusesTitleMap = {
export const statusesTitleMap = {
late: I18n.t('Late'),
missing: I18n.t('Missing'),
resubmitted: I18n.t('Resubmitted'),
@ -34,8 +34,3 @@ const statusesTitleMap = {
excused: I18n.t('Excused')
};
export default {
statuses,
statusesTitleMap
};

View File

@ -18,38 +18,38 @@
import GRADEBOOK_TRANSLATIONS from 'compiled/gradebook/GradebookTranslations'
const MULTIPLIER = 1.5;
const MULTIPLIER = 1.5
const isNegativePoints = function(score) {
return score < 0;
};
function isNegativePoints (score) {
return score < 0
}
const isUnusuallyHigh = function(score, pointsPossible) {
if (pointsPossible === 0 || pointsPossible == null) { return false; }
const outlierBoundary = pointsPossible * MULTIPLIER;
return score >= outlierBoundary;
};
export function isUnusuallyHigh(score, pointsPossible) {
if (pointsPossible === 0 || pointsPossible == null) {
return false
}
const outlierBoundary = pointsPossible * MULTIPLIER
return score >= outlierBoundary
}
class OutlierScoreHelper {
constructor(score, pointsPossible) {
this.score = score;
this.pointsPossible = pointsPossible;
export default class OutlierScoreHelper {
constructor(score, pointsPossible) {
this.score = score
this.pointsPossible = pointsPossible
}
hasWarning() {
// mutually exclusive
return isNegativePoints(this.score) || isUnusuallyHigh(this.score, this.pointsPossible)
}
warningMessage() {
if (isNegativePoints(this.score)) {
return GRADEBOOK_TRANSLATIONS.submission_negative_points_warning
} else if (isUnusuallyHigh(this.score, this.pointsPossible)) {
return GRADEBOOK_TRANSLATIONS.submission_too_many_points_warning
} else {
return null
}
hasWarning() {
// mutually exclusive
return isNegativePoints(this.score) || isUnusuallyHigh(this.score, this.pointsPossible);
}
warningMessage() {
if (isNegativePoints(this.score)) {
return GRADEBOOK_TRANSLATIONS.submission_negative_points_warning;
} else if (isUnusuallyHigh(this.score, this.pointsPossible)) {
return GRADEBOOK_TRANSLATIONS.submission_too_many_points_warning;
} else {
return null;
}
}
};
export { OutlierScoreHelper as default, isUnusuallyHigh }
}
}

View File

@ -27,7 +27,7 @@ import CloseButton from '@instructure/ui-buttons/lib/components/CloseButton'
import IconGroup from '@instructure/ui-icons/lib/Line/IconGroup'
import Spinner from '@instructure/ui-elements/lib/components/Spinner'
import PresentationContent from '@instructure/ui-a11y/lib/components/PresentationContent'
import {post} from 'axios'
import axios from 'axios'
import {string} from 'prop-types'
export default class GeneratePairingCode extends Component {
@ -50,7 +50,7 @@ export default class GeneratePairingCode extends Component {
generatePairingCode = () => {
this.setState({ gettingPairingCode: true, pairingCodeError: false })
post(`/api/v1/users/${this.props.userId}/observer_pairing_codes`)
axios.post(`/api/v1/users/${this.props.userId}/observer_pairing_codes`)
.then(({ data }) => {
this.setState({
gettingPairingCode: false,

View File

@ -168,6 +168,8 @@ module.exports = {
],
exclude: [
path.resolve(__dirname, '../public/javascripts/translations'),
path.resolve(__dirname, '../public/javascripts/react-dnd-test-backend'),
path.resolve(__dirname, '../public/javascripts/lodash.underscore'),
/bower\//,
],
loaders: happify('babel', [

View File

@ -21,12 +21,12 @@
// back a Backbone with all of our instructure specific patches to it.
// Get the unpatched Backbone
import Backbone from 'node_modules-version-of-backbone'
const Backbone = require('node_modules-version-of-backbone')
// Apply all of our patches
import 'compiled/backbone-ext/Backbone.syncWithMultipart'
import 'compiled/backbone-ext/Model'
import 'compiled/backbone-ext/View'
import 'compiled/backbone-ext/Collection'
require('compiled/backbone-ext/Backbone.syncWithMultipart')
require('compiled/backbone-ext/Model')
require('compiled/backbone-ext/View')
require('compiled/backbone-ext/Collection')
export default Backbone
module.exports = Backbone

View File

@ -22,7 +22,7 @@ import PublishCloud from 'jsx/shared/PublishCloud'
import ModuleDuplicationSpinner from 'jsx/modules/components/ModuleDuplicationSpinner'
import React from 'react'
import ReactDOM from 'react-dom'
import * as MoveItem from 'jsx/move_item'
import {reorderElements, renderTray} from 'jsx/move_item'
import PublishableModuleItem from 'compiled/models/PublishableModuleItem'
import PublishIconView from 'compiled/views/PublishIconView'
import LockIconView from 'compiled/views/LockIconView'
@ -1275,13 +1275,13 @@ function scrollTo ($thing, time = 500) {
$container[0].appendChild(item)
const order = data.context_module.content_tags.map(item => item.content_tag.id)
MoveItem.reorderElements(order, $container[0], id => `#context_module_item_${id}`)
reorderElements(order, $container[0], id => `#context_module_item_${id}`)
$container.sortable('enable').sortable('refresh')
},
focusOnExit: () => currentItem.querySelector('.al-trigger'),
}
MoveItem.renderTray(moveTrayProps, document.getElementById('not_right_side'))
renderTray(moveTrayProps, document.getElementById('not_right_side'))
})
$('.move_module_link').on('click keyclick', function (event) {

View File

@ -197,7 +197,7 @@ import YouTubeApi from './youtube_api'
var $editor = $box.data('editor');
var $target = $(event.target);
event.preventDefault();
RceCommandShim.send($editor, 'insert_code', buttonToImg($target));
send($editor, 'insert_code', buttonToImg($target));
$box.dialog('close');
});
// http://img.youtube.com/vi/BOegH4uYe-c/3.jpg

View File

@ -18,8 +18,7 @@
////
// if you want underscore in your code. require 'underscore' (this file)
import _ from 'vendor/lodash.underscore'
const _ = require('vendor/lodash.underscore')
// grab the global '_' variable, make it not global and return it
export default _.noConflict();
module.exports = _.noConflict();

View File

@ -1,6 +1,6 @@
import $ from 'jquery'
import h from '../../str/htmlEscape'
import returnValOfUnpatchedDialog from 'jqueryui/dialog-unpatched'
import 'jqueryui/dialog-unpatched'
// have UI dialogs default to modal:true
$.ui.dialog.prototype.options.modal = true
@ -41,5 +41,3 @@ import returnValOfUnpatchedDialog from 'jqueryui/dialog-unpatched'
return setOption.call(this, key, value);
}
});
export default returnValOfUnpatchedDialog;

View File

@ -1,4 +1,2 @@
import returnValueOfUnpatchedDraggable from 'jqueryui/draggable-unpatched'
import 'jqueryui/draggable-unpatched'
import 'jquery-ui-touch-punch'
export default returnValueOfUnpatchedDraggable

View File

@ -1,36 +1,38 @@
import $ from 'jquery'
import returnValueOfUnpatchedWidget from 'jqueryui/widget-unpatched'
import 'jqueryui/widget-unpatched'
// This function is the same as $.widget.extend
// except for this additional check on the target:
// && $.isPlainObject(target[key])
//
// The change is because it was merging strings and objects
// which caused problems. Here's an example of what it was doing:
// $.widget.extend({}, {handle: 'e,s,se'}, {handle: {s: 'div.ui-resizable-s'}})
// => {0: 'e',
// 1: ',',
// 2: 's',
// 3: ',',
// 4: 's',
// 5: 'e',
// s: 'div.ui-resizable-s'}
$.widget.extend = function( target ) {
var input = Array.prototype.slice.call( arguments, 1 ),
// This function is the same as $.widget.extend
// except for this additional check on the target:
// && $.isPlainObject(target[key])
//
// The change is because it was merging strings and objects
// which caused problems. Here's an example of what it was doing:
// $.widget.extend({}, {handle: 'e,s,se'}, {handle: {s: 'div.ui-resizable-s'}})
// => {0: 'e',
// 1: ',',
// 2: 's',
// 3: ',',
// 4: 's',
// 5: 'e',
// s: 'div.ui-resizable-s'}
$.widget.extend = function(target) {
var input = Array.prototype.slice.call(arguments, 1),
inputIndex = 0,
inputLength = input.length,
key,
value;
for ( ; inputIndex < inputLength; inputIndex++ ) {
for ( key in input[ inputIndex ] ) {
value = input[ inputIndex ][ key ];
if (input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
target[ key ] = $.isPlainObject( value ) && $.isPlainObject(target[key]) ? $.widget.extend( {}, target[ key ], value ) : value;
}
value
for (; inputIndex < inputLength; inputIndex++) {
for (key in input[inputIndex]) {
value = input[inputIndex][key]
if (input[inputIndex].hasOwnProperty(key) && value !== undefined) {
target[key] =
$.isPlainObject(value) && $.isPlainObject(target[key])
? $.widget.extend({}, target[key], value)
: value
}
}
return target;
};
export default returnValueOfUnpatchedWidget;
}
return target
}
export default $

View File

@ -21,7 +21,7 @@ import UnassignedGroupUserCollection from 'compiled/collections/UnassignedGroupU
import GroupCategory from 'compiled/models/GroupCategory'
import GroupUser from 'compiled/models/GroupUser'
import Group from 'compiled/models/Group'
import {Collection} from 'Backbone'
import Backbone from 'Backbone'
let source = null
let target = null
@ -32,7 +32,7 @@ QUnit.module('GroupUserCollection', {
setup() {
group = new Group({id: 1})
const category = new GroupCategory()
category._groups = new Collection([group])
category._groups = new Backbone.Collection([group])
users = [
new GroupUser({
id: 1,

View File

@ -16,7 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import GradeCalculatorSpecHelper from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
import {createCourseGradesWithGradingPeriods as createExampleGrades} from 'spec/jsx/gradebook/GradeCalculatorSpecHelper'
import Gradebook from 'compiled/gradebook/Gradebook'
import DataLoader from 'jsx/gradebook/DataLoader'
import _ from 'underscore'
@ -43,8 +43,6 @@ const exampleGradebookOptions = {
sections: []
}
const createExampleGrades = GradeCalculatorSpecHelper.createCourseGradesWithGradingPeriods
QUnit.module('Gradebook')
test('normalizes the grading period set from the env', function() {

View File

@ -16,7 +16,7 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
module.exports = {
export default {
setup(options = {}) {
if (!window.ENV) window.ENV = {}

View File

@ -18,7 +18,7 @@
import environment from 'jsx/gradebook-history/environment';
import GradebookHistoryStore from 'jsx/gradebook-history/store/GradebookHistoryStore';
import HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
import * as HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
import HistoryApi from 'jsx/gradebook-history/api/HistoryApi';
import SearchFormActions, {
CLEAR_RECORDS,

View File

@ -18,9 +18,9 @@
import Fixtures from '../../gradebook-history/Fixtures';
import GradebookHistoryStore from 'jsx/gradebook-history/store/GradebookHistoryStore';
import HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
import * as HistoryActions from 'jsx/gradebook-history/actions/HistoryActions';
import HistoryApi from 'jsx/gradebook-history/api/HistoryApi';
import SearchResultsActions from 'jsx/gradebook-history/actions/SearchResultsActions';
import * as SearchResultsActions from 'jsx/gradebook-history/actions/SearchResultsActions';
QUnit.module('SearchResultsActionsSpec getHistoryNextPage', {
setup () {

View File

@ -16,61 +16,57 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
const GradeCalculatorSpecHelper = {
createCourseGradesWithGradingPeriods() {
return {
assignmentGroups: {
301: {
assignmentGroupId: 301,
assignmentGroupWeight: 40,
current: {score: 5, possible: 10, submissions: []},
final: {score: 5, possible: 20, submissions: []}
},
302: {
assignmentGroupId: 302,
assignmentGroupWeight: 60,
current: {score: 12, possible: 15, submissions: []},
final: {score: 12, possible: 25, submissions: []}
}
export function createCourseGradesWithGradingPeriods() {
return {
assignmentGroups: {
301: {
assignmentGroupId: 301,
assignmentGroupWeight: 40,
current: {score: 5, possible: 10, submissions: []},
final: {score: 5, possible: 20, submissions: []}
},
gradingPeriods: {
701: {
gradingPeriodId: 701,
gradingPeriodWeight: 25,
assignmentGroups: {
301: {
assignmentGroupId: 301,
assignmentGroupWeight: 40,
current: {score: 5, possible: 10, submissions: []},
final: {score: 5, possible: 20, submissions: []}
}
},
current: {score: 5, possible: 10, submissions: []},
final: {score: 5, possible: 20, submissions: []}
},
302: {
assignmentGroupId: 302,
assignmentGroupWeight: 60,
current: {score: 12, possible: 15, submissions: []},
final: {score: 12, possible: 25, submissions: []}
}
},
702: {
gradingPeriodId: 702,
gradingPeriodWeight: 75,
assignmentGroups: {
302: {
assignmentGroupId: 302,
assignmentGroupWeight: 60,
current: {score: 12, possible: 15, submissions: []},
final: {score: 12, possible: 25, submissions: []}
}
},
current: {score: 12, possible: 15, submissions: []},
final: {score: 12, possible: 25, submissions: []}
}
gradingPeriods: {
701: {
gradingPeriodId: 701,
gradingPeriodWeight: 25,
assignmentGroups: {
301: {
assignmentGroupId: 301,
assignmentGroupWeight: 40,
current: {score: 5, possible: 10, submissions: []},
final: {score: 5, possible: 20, submissions: []}
}
},
current: {score: 5, possible: 10, submissions: []},
final: {score: 5, possible: 20, submissions: []}
},
current: {score: 17, possible: 25, submissions: []},
final: {score: 17, possible: 45, submissions: []}
}
702: {
gradingPeriodId: 702,
gradingPeriodWeight: 75,
assignmentGroups: {
302: {
assignmentGroupId: 302,
assignmentGroupWeight: 60,
current: {score: 12, possible: 15, submissions: []},
final: {score: 12, possible: 25, submissions: []}
}
},
current: {score: 12, possible: 15, submissions: []},
final: {score: 12, possible: 25, submissions: []}
}
},
current: {score: 17, possible: 25, submissions: []},
final: {score: 17, possible: 45, submissions: []}
}
}
export default GradeCalculatorSpecHelper

View File

@ -17,10 +17,12 @@
*/
import $ from 'jquery';
import { Editors, Grid } from 'vendor/slickgrid';
import slickgrid from 'vendor/slickgrid';
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
import SlickGridSpecHelper from './SlickGridSpecHelper'
const { Editors, Grid } = slickgrid
function createColumns () {
return [1, 2, 3, 4].map(id => (
{

View File

@ -16,9 +16,11 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Editors, Grid } from 'vendor/slickgrid';
import slickgrid from 'vendor/slickgrid';
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
const { Editors, Grid } = slickgrid
function createColumns () {
return [1, 2, 3, 4].map(id => (
{

View File

@ -17,9 +17,11 @@
*/
import 'jquery.keycodes'; // used by some SlickGrid editors
import { Grid, Editors } from 'vendor/slickgrid';
import slickgrid from 'vendor/slickgrid';
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
const { Grid, Editors } = slickgrid
const keyMap = {
Tab: { which: 9, shiftKey: false },
ShiftTab: { which: 9, shiftKey: true },

View File

@ -17,9 +17,10 @@
*/
import 'jquery.keycodes'; // used by some SlickGrid editors
import { Editors, GlobalEditorLock, Grid } from 'vendor/slickgrid';
import slickgrid from 'vendor/slickgrid';
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
const { Editors, GlobalEditorLock, Grid } = slickgrid
const $fixtures = document.getElementById('fixtures');
function createColumns () {

View File

@ -16,9 +16,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import { Editors, Grid } from 'vendor/slickgrid';
import slickgrid from 'vendor/slickgrid';
import GridSupport from 'jsx/gradezilla/default_gradebook/GradebookGrid/GridSupport';
const { Editors, Grid } = slickgrid
const $fixtures = document.getElementById('fixtures');
function createColumns () {

View File

@ -18,8 +18,7 @@
import ReactDOM from 'react-dom';
import { createGradebook, setFixtureHtml } from '../../GradebookSpecHelper';
import AssignmentColumnHeaderRenderer
from 'jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer'
import AssignmentColumnHeaderRenderer from 'jsx/gradezilla/default_gradebook/GradebookGrid/headers/AssignmentColumnHeaderRenderer'
QUnit.module('AssignmentColumnHeaderRenderer', function (suiteHooks) {
let $container;

View File

@ -24,7 +24,7 @@ import fakeENV from 'helpers/fakeENV'
import numberHelper from 'jsx/shared/helpers/numberHelper'
import CourseGradeCalculator from 'jsx/gradebook/CourseGradeCalculator'
import GradeSummary from 'jsx/grading/GradeSummary'
import GradeCalculatorSpecHelper from '../gradebook/GradeCalculatorSpecHelper'
import {createCourseGradesWithGradingPeriods} from '../gradebook/GradeCalculatorSpecHelper'
const $fixtures = $('#fixtures')
@ -473,7 +473,7 @@ QUnit.module('GradeSummary.calculateGrades', {
}
ENV.effective_due_dates = {201: {101: {grading_period_id: '701'}}}
ENV.student_id = '101'
exampleGrades = GradeCalculatorSpecHelper.createCourseGradesWithGradingPeriods()
exampleGrades = createCourseGradesWithGradingPeriods()
sandbox.stub(CourseGradeCalculator, 'calculate').returns(exampleGrades)
},

View File

@ -16,14 +16,14 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import {encodeSpecialChars, decodeSpecialChars} from 'jsx/shared/helpers/urlHelper'
import urlHelper from 'jsx/shared/helpers/urlHelper'
QUnit.module('Url Helper')
test('encodes % properly', () => {
equal(encodeSpecialChars('/some/path%thing'), '/some/path&#37;thing')
equal(urlHelper.encodeSpecialChars('/some/path%thing'), '/some/path&#37;thing')
})
test('decodes the encoded % properly', () => {
equal(decodeSpecialChars('/some/path%26%2337%3Bthing'), '/some/path%25thing')
equal(urlHelper.decodeSpecialChars('/some/path%26%2337%3Bthing'), '/some/path%25thing')
})

View File

@ -27,7 +27,9 @@ import fakeENV from 'helpers/fakeENV';
import natcompare from 'compiled/util/natcompare';
import numberHelper from 'jsx/shared/helpers/numberHelper';
import userSettings from 'compiled/userSettings';
import {unescape} from 'str/htmlEscape';
import htmlEscape from 'str/htmlEscape';
const {unescape} = htmlEscape;
import 'jquery.ajaxJSON';

View File

@ -16,7 +16,9 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import htmlEscape, {unescape} from 'str/htmlEscape'
import htmlEscape from 'str/htmlEscape'
const {unescape} = htmlEscape
QUnit.module('htmlEscape', () => {
QUnit.module('.htmlEscape()', () => {