Canvas API to mark a web conference as having a prepared recording
Fixes: CNVS-19783 Test Plan: Run migrations Create a new web conference. Get the conference key from a rails console: conf_key = WebConference.last.conference_key Get the secret key: secret = WebConference.last.config[:secret_dec] Put together a signed payload like this: signed = JWT.encode({meeting_id: conf_key}, secret) Then post it to your localhost like this (not in the rails console): curl --data "signed_parameters={the string you got handed when you signed the payload}" http://localhost:3000/api/v1/courses/{your course id}/conferences/{your conference id}/recording_ready If you look at the rails server you should see the html of the notification email fly by. Change-Id: I87cf9fc229130c2e23529c47856a66aa8e57c697 Reviewed-on: https://gerrit.instructure.com/51813 Reviewed-by: Joel Hough <joel@instructure.com> Tested-by: Jenkins QA-Review: Derek Hansen <dhansen@instructure.com> Product-Review: Joel Hough <joel@instructure.com>
This commit is contained in:
parent
badeee7b1a
commit
a747d30aa1
|
@ -13,7 +13,8 @@ define [
|
|||
# gets the I18n version of the group name. The display text used for the items gets set through the
|
||||
# ProfileController#communication. The values are defined in Notification#category_display_name.
|
||||
@groups =
|
||||
Course: ['due_date', 'grading_policies', 'course_content', 'files', 'announcement', 'announcement_created_by_you', 'announcement_reply', 'grading', 'invitation',
|
||||
Course: ['due_date', 'grading_policies', 'course_content', 'files', 'announcement',
|
||||
'announcement_created_by_you', 'announcement_reply', 'grading', 'invitation',
|
||||
'all_submissions', 'late_grading', 'submission_comment']
|
||||
Discussions: ['discussion', 'discussion_entry']
|
||||
Communication: ['added_to_conversation', 'conversation_message', 'conversation_created']
|
||||
|
@ -22,6 +23,7 @@ define [
|
|||
Parent: []
|
||||
Groups: ['membership_update']
|
||||
Alerts: ['other']
|
||||
Conferences: ['recording_ready']
|
||||
|
||||
# Get the I18n display text to use for the group name.
|
||||
getGroupDisplayName: (groupName) =>
|
||||
|
@ -34,4 +36,5 @@ define [
|
|||
when 'Groups' then I18n.t('groups.groups', 'Groups')
|
||||
when 'Alerts' then I18n.t('groups.alerts', 'Alerts')
|
||||
when 'Other' then I18n.t('groups.admin', 'Administrative')
|
||||
when 'Conferences' then I18n.t('groups.conferences', 'Conferences')
|
||||
else I18n.t('groups.other', 'Other')
|
||||
|
|
|
@ -136,7 +136,12 @@ class ConferencesController < ApplicationController
|
|||
include Api::V1::Conferences
|
||||
|
||||
before_filter :require_context
|
||||
add_crumb(proc{ t '#crumbs.conferences', "Conferences"}) { |c| c.send(:named_context_url, c.instance_variable_get("@context"), :context_conferences_url) }
|
||||
skip_before_filter :load_user, :only => [:recording_ready]
|
||||
|
||||
add_crumb(proc{ t '#crumbs.conferences', "Conferences"}) do |c|
|
||||
c.send(:named_context_url, c.instance_variable_get("@context"), :context_conferences_url)
|
||||
end
|
||||
|
||||
before_filter { |c| c.active_tab = "conferences" }
|
||||
before_filter :require_config
|
||||
before_filter :reject_student_view_student
|
||||
|
@ -285,6 +290,21 @@ class ConferencesController < ApplicationController
|
|||
redirect_to named_context_url(@context, :context_conferences_url)
|
||||
end
|
||||
|
||||
def recording_ready
|
||||
secret = @conference.config[:secret_dec]
|
||||
begin
|
||||
signed_params = Canvas::Security.decode_jwt(params[:signed_parameters], [secret])
|
||||
if signed_params[:meeting_id] == @conference.conference_key
|
||||
@conference.recording_ready!
|
||||
render json: [], status: :accepted
|
||||
else
|
||||
render json: signed_id_invalid_json, status: :unprocessable_entity
|
||||
end
|
||||
rescue Canvas::Security::InvalidToken
|
||||
render json: invalid_jwt_token_json, status: :unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
def close
|
||||
if authorized_action(@conference, @current_user, :close)
|
||||
unless @conference.active?
|
||||
|
|
|
@ -246,3 +246,8 @@
|
|||
notifications:
|
||||
- name: Summaries
|
||||
delay_for: 0
|
||||
|
||||
- category: Recording Ready
|
||||
notifications:
|
||||
- name: Web Conference Recording Ready
|
||||
delay_for: 0
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
<% define_content :link do %>
|
||||
<%= polymorphic_url([asset.context, :conferences]) %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t :subject, "Web Conference Recording Ready: %{name}", :name => asset.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= t :body, "Your recording of %{title} for %{name} is ready.", :title => asset.title, :name => asset.context.name %>
|
||||
|
||||
<%= t :details_link, "You can see the details here: %{link}", :link => content(:link) %>
|
|
@ -0,0 +1,15 @@
|
|||
<% define_content :link do %>
|
||||
<%= polymorphic_url([asset.context, :conferences]) %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t :subject, "Web Conference Recording Ready: %{name}", :name => asset.context.name %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :footer_link do %>
|
||||
<a href="<%= content(:link) %>">
|
||||
<%= t :details_link, "Click here to see the details"%>
|
||||
</a>
|
||||
<% end %>
|
||||
|
||||
<p><%= t :body, "Your recording of %{title} for %{name} is ready.", :title => asset.title, :name => asset.context.name %></p>
|
|
@ -0,0 +1,3 @@
|
|||
<%= t :body, "Your recording of %{title} for %{name} is ready.", :title => asset.title, :name => asset.context.name %>
|
||||
|
||||
<%= t :link_message, "More info at %{url}", :url => HostUrl.context_host(asset.context) %>
|
|
@ -0,0 +1,9 @@
|
|||
<% define_content :link do %>
|
||||
<%= polymorphic_url([asset.context, :conferences]) %>
|
||||
<% end %>
|
||||
|
||||
<% define_content :subject do %>
|
||||
<%= t :subject, "Web Conference Recording Ready: %{name}", :name => asset.context.name %>
|
||||
<% end %>
|
||||
|
||||
<%= t :body, "Your recording of %{title} for %{name} is ready.", :title => asset.title, :name => asset.context.name %>
|
|
@ -0,0 +1,4 @@
|
|||
<% define_content :link do -%>
|
||||
<%= polymorphic_url([asset.context, :conferences]) %>
|
||||
<% end -%>
|
||||
<%= t :tweet, "Canvas Alert - Recording ready: %{title}, %{name}", :title => asset.title, :name => asset.context.name %>
|
|
@ -19,6 +19,8 @@
|
|||
require 'nokogiri'
|
||||
|
||||
class BigBlueButtonConference < WebConference
|
||||
include ActionDispatch::Routing::PolymorphicRoutes
|
||||
include CanvasRails::Application.routes.url_helpers
|
||||
after_destroy :end_meeting
|
||||
after_destroy :delete_all_recordings
|
||||
|
||||
|
@ -51,13 +53,21 @@ class BigBlueButtonConference < WebConference
|
|||
:moderatorPW => settings[:admin_key],
|
||||
:logoutURL => (settings[:default_return_url] || "http://www.instructure.com"),
|
||||
:record => settings[:record] ? "true" : "false",
|
||||
:welcome => settings[:record] ? t("This conference may be recorded.") : ""
|
||||
:welcome => settings[:record] ? t("This conference may be recorded.") : "",
|
||||
"meta_canvas-recording-ready-url" => recording_ready_url
|
||||
}) or return nil
|
||||
@conference_active = true
|
||||
save
|
||||
conference_key
|
||||
end
|
||||
|
||||
def recording_ready_url
|
||||
polymorphic_url([:api_v1, context, :conferences, :recording_ready],
|
||||
conference_id: self.id,
|
||||
protocol: HostUrl.protocol,
|
||||
host: HostUrl.context_host(self))
|
||||
end
|
||||
|
||||
def conference_status
|
||||
if (result = send_request(:isMeetingRunning, :meetingID => conference_key)) && result[:running] == 'true'
|
||||
:active
|
||||
|
|
|
@ -60,7 +60,7 @@ class Notification < ActiveRecord::Base
|
|||
state :active do
|
||||
event :deactivate, :transitions_to => :inactive
|
||||
end
|
||||
|
||||
|
||||
state :inactive do
|
||||
event :reactivate, :transitions_to => :active
|
||||
end
|
||||
|
@ -103,7 +103,7 @@ class Notification < ActiveRecord::Base
|
|||
def create_message(asset, to_list, options={})
|
||||
return NotificationMessageCreator.new(self, asset, options.merge(:to_list => to_list)).create_message
|
||||
end
|
||||
|
||||
|
||||
def category_spaceless
|
||||
(self.category || "None").gsub(/\s/, "_")
|
||||
end
|
||||
|
@ -128,15 +128,15 @@ class Notification < ActiveRecord::Base
|
|||
9
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def self.types_to_show_in_feed
|
||||
TYPES_TO_SHOW_IN_FEED
|
||||
end
|
||||
|
||||
|
||||
def show_in_feed?
|
||||
self.category == "TestImmediately" || Notification.types_to_show_in_feed.include?(self.name)
|
||||
end
|
||||
|
||||
|
||||
def registration?
|
||||
return self.category == "Registration"
|
||||
end
|
||||
|
@ -144,19 +144,19 @@ class Notification < ActiveRecord::Base
|
|||
def migration?
|
||||
return self.category == "Migration"
|
||||
end
|
||||
|
||||
|
||||
def summarizable?
|
||||
return !self.registration? && !self.migration?
|
||||
end
|
||||
|
||||
|
||||
def dashboard?
|
||||
return ["Migration", "Registration", "Summaries", "Alert"].include?(self.category) == false
|
||||
end
|
||||
|
||||
|
||||
def category_slug
|
||||
(self.category || "").gsub(/ /, "_").gsub(/[^\w]/, "").downcase
|
||||
end
|
||||
|
||||
|
||||
# if user is given, categories that aren't relevant to that user will be
|
||||
# filtered out.
|
||||
def self.dashboard_categories(user = nil)
|
||||
|
@ -183,8 +183,8 @@ class Notification < ActiveRecord::Base
|
|||
setting[:id] = "cat_#{self.id}_option" if setting
|
||||
setting
|
||||
end
|
||||
|
||||
def default_frequency(user = nil)
|
||||
|
||||
def default_frequency(_user = nil)
|
||||
# user arg is used in plugins
|
||||
case category
|
||||
when 'All Submissions'
|
||||
|
@ -249,11 +249,13 @@ class Notification < ActiveRecord::Base
|
|||
FREQ_IMMEDIATELY
|
||||
when 'Conversation Created'
|
||||
FREQ_NEVER
|
||||
when 'Recording Ready'
|
||||
FREQ_IMMEDIATELY
|
||||
else
|
||||
FREQ_DAILY
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# TODO i18n: show the localized notification name in the dashboard (or
|
||||
# wherever), even if we continue to store the english string in the db
|
||||
# (it's actually just the titleized message template filename)
|
||||
|
@ -326,6 +328,7 @@ class Notification < ActiveRecord::Base
|
|||
t 'names.appointment_reserved_by_user', 'Appointment Reserved By User'
|
||||
t 'names.appointment_reserved_for_user', 'Appointment Reserved For User'
|
||||
t 'names.submission_needs_grading', 'Submission Needs Grading'
|
||||
t 'names.web_conference_recording_ready', 'Web Conference Recording Ready'
|
||||
end
|
||||
|
||||
# TODO: i18n ... show these anywhere we show the category today
|
||||
|
@ -352,6 +355,7 @@ class Notification < ActiveRecord::Base
|
|||
t 'categories.migration', 'Migration'
|
||||
t 'categories.reminder', 'Reminder'
|
||||
t 'categories.submission_comment', 'Submission Comment'
|
||||
t 'categories.recording_ready', 'Recording Ready'
|
||||
end
|
||||
|
||||
# Translatable display text to use when representing the category to the user.
|
||||
|
@ -359,56 +363,58 @@ class Notification < ActiveRecord::Base
|
|||
# on notification preferences page. /app/coffeescripts/notifications/NotificationGroupMappings.coffee
|
||||
def category_display_name
|
||||
case category
|
||||
when 'Announcement'
|
||||
t(:announcement_display, 'Announcement')
|
||||
when 'Announcement Created By You'
|
||||
t(:announcement_created_by_you_display, 'Announcement Created By You')
|
||||
when 'Course Content'
|
||||
t(:course_content_display, 'Course Content')
|
||||
when 'Files'
|
||||
t(:files_display, 'Files')
|
||||
when 'Discussion'
|
||||
t(:discussion_display, 'Discussion')
|
||||
when 'DiscussionEntry'
|
||||
t(:discussion_post_display, 'Discussion Post')
|
||||
when 'Due Date'
|
||||
t(:due_date_display, 'Due Date')
|
||||
when 'Grading'
|
||||
t(:grading_display, 'Grading')
|
||||
when 'Late Grading'
|
||||
t(:late_grading_display, 'Late Grading')
|
||||
when 'All Submissions'
|
||||
t(:all_submissions_display, 'All Submissions')
|
||||
when 'Submission Comment'
|
||||
t(:submission_comment_display, 'Submission Comment')
|
||||
when 'Grading Policies'
|
||||
t(:grading_policies_display, 'Grading Policies')
|
||||
when 'Invitation'
|
||||
t(:invitation_display, 'Invitation')
|
||||
when 'Other'
|
||||
t(:other_display, 'Administrative Notifications')
|
||||
when 'Calendar'
|
||||
t(:calendar_display, 'Calendar')
|
||||
when 'Student Appointment Signups'
|
||||
t(:student_appointment_display, 'Student Appointment Signups')
|
||||
when 'Appointment Availability'
|
||||
t(:appointment_availability_display, 'Appointment Availability')
|
||||
when 'Appointment Signups'
|
||||
t(:appointment_signups_display, 'Appointment Signups')
|
||||
when 'Appointment Cancelations'
|
||||
t(:appointment_cancelations_display, 'Appointment Cancelations')
|
||||
when 'Conversation Message'
|
||||
t(:conversation_message_display, 'Conversation Message')
|
||||
when 'Added To Conversation'
|
||||
t(:added_to_conversation_display, 'Added To Conversation')
|
||||
when 'Conversation Created'
|
||||
t(:conversation_created_display, 'Conversations Created By Me')
|
||||
when 'Membership Update'
|
||||
t(:membership_update_display, 'Membership Update')
|
||||
when 'Reminder'
|
||||
t(:reminder_display, 'Reminder')
|
||||
else
|
||||
t(:missing_display_display, "For %{category} notifications", :category => category)
|
||||
when 'Announcement'
|
||||
t(:announcement_display, 'Announcement')
|
||||
when 'Announcement Created By You'
|
||||
t(:announcement_created_by_you_display, 'Announcement Created By You')
|
||||
when 'Course Content'
|
||||
t(:course_content_display, 'Course Content')
|
||||
when 'Files'
|
||||
t(:files_display, 'Files')
|
||||
when 'Discussion'
|
||||
t(:discussion_display, 'Discussion')
|
||||
when 'DiscussionEntry'
|
||||
t(:discussion_post_display, 'Discussion Post')
|
||||
when 'Due Date'
|
||||
t(:due_date_display, 'Due Date')
|
||||
when 'Grading'
|
||||
t(:grading_display, 'Grading')
|
||||
when 'Late Grading'
|
||||
t(:late_grading_display, 'Late Grading')
|
||||
when 'All Submissions'
|
||||
t(:all_submissions_display, 'All Submissions')
|
||||
when 'Submission Comment'
|
||||
t(:submission_comment_display, 'Submission Comment')
|
||||
when 'Grading Policies'
|
||||
t(:grading_policies_display, 'Grading Policies')
|
||||
when 'Invitation'
|
||||
t(:invitation_display, 'Invitation')
|
||||
when 'Other'
|
||||
t(:other_display, 'Administrative Notifications')
|
||||
when 'Calendar'
|
||||
t(:calendar_display, 'Calendar')
|
||||
when 'Student Appointment Signups'
|
||||
t(:student_appointment_display, 'Student Appointment Signups')
|
||||
when 'Appointment Availability'
|
||||
t(:appointment_availability_display, 'Appointment Availability')
|
||||
when 'Appointment Signups'
|
||||
t(:appointment_signups_display, 'Appointment Signups')
|
||||
when 'Appointment Cancelations'
|
||||
t(:appointment_cancelations_display, 'Appointment Cancelations')
|
||||
when 'Conversation Message'
|
||||
t(:conversation_message_display, 'Conversation Message')
|
||||
when 'Added To Conversation'
|
||||
t(:added_to_conversation_display, 'Added To Conversation')
|
||||
when 'Conversation Created'
|
||||
t(:conversation_created_display, 'Conversations Created By Me')
|
||||
when 'Membership Update'
|
||||
t(:membership_update_display, 'Membership Update')
|
||||
when 'Reminder'
|
||||
t(:reminder_display, 'Reminder')
|
||||
when 'Recording Ready'
|
||||
t(:recording_ready_display, 'Recording Ready')
|
||||
else
|
||||
t(:missing_display_display, "For %{category} notifications", :category => category)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -511,6 +517,8 @@ EOS
|
|||
t(:added_to_conversation_description, 'You are added to a conversation')
|
||||
when 'Conversation Created'
|
||||
t(:conversation_created_description, 'You created a conversation')
|
||||
when 'Recording Ready'
|
||||
t(:web_conference_recording_ready, 'A conference recording is ready')
|
||||
when 'Membership Update'
|
||||
mt(:membership_update_description, <<-EOS)
|
||||
*Admin only: pending enrollment activated*
|
||||
|
|
|
@ -166,10 +166,18 @@ class WebConference < ActiveRecord::Base
|
|||
|
||||
set_broadcast_policy do |p|
|
||||
p.dispatch :web_conference_invitation
|
||||
p.to { @new_participants.select { |p| context.membership_for_user(p).active? } }
|
||||
p.whenever { |record|
|
||||
@new_participants && !@new_participants.empty?
|
||||
}
|
||||
p.to do
|
||||
@new_participants.select do |participant|
|
||||
context.membership_for_user(participant).active?
|
||||
end
|
||||
end
|
||||
p.whenever { @new_participants && !@new_participants.empty? }
|
||||
|
||||
p.dispatch :web_conference_recording_ready
|
||||
p.to { user }
|
||||
p.whenever do
|
||||
recording_ready? && recording_ready_changed?
|
||||
end
|
||||
end
|
||||
|
||||
on_create_send_to_streams do
|
||||
|
@ -190,6 +198,15 @@ class WebConference < ActiveRecord::Base
|
|||
p.save
|
||||
end
|
||||
|
||||
def recording_ready!
|
||||
self.recording_ready = true
|
||||
save!
|
||||
end
|
||||
|
||||
def recording_ready?
|
||||
!!recording_ready
|
||||
end
|
||||
|
||||
def added_users
|
||||
attendees
|
||||
end
|
||||
|
|
|
@ -1554,6 +1554,7 @@ CanvasRails::Application.routes.draw do
|
|||
%w(course group).each do |context|
|
||||
prefix = "#{context}s/:#{context}_id/conferences"
|
||||
get prefix, action: :index, as: "#{context}_conferences"
|
||||
post "#{prefix}/:conference_id/recording_ready", action: :recording_ready, as: "#{context}_conferences_recording_ready"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
class AddRecordingReadyToWebConference < ActiveRecord::Migration
|
||||
tag :predeploy
|
||||
|
||||
def change
|
||||
add_column :web_conferences, :recording_ready, :boolean
|
||||
end
|
||||
end
|
|
@ -0,0 +1,17 @@
|
|||
class AddWebConferenceRecordingReadyNotification < ActiveRecord::Migration
|
||||
tag :predeploy
|
||||
|
||||
def up
|
||||
return unless Shard.current == Shard.default
|
||||
Canvas::MessageHelper.create_notification({
|
||||
name: 'Web Conference Recording Ready',
|
||||
delay_for: 0,
|
||||
category: 'Recording Ready'
|
||||
})
|
||||
end
|
||||
|
||||
def down
|
||||
return unless Shard.current == Shard.default
|
||||
Notification.where(name: 'Web Conference Recording Ready').delete_all
|
||||
end
|
||||
end
|
|
@ -96,4 +96,15 @@ module Api::V1::Conferences
|
|||
end
|
||||
end
|
||||
|
||||
def signed_id_invalid_json
|
||||
{ status: I18n.t(:unprocessable_entity, 'unprocessable entity'),
|
||||
errors: [{message: I18n.t(:unprocessable_entity_message, 'Signed meeting id invalid')}]
|
||||
}.to_json
|
||||
end
|
||||
|
||||
def invalid_jwt_token_json
|
||||
{status: I18n.t(:unauthorized, 'unauthorized'),
|
||||
errors: [{message: I18n.t(:unauthorized_message, 'JWT signature invalid')}]
|
||||
}.to_json
|
||||
end
|
||||
end
|
||||
|
|
|
@ -92,6 +92,58 @@ describe "Conferences API", type: :request do
|
|||
merge(action: 'index', group_id: @group.to_param))
|
||||
expect(json).to eq api_conferences_json(@conferences.reverse.map{|c| WebConference.find(c.id)}, @group, @student)
|
||||
end
|
||||
end
|
||||
|
||||
describe "POST 'recording_ready'" do
|
||||
before do
|
||||
WebConference.stubs(:plugins).returns([
|
||||
web_conference_plugin_mock("big_blue_button", {
|
||||
:domain => "bbb.instructure.com",
|
||||
:secret_dec => "secret",
|
||||
})
|
||||
])
|
||||
end
|
||||
|
||||
let(:conference) do
|
||||
BigBlueButtonConference.create!(context: course,
|
||||
user: user,
|
||||
conference_key: "conf_key")
|
||||
end
|
||||
|
||||
let(:course_id) { conference.context.id }
|
||||
|
||||
let(:path) do
|
||||
"api/v1/courses/#{course_id}/conferences/#{conference.id}/recording_ready"
|
||||
end
|
||||
|
||||
let(:params) do
|
||||
@category_path_options.merge(action: 'recording_ready',
|
||||
course_id: course_id,
|
||||
conference_id: conference.id)
|
||||
end
|
||||
|
||||
it 'should mark the recording as ready' do
|
||||
payload = {meeting_id: conference.conference_key}
|
||||
body_params = {signed_parameters: JWT.encode(payload, conference.config[:secret_dec])}
|
||||
|
||||
raw_api_call(:post, path, params, body_params)
|
||||
expect(response.status).to eq 202
|
||||
end
|
||||
|
||||
it 'should error if the secret key is wrong' do
|
||||
payload = {meeting_id: conference.conference_key}
|
||||
body_params = {signed_parameters: JWT.encode(payload, "wrong_key")}
|
||||
|
||||
raw_api_call(:post, path, params, body_params)
|
||||
expect(response.status).to eq 401
|
||||
end
|
||||
|
||||
it 'should error if the conference_key is wrong' do
|
||||
payload = {meeting_id: "wrong_conference_key"}
|
||||
body_params = {signed_parameters: JWT.encode(payload, conference.config[:secret_dec])}
|
||||
|
||||
raw_api_call(:post, path, params, body_params)
|
||||
expect(response.status).to eq 422
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ describe BigBlueButtonConference do
|
|||
before do
|
||||
WebConference.stubs(:plugins).returns([
|
||||
web_conference_plugin_mock("big_blue_button", {
|
||||
:domain => "bbb.instructure.com",
|
||||
:domain => "bbb.instructure.com",
|
||||
:secret_dec => "secret",
|
||||
})
|
||||
])
|
||||
|
@ -34,7 +34,7 @@ describe BigBlueButtonConference do
|
|||
@conference = BigBlueButtonConference.create!(
|
||||
:title => "my conference",
|
||||
:user => @user,
|
||||
:context => Account.default
|
||||
:context => course
|
||||
)
|
||||
end
|
||||
|
||||
|
@ -109,7 +109,7 @@ describe BigBlueButtonConference do
|
|||
bbb = BigBlueButtonConference.new
|
||||
bbb.user_settings = { :record => true }
|
||||
bbb.user = user
|
||||
bbb.context = Account.default
|
||||
bbb.context = course
|
||||
bbb.save!
|
||||
bbb.expects(:send_request).with do |verb, options|
|
||||
expect(verb).to eql :create
|
||||
|
@ -122,7 +122,7 @@ describe BigBlueButtonConference do
|
|||
bbb = BigBlueButtonConference.new
|
||||
bbb.user_settings = { :record => false }
|
||||
bbb.user = user
|
||||
bbb.context = Account.default
|
||||
bbb.context = course
|
||||
bbb.save!
|
||||
bbb.expects(:send_request).with do |verb, options|
|
||||
expect(verb).to eql :create
|
||||
|
@ -136,7 +136,7 @@ describe BigBlueButtonConference do
|
|||
bbb.stubs(:conference_key).returns('12345')
|
||||
bbb.user_settings = { record: true }
|
||||
bbb.user = user
|
||||
bbb.context = Account.default
|
||||
bbb.context = course
|
||||
bbb.save!
|
||||
response = {returncode: 'SUCCESS', recordings: "\n ",
|
||||
messageKey: 'noRecordings', message: 'There are not
|
||||
|
@ -149,7 +149,7 @@ describe BigBlueButtonConference do
|
|||
bbb = BigBlueButtonConference.new
|
||||
bbb.user_settings = { :record => false }
|
||||
bbb.user = user
|
||||
bbb.context = Account.default
|
||||
bbb.context = course
|
||||
|
||||
# set some vars so it thinks it's been created and doesn't do an api call
|
||||
bbb.conference_key = 'test'
|
||||
|
@ -187,7 +187,7 @@ describe BigBlueButtonConference do
|
|||
bbb = BigBlueButtonConference.new
|
||||
bbb.user_settings = { :record => true }
|
||||
bbb.user = user
|
||||
bbb.context = Account.default
|
||||
bbb.context = course
|
||||
bbb.save!
|
||||
bbb.expects(:send_request).with do |verb, options|
|
||||
expect(verb).to eql :create
|
||||
|
@ -197,5 +197,4 @@ describe BigBlueButtonConference do
|
|||
expect(bbb.user_settings[:record]).to be_falsey
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -89,7 +89,7 @@ describe WebConference do
|
|||
expect(conference.started_at).to be_nil
|
||||
expect(conference.ended_at).to be_nil
|
||||
end
|
||||
|
||||
|
||||
it "should set start and end times when a paricipant is added" do
|
||||
conference.add_attendee(@user)
|
||||
expect(conference.start_at).not_to be_nil
|
||||
|
@ -97,7 +97,7 @@ describe WebConference do
|
|||
expect(conference.started_at).to eql(conference.start_at)
|
||||
expect(conference.ended_at).to be_nil
|
||||
end
|
||||
|
||||
|
||||
it "should not set ended_at if the conference is still active" do
|
||||
conference.add_attendee(@user)
|
||||
conference.stubs(:conference_status).returns(:active)
|
||||
|
@ -105,7 +105,7 @@ describe WebConference do
|
|||
expect(conference).to be_active
|
||||
expect(conference.ended_at).to be_nil
|
||||
end
|
||||
|
||||
|
||||
it "should not set ended_at if the conference is no longer active but end_at has not passed" do
|
||||
conference.add_attendee(@user)
|
||||
conference.stubs(:conference_status).returns(:closed)
|
||||
|
@ -113,7 +113,7 @@ describe WebConference do
|
|||
expect(conference.active?(true)).to eql(false)
|
||||
expect(conference.ended_at).to be_nil
|
||||
end
|
||||
|
||||
|
||||
it "should set ended_at if the conference is no longer active and end_at has passed" do
|
||||
conference.add_attendee(@user)
|
||||
conference.stubs(:conference_status).returns(:closed)
|
||||
|
@ -123,9 +123,9 @@ describe WebConference do
|
|||
expect(conference.ended_at).to be_nil
|
||||
expect(conference.active?(true)).to eql(false)
|
||||
expect(conference.ended_at).not_to be_nil
|
||||
expect(conference.ended_at).to be < Time.now
|
||||
expect(conference.ended_at).to be < Time.zone.now
|
||||
end
|
||||
|
||||
|
||||
it "should set ended_at if it's more than 15 minutes past end_at" do
|
||||
conference.add_attendee(@user)
|
||||
conference.stubs(:conference_status).returns(:active)
|
||||
|
@ -136,16 +136,16 @@ describe WebConference do
|
|||
expect(conference.active?(true)).to eql(false)
|
||||
expect(conference.conference_status).to eql(:active)
|
||||
expect(conference.ended_at).not_to be_nil
|
||||
expect(conference.ended_at).to be < Time.now
|
||||
expect(conference.ended_at).to be < Time.zone.now
|
||||
end
|
||||
|
||||
|
||||
it "should be restartable if end_at has not passed" do
|
||||
conference.add_attendee(@user)
|
||||
conference.stubs(:conference_status).returns(:active)
|
||||
expect(conference).not_to be_finished
|
||||
expect(conference).to be_restartable
|
||||
end
|
||||
|
||||
|
||||
it "should not be restartable if end_at has passed" do
|
||||
conference.add_attendee(@user)
|
||||
conference.start_at = 30.minutes.ago
|
||||
|
@ -169,19 +169,23 @@ describe WebConference do
|
|||
|
||||
context "notifications" do
|
||||
before :once do
|
||||
Notification.create!(:name => 'Web Conference Invitation', :category => "TestImmediately")
|
||||
Notification.create!(:name => 'Web Conference Invitation',
|
||||
:category => "TestImmediately")
|
||||
Notification.create!(:name => 'Web Conference Recording Ready',
|
||||
:category => "TestImmediately")
|
||||
course_with_student(:active_all => 1)
|
||||
@student.communication_channels.create(:path => "test_channel_email_#{user.id}", :path_type => "email").confirm
|
||||
@student.communication_channels.create(:path => "test_channel_email_#{user.id}",
|
||||
:path_type => "email").confirm
|
||||
end
|
||||
|
||||
it "should send notifications" do
|
||||
it "should send invitation notifications" do
|
||||
conference = WimbaConference.create!(:title => "my conference", :user => @user, :context => @course)
|
||||
conference.add_attendee(@student)
|
||||
conference.save!
|
||||
expect(conference.messages_sent['Web Conference Invitation']).not_to be_empty
|
||||
end
|
||||
|
||||
it "should not send notifications to inactive users" do
|
||||
it "should not send invitation notifications to inactive users" do
|
||||
@course.restrict_enrollments_to_course_dates = true
|
||||
@course.start_at = 2.days.from_now
|
||||
@course.conclude_at = 4.days.from_now
|
||||
|
@ -191,6 +195,18 @@ describe WebConference do
|
|||
conference.save!
|
||||
expect(conference.messages_sent['Web Conference Invitation']).to be_blank
|
||||
end
|
||||
|
||||
it "should send recording ready notifications, but only once" do
|
||||
conference = WimbaConference.create!(:title => "my conference",
|
||||
:user => @student,
|
||||
:context => @course)
|
||||
conference.recording_ready!
|
||||
expect(conference.messages_sent['Web Conference Recording Ready'].length).to eq(2)
|
||||
|
||||
# check that it won't send the notification again when saved again.
|
||||
conference.save!
|
||||
expect(conference.messages_sent['Web Conference Recording Ready'].length).to eq(2)
|
||||
end
|
||||
end
|
||||
|
||||
context "scheduled conferences" do
|
||||
|
|
Loading…
Reference in New Issue