allow messaging more than 100 students from quizzes
fixes CNVS-39904 conversation create api has a limit of 100 recipients for private messages, so we need to batch them client side test plan: - test using "Message students who" in quizzes with > 100 people - also test from a group category (other place where this code is reused) Change-Id: I387105ca3a9d9245a795cad07c9fb3c576c78478 Reviewed-on: https://gerrit.instructure.com/131385 Tested-by: Jenkins Reviewed-by: Felix Milea-Ciobanu <fmileaciobanu@instructure.com> QA-Review: KC Naegle <knaegle@instructure.com> Product-Review: Simon Williams <simon@instructure.com>
This commit is contained in:
parent
e8787b677f
commit
c004ff0367
|
@ -18,9 +18,8 @@
|
|||
define [
|
||||
'i18n!conversations'
|
||||
'Backbone'
|
||||
'underscore'
|
||||
'jquery'
|
||||
], (I18n,{Model},_,$) ->
|
||||
], (I18n, {Model}, $) ->
|
||||
|
||||
class Conversation extends Model
|
||||
|
||||
|
@ -37,13 +36,13 @@ define [
|
|||
NO_RECIPIENTS_ERR = I18n.t('no_recipients_choose_another_group',
|
||||
'No recipients are in this group. Please choose another group.')
|
||||
|
||||
validate: (attrs,options) ->
|
||||
validate: (attrs, options) ->
|
||||
errors = {}
|
||||
if !attrs.body or !$.trim(attrs.body.toString())
|
||||
errors.body = [ message: BLANK_BODY_ERR ]
|
||||
if !attrs.recipients || !attrs.recipients.length
|
||||
errors.recipients = [ message: NO_RECIPIENTS_ERR ]
|
||||
if _.keys(errors).length
|
||||
if Object.keys(errors).length
|
||||
errors
|
||||
else
|
||||
undefined
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#
|
||||
# Copyright (C) 2017 - 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 [
|
||||
'jquery'
|
||||
'lodash'
|
||||
'compiled/models/Conversation'
|
||||
], ($, _, Conversation) ->
|
||||
|
||||
class ConversationCreator
|
||||
constructor: (opts) ->
|
||||
@chunkSize = opts.chunkSize || 100
|
||||
|
||||
save: (data, saveOpts) ->
|
||||
xhrs = _.chunk(data.recipients, @chunkSize).map (chunk) ->
|
||||
chunkData = Object.assign({}, data, { recipients: chunk })
|
||||
(new Conversation).save(chunkData, saveOpts)
|
||||
$.when.apply($, xhrs)
|
||||
|
||||
# we can validate the full data set in one go
|
||||
validate: (attrs, options) ->
|
||||
(new Conversation).validate(attrs, options)
|
|
@ -21,11 +21,11 @@ define [
|
|||
'compiled/views/DialogFormView'
|
||||
'jst/messageStudentsDialog'
|
||||
'jst/EmptyDialogFormWrapper'
|
||||
'compiled/models/Conversation'
|
||||
'compiled/models/ConversationCreator'
|
||||
'jst/_messageStudentsWhoRecipientList'
|
||||
'underscore'
|
||||
'compiled/jquery/serializeForm'
|
||||
], (I18n, $, DialogFormView, template, wrapperTemplate, Conversation, recipientListTemplate, _) ->
|
||||
], (I18n, $, DialogFormView, template, wrapperTemplate, ConversationCreator, recipientListTemplate, _) ->
|
||||
|
||||
class MessageStudentsDialog extends DialogFormView
|
||||
|
||||
|
@ -68,7 +68,7 @@ define [
|
|||
I18n.t('message_students', 'Message students')
|
||||
|
||||
@recipients = @recipientGroups[0].recipients
|
||||
@model or= new Conversation
|
||||
@model or= new ConversationCreator(chunkSize: ENV.MAX_GROUP_CONVERSATION_SIZE)
|
||||
|
||||
toJSON: =>
|
||||
json = {}
|
||||
|
|
|
@ -239,7 +239,8 @@ class Quizzes::QuizzesController < ApplicationController
|
|||
COURSE_ID: @context.id,
|
||||
LOCKDOWN_BROWSER: @quiz.require_lockdown_browser?,
|
||||
QUIZ: quiz_json(@quiz,@context,@current_user,session),
|
||||
QUIZZES_URL: course_quizzes_url(@context)
|
||||
QUIZZES_URL: course_quizzes_url(@context),
|
||||
MAX_GROUP_CONVERSATION_SIZE: Conversation.max_group_conversation_size
|
||||
}
|
||||
append_sis_data(hash)
|
||||
js_env(hash)
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#
|
||||
# Copyright (C) 2013 - 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 [
|
||||
'compiled/models/ConversationCreator'
|
||||
], (ConversationCreator) ->
|
||||
|
||||
QUnit.module "ConversationCreator",
|
||||
setup: ->
|
||||
@cc = new ConversationCreator(chunkSize: 2)
|
||||
@server = sinon.fakeServer.create()
|
||||
|
||||
teardown: ->
|
||||
@server.restore()
|
||||
|
||||
respond = (data) ->
|
||||
|
||||
test "#validate passes through to Conversation", ->
|
||||
ok @cc.validate(body: '')
|
||||
ok @cc.validate(body: null).body
|
||||
ok @cc.validate(body: 'body', recipients: [{}]) == undefined
|
||||
|
||||
test "#save calls save in batches", ->
|
||||
spy = @spy()
|
||||
@server.respondWith("POST", '/api/v1/conversations', (xhr) ->
|
||||
spy()
|
||||
xhr.respond([200, { "Content-Type": "application/json"}, JSON.stringify({})])
|
||||
)
|
||||
dfd = @cc.save(body: 'body', recipients: [1, 2, 3, 4])
|
||||
equal dfd.state(), "pending"
|
||||
@server.respond()
|
||||
equal dfd.state(), "resolved"
|
||||
ok spy.calledTwice
|
Loading…
Reference in New Issue