allow all observers
closes MBL-10561 test plan: - go through all the observer_alerts & observer_alert_thresholds endpoints and use them with a course observer Change-Id: I64b14746969727b69b047139fdceecb89f4c123a Reviewed-on: https://gerrit.instructure.com/151107 Reviewed-by: Matthew Sessions <msessions@instructure.com> Tested-by: Jenkins QA-Review: Taylor Wilson <twilson@instructure.com> Product-Review: Taylor Wilson <twilson@instructure.com>
This commit is contained in:
parent
415301357f
commit
080beef78d
|
@ -25,39 +25,34 @@ class ObserverAlertThresholdsApiController < ApplicationController
|
|||
|
||||
def index
|
||||
thresholds = if params[:student_id]
|
||||
student_id = params[:student_id]
|
||||
link = @current_user.as_observer_observation_links.active.where(student: student_id).take
|
||||
return render_unauthorized_action unless link
|
||||
link.observer_alert_thresholds.active
|
||||
@current_user.as_observer_observer_alert_thresholds.active.where(student: params[:student_id])
|
||||
else
|
||||
links = @current_user.as_observer_observation_links.active
|
||||
return render_unauthorized_action unless links.count > 0
|
||||
links.map { |uol| uol.observer_alert_thresholds.active }.flatten
|
||||
@current_user.as_observer_observer_alert_thresholds.active
|
||||
end
|
||||
|
||||
if thresholds.count > 0
|
||||
thresholds = thresholds.select(&:users_are_still_linked?)
|
||||
return render_unauthorized_action unless thresholds.count > 0
|
||||
end
|
||||
|
||||
render json: thresholds.map { |threshold| observer_alert_threshold_json(threshold, @current_user, session) }
|
||||
end
|
||||
|
||||
def show
|
||||
threshold = ObserverAlertThreshold.active.find(params[:observer_alert_threshold_id])
|
||||
link = @current_user.as_observer_observation_links.select { |uol| uol.id == threshold.user_observation_link.id }
|
||||
return render_unauthorized_action unless link.count > 0
|
||||
return render_unauthorized_action unless threshold.observer_id == @current_user.id && threshold.users_are_still_linked?
|
||||
render json: observer_alert_threshold_json(threshold, @current_user, session)
|
||||
end
|
||||
|
||||
def create
|
||||
student_id = params[:student_id]
|
||||
link = UserObservationLink.where(observer_id: @current_user, user_id: student_id).take
|
||||
return render_unauthorized_action unless link
|
||||
attrs = create_params
|
||||
|
||||
attrs = create_params.merge(user_observation_link: link)
|
||||
|
||||
threshold = link.observer_alert_thresholds.active.where(alert_type: attrs[:alert_type]).take
|
||||
threshold = ObserverAlertThreshold.active.where(observer: attrs[:observer_id], student: attrs[:user_id], alert_type: attrs[:alert_type]).take
|
||||
if threshold
|
||||
# update if duplicate
|
||||
threshold.update(threshold: attrs[:threshold])
|
||||
else
|
||||
threshold = link.observer_alert_thresholds.create(attrs)
|
||||
threshold = ObserverAlertThreshold.create(attrs)
|
||||
end
|
||||
|
||||
if threshold.valid?
|
||||
|
@ -69,22 +64,20 @@ class ObserverAlertThresholdsApiController < ApplicationController
|
|||
|
||||
def update
|
||||
threshold = ObserverAlertThreshold.active.find(params[:observer_alert_threshold_id])
|
||||
link = @current_user.as_observer_observation_links.select { |uol| uol.id == threshold.user_observation_link.id }
|
||||
return render_unauthorized_action unless link.count > 0
|
||||
return render_unauthorized_action unless threshold.observer_id == @current_user.id && threshold.users_are_still_linked?
|
||||
threshold.update(update_params)
|
||||
render json: observer_alert_threshold_json(threshold.reload, @current_user, session)
|
||||
end
|
||||
|
||||
def destroy
|
||||
threshold = ObserverAlertThreshold.active.find(params[:observer_alert_threshold_id])
|
||||
link = @current_user.as_observer_observation_links.select { |uol| uol.id == threshold.user_observation_link.id }
|
||||
return render_unauthorized_action unless link.count > 0
|
||||
return render_unauthorized_action unless threshold.observer_id == @current_user.id && threshold.users_are_still_linked?
|
||||
threshold.destroy
|
||||
render json: observer_alert_threshold_json(threshold, @current_user, session)
|
||||
end
|
||||
|
||||
def create_params
|
||||
params.require(:observer_alert_threshold).permit(:alert_type, :threshold)
|
||||
params.require(:observer_alert_threshold).permit(:alert_type, :threshold, :observer_id, :user_id)
|
||||
end
|
||||
|
||||
def update_params
|
||||
|
|
|
@ -24,29 +24,28 @@ class ObserverAlertsApiController < ApplicationController
|
|||
before_action :require_user
|
||||
|
||||
def alerts_by_student
|
||||
link = @current_user.as_observer_observation_links.active.where(student: params[:student_id]).take
|
||||
return render_unauthorized_action unless link
|
||||
all_alerts = @current_user.as_observer_observer_alerts.active.where(student: params[:student_id]).select(&:users_are_still_linked?)
|
||||
|
||||
alerts = Api.paginate(link.observer_alerts.active, self, api_v1_observer_alerts_by_student_url)
|
||||
alerts = Api.paginate(all_alerts, self, api_v1_observer_alerts_by_student_url)
|
||||
|
||||
render json: alerts.map { |alert| observer_alert_json(alert, @current_user, session) }
|
||||
end
|
||||
|
||||
def alerts_count
|
||||
links = UserObservationLink.active.where(observer: @current_user)
|
||||
links = links.where(user_id: params[:student_id]) if params[:student_id]
|
||||
all_alerts = if params[:student_id]
|
||||
ObserverAlert.unread.where(observer: @current_user, student: params[:student_id])
|
||||
else
|
||||
ObserverAlert.unread.where(observer: @current_user)
|
||||
end
|
||||
|
||||
return render_unauthorized_action unless links.count > 0
|
||||
|
||||
alerts = ObserverAlert.unread.where(user_observation_link: links)
|
||||
alerts = all_alerts.select(&:users_are_still_linked?)
|
||||
|
||||
render json: { unread_count: alerts.count }
|
||||
end
|
||||
|
||||
def update
|
||||
alert = ObserverAlert.find(params[:observer_alert_id])
|
||||
link = alert.user_observation_link
|
||||
return render_unauthorized_action unless link.observer == @current_user
|
||||
return render_unauthorized_action unless alert.observer_id == @current_user.id && alert.users_are_still_linked?
|
||||
|
||||
case params[:workflow_state]
|
||||
when 'read'
|
||||
|
|
|
@ -52,12 +52,9 @@ class AccountNotification < ActiveRecord::Base
|
|||
roles = self.account_notification_roles.map(&:role_name)
|
||||
return if roles.count > 0 && (roles & ['StudentEnrollment', 'ObserverEnrollment']).none?
|
||||
|
||||
links = UserObservationLink.active.where(:root_account => self.account)
|
||||
return if links.count == 0
|
||||
|
||||
thresholds = ObserverAlertThreshold.active.where(user_observation_link: links, alert_type: 'institution_announcement')
|
||||
thresholds = ObserverAlertThreshold.active.where(observer: User.of_account(self.account), alert_type: 'institution_announcement')
|
||||
thresholds.each do |threshold|
|
||||
ObserverAlert.create(user_observation_link: threshold.user_observation_link,
|
||||
ObserverAlert.create(student: threshold.student, observer: threshold.observer,
|
||||
observer_alert_threshold: threshold, context: self,
|
||||
alert_type: 'institution_announcement', action_date: self.start_at,
|
||||
title: I18n.t('Announcement posted: %{account_name}', { account_name: self.account.name}))
|
||||
|
|
|
@ -139,15 +139,13 @@ class Announcement < DiscussionTopic
|
|||
return if !saved_changes.keys.include?('workflow_state') || saved_changes['workflow_state'][1] != 'active'
|
||||
return if self.context_type != 'Course'
|
||||
|
||||
observers = self.course.enrollments.active.where(type: 'ObserverEnrollment')
|
||||
observers.each do |observer|
|
||||
link = UserObservationLink.active.
|
||||
where(user_id: observer.associated_user_id, observer_id: observer.user_id).first
|
||||
observer_enrollments = self.course.enrollments.active.where(type: 'ObserverEnrollment')
|
||||
observer_enrollments.each do |enrollment|
|
||||
observer = enrollment.user
|
||||
threshold = ObserverAlertThreshold.where(observer: observer, alert_type: 'course_announcement').first
|
||||
next unless threshold
|
||||
|
||||
threshold = ObserverAlertThreshold.where(user_observation_link: link, alert_type: 'course_announcement').first
|
||||
next if threshold.nil?
|
||||
|
||||
ObserverAlert.create!(user_observation_link: link, observer_alert_threshold: threshold,
|
||||
ObserverAlert.create!(observer: observer, student: threshold.student, observer_alert_threshold: threshold,
|
||||
context: self, alert_type: 'course_announcement', action_date: self.updated_at,
|
||||
title: I18n.t("Announcement posted: %{title}", title: self.title))
|
||||
end
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class ObserverAlert < ActiveRecord::Base
|
||||
belongs_to :user_observation_link, :inverse_of => :observer_alerts
|
||||
belongs_to :student, :class_name => 'User', inverse_of: :as_student_observer_alerts, :foreign_key => :user_id
|
||||
belongs_to :observer, :class_name => 'User', inverse_of: :as_observer_observer_alerts
|
||||
belongs_to :observer_alert_threshold, :inverse_of => :observer_alerts
|
||||
belongs_to :context, polymorphic: [:discussion_topic, :assignment, :course, :account_notification]
|
||||
|
||||
|
@ -30,11 +31,25 @@ class ObserverAlert < ActiveRecord::Base
|
|||
institution_announcement
|
||||
).freeze
|
||||
validates :alert_type, inclusion: { in: ALERT_TYPES }
|
||||
validates :user_observation_link_id, :observer_alert_threshold_id, :alert_type, :action_date, :title, presence: true
|
||||
validates :user_id, :observer_id, :observer_alert_threshold_id, :alert_type, :action_date, :title, presence: true
|
||||
validate :validate_users_link
|
||||
|
||||
scope :active, -> { where.not(workflow_state: ['dismissed', 'deleted']) }
|
||||
scope :unread, -> { where(workflow_state: 'unread') }
|
||||
|
||||
def validate_users_link
|
||||
unless users_are_still_linked?
|
||||
errors.add(:observer_id, "Observer must be linked to Student")
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: search cross-shard enrollments
|
||||
def users_are_still_linked?
|
||||
return true if observer.as_observer_observation_links.active.where(student: student).any?
|
||||
return true if observer.enrollments.active.where(associated_user: student).any?
|
||||
false
|
||||
end
|
||||
|
||||
def self.clean_up_old_alerts
|
||||
ObserverAlert.where('created_at < ?', 6.months.ago).delete_all
|
||||
end
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
# with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
class ObserverAlertThreshold < ActiveRecord::Base
|
||||
belongs_to :user_observation_link, :inverse_of => :observer_alert_thresholds
|
||||
belongs_to :student, :class_name => 'User', inverse_of: :as_student_observer_alert_thresholds, :foreign_key => :user_id
|
||||
belongs_to :observer, :class_name => 'User', inverse_of: :as_observer_observer_alert_thresholds
|
||||
has_many :observer_alerts, :inverse_of => :observer_alert_threshold
|
||||
|
||||
ALERT_TYPES = %w(
|
||||
|
@ -29,11 +30,25 @@ class ObserverAlertThreshold < ActiveRecord::Base
|
|||
institution_announcement
|
||||
).freeze
|
||||
validates :alert_type, inclusion: { in: ALERT_TYPES }
|
||||
validates :user_observation_link_id, :alert_type, presence: true
|
||||
validates :alert_type, uniqueness: { scope: :user_observation_link }
|
||||
validates :user_id, :observer_id, :alert_type, presence: true
|
||||
validates :alert_type, uniqueness: { scope: [:user_id, :observer_id] }
|
||||
validate :validate_users_link
|
||||
|
||||
scope :active, -> { where.not(workflow_state: 'deleted') }
|
||||
|
||||
def validate_users_link
|
||||
unless users_are_still_linked?
|
||||
errors.add(:observer_id, "Observer must be linked to Student")
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: search cross-shard enrollments
|
||||
def users_are_still_linked?
|
||||
return true if observer.as_observer_observation_links.active.where(student: student).any?
|
||||
return true if observer.enrollments.active.where(associated_user: student).any?
|
||||
false
|
||||
end
|
||||
|
||||
def destroy
|
||||
self.workflow_state = 'deleted'
|
||||
self.save!
|
||||
|
|
|
@ -536,10 +536,7 @@ class Submission < ActiveRecord::Base
|
|||
def create_alert
|
||||
return unless saved_change_to_score? && self.grader_id && !self.autograded?
|
||||
|
||||
links = self.user.as_student_observation_links.active
|
||||
return unless links.count > 0
|
||||
|
||||
thresholds = ObserverAlertThreshold.active.where(user_observation_link: links,
|
||||
thresholds = ObserverAlertThreshold.active.where(student: self.user,
|
||||
alert_type: ['assignment_grade_high', 'assignment_grade_low'])
|
||||
|
||||
thresholds.each do |threshold|
|
||||
|
@ -547,7 +544,7 @@ class Submission < ActiveRecord::Base
|
|||
next if threshold.alert_type == 'assignment_grade_high' && self.score < threshold_value
|
||||
next if threshold.alert_type == 'assignment_grade_low' && self.score > threshold_value
|
||||
|
||||
ObserverAlert.create!(user_observation_link_id: threshold.user_observation_link_id,
|
||||
ObserverAlert.create!(observer: threshold.observer, student: self.user,
|
||||
observer_alert_threshold: threshold,
|
||||
context: self.assignment, alert_type: threshold.alert_type, action_date: self.graded_at,
|
||||
title: I18n.t("Assignment graded: %{score} on %{assignmentName} in %{courseName}", {
|
||||
|
|
|
@ -68,6 +68,16 @@ class User < ActiveRecord::Base
|
|||
has_many :as_observer_observation_links, -> { where.not(:workflow_state => 'deleted') }, class_name: 'UserObservationLink',
|
||||
foreign_key: :observer_id, dependent: :destroy, inverse_of: :observer
|
||||
|
||||
has_many :as_student_observer_alert_thresholds, -> { where.not(workflow_state: 'deleted') }, class_name: 'ObserverAlertThreshold',
|
||||
foreign_key: :user_id, dependent: :destroy, inverse_of: :student
|
||||
has_many :as_student_observer_alerts, -> { where.not(workflow_state: 'deleted') }, class_name: 'ObserverAlert',
|
||||
foreign_key: :user_id, dependent: :destroy, inverse_of: :student
|
||||
|
||||
has_many :as_observer_observer_alert_thresholds, -> { where.not(workflow_state: 'deleted') }, class_name: 'ObserverAlertThreshold',
|
||||
foreign_key: :observer_id, dependent: :destroy, inverse_of: :observer
|
||||
has_many :as_observer_observer_alerts, -> { where.not(workflow_state: 'deleted') }, class_name: 'ObserverAlert',
|
||||
foreign_key: :observer_id, dependent: :destroy, inverse_of: :observer
|
||||
|
||||
has_many :linked_observers, -> { distinct }, :through => :as_student_observation_links, :source => :observer, :class_name => 'User'
|
||||
has_many :linked_students, -> { distinct }, :through => :as_observer_observation_links, :source => :student, :class_name => 'User'
|
||||
|
||||
|
|
|
@ -27,9 +27,6 @@ class UserObservationLink < ActiveRecord::Base
|
|||
belongs_to :observer, :class_name => 'User', inverse_of: :as_observer_observation_links
|
||||
belongs_to :root_account, :class_name => 'Account'
|
||||
|
||||
has_many :observer_alert_thresholds, :inverse_of => :user_observation_link
|
||||
has_many :observer_alerts, :inverse_of => :user_observation_link
|
||||
|
||||
after_create :create_linked_enrollments
|
||||
|
||||
validate :not_same_user, :if => lambda { |uo| uo.changed? }
|
||||
|
|
|
@ -1322,11 +1322,6 @@ CanvasRails::Application.routes.draw do
|
|||
|
||||
post 'users/self/pandata_token', controller: 'users', action: 'pandata_token'
|
||||
|
||||
scope(controller: :observer_alerts_api) do
|
||||
get '/users/:user_id/observer_alerts/unread_count', action: :alerts_count
|
||||
get 'users/:user_id/observer_alerts/:student_id', action: :alerts_by_student
|
||||
end
|
||||
|
||||
scope(controller: :user_observees) do
|
||||
get 'users/:user_id/observees', action: :index, as: 'user_observees'
|
||||
post 'users/:user_id/observees', action: :create
|
||||
|
@ -1335,6 +1330,12 @@ CanvasRails::Application.routes.draw do
|
|||
delete 'users/:user_id/observees/:observee_id', action: :destroy
|
||||
end
|
||||
|
||||
scope(controller: :observer_alerts_api) do
|
||||
get 'users/:user_id/observer_alerts/unread_count', action: :alerts_count
|
||||
get 'users/:user_id/observer_alerts/:student_id', action: :alerts_by_student, as: 'observer_alerts_by_student'
|
||||
put 'users/:user_id/observer_alerts/:observer_alert_id/:workflow_state', action: :update
|
||||
end
|
||||
|
||||
scope(controller: :observer_alert_thresholds_api) do
|
||||
get 'users/:user_id/observer_alert_thresholds', action: :index
|
||||
post 'users/:user_id/observer_alert_thresholds', action: :create
|
||||
|
@ -1342,11 +1343,6 @@ CanvasRails::Application.routes.draw do
|
|||
put 'users/:user_id/observer_alert_thresholds/:observer_alert_threshold_id', action: :update
|
||||
delete 'users/:user_id/observer_alert_thresholds/:observer_alert_threshold_id', action: :destroy
|
||||
end
|
||||
|
||||
scope(controller: :observer_alerts_api) do
|
||||
get 'users/:user_id/observer_alerts/:student_id', action: :alerts_by_student, as: 'observer_alerts_by_student'
|
||||
put 'users/:user_id/observer_alerts/:observer_alert_id/:workflow_state', action: :update
|
||||
end
|
||||
end
|
||||
|
||||
scope(controller: :custom_data) do
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
#
|
||||
# Copyright (C) 2018 - 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/>.
|
||||
#
|
||||
|
||||
require_relative '20180516171715_add_index_to_observer_alert_threshold'
|
||||
|
||||
class FixupAddIndexToObserverAlertThreshold < ActiveRecord::Migration[5.1]
|
||||
tag :predeploy
|
||||
def change
|
||||
ObserverAlertThreshold.delete_all # no data expected. This should be a no-op, but just in case
|
||||
revert AddIndexToObserverAlertThreshold
|
||||
|
||||
change_table :observer_alert_thresholds do |t|
|
||||
t.remove_belongs_to :user_observation_link, foreign_key: { to_table: 'user_observers' }
|
||||
t.references :user, null: false, foreign_key: { to_table: 'users'}
|
||||
t.references :observer, null: false, foreign_key: { to_table: 'users'}
|
||||
end
|
||||
|
||||
add_index :observer_alert_thresholds, [:alert_type, :user_id, :observer_id], unique: true, name: 'observer_alert_thresholds_on_alert_type_and_observer_and_user'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,31 @@
|
|||
#
|
||||
# Copyright (C) 2018 - 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 FixupObserverAlert < ActiveRecord::Migration[5.1]
|
||||
tag :predeploy
|
||||
def change
|
||||
ObserverAlert.delete_all # no data expected. This should be a no-op, but just in case
|
||||
remove_column :observer_alerts, :html_url
|
||||
|
||||
change_table :observer_alerts do |t|
|
||||
t.remove_belongs_to :user_observation_link, foreign_key: { to_table: 'user_observers' }
|
||||
t.references :user, null: false, foreign_key: { to_table: 'users'}
|
||||
t.references :observer, null: false, foreign_key: { to_table: 'users'}
|
||||
end
|
||||
end
|
||||
end
|
|
@ -24,7 +24,8 @@ module Api::V1::ObserverAlert
|
|||
:only => %w(
|
||||
id
|
||||
title
|
||||
user_observation_link_id
|
||||
user_id
|
||||
observer_id
|
||||
observer_alert_threshold_id
|
||||
alert_type
|
||||
context_type
|
||||
|
|
|
@ -23,7 +23,8 @@ module Api::V1::ObserverAlertThreshold
|
|||
API_ALLOWED_OUTPUT_FIELDS = {
|
||||
:only => %w(
|
||||
id
|
||||
user_observation_link_id
|
||||
user_id
|
||||
observer_id
|
||||
alert_type
|
||||
threshold
|
||||
workflow_state
|
||||
|
|
|
@ -22,48 +22,63 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
include Api
|
||||
include Api::V1::ObserverAlertThreshold
|
||||
|
||||
context '#index' do
|
||||
describe '#index' do
|
||||
before :once do
|
||||
observer_alert_threshold_model(alert_type: 'assignment_missing')
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds?student_id=#{@observee.id}"
|
||||
@params = {user_id: @observer.to_param, student_id: @observee.to_param,
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds?student_id=#{@student.id}"
|
||||
@params = {user_id: @observer.to_param, student_id: @student.to_param,
|
||||
controller: 'observer_alert_thresholds_api', action: 'index', format: 'json'}
|
||||
end
|
||||
|
||||
describe 'with student_id' do
|
||||
context 'with student_id' do
|
||||
it 'returns the thresholds' do
|
||||
json = api_call_as_user(@observer, :get, @path, @params)
|
||||
expect(json.length).to eq 1
|
||||
expect(json[0]['user_observation_link_id']).to eq @observation_link.id
|
||||
expect(json[0]['user_id']).to eq @student.id
|
||||
expect(json[0]['observer_id']).to eq @observer.id
|
||||
expect(json[0]['alert_type']).to eq 'assignment_missing'
|
||||
end
|
||||
|
||||
it 'only returns active thresholds' do
|
||||
to_destroy = @observation_link.observer_alert_thresholds.create(alert_type: 'assignment_grade_low')
|
||||
to_destroy = observer_alert_threshold_model(observer: @observer, student: @student, alert_type: 'assignment_grade_low')
|
||||
to_destroy.destroy!
|
||||
|
||||
json = api_call_as_user(@observer, :get, @path, @params)
|
||||
expect(json.length).to eq 1
|
||||
|
||||
thresholds = @observation_link.observer_alert_thresholds.reload
|
||||
expect(thresholds.count).to eq 2
|
||||
count = ObserverAlertThreshold.where(observer: @observer, student: @student).count
|
||||
expect(count).to eq 2
|
||||
end
|
||||
|
||||
it 'errors without proper user_observation_link' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds?student_id=#{user.id}"
|
||||
params = {user_id: @observer.to_param, student_id: user.to_param,
|
||||
it 'returns an empty array if there arent any thresholds' do
|
||||
observer = user_model
|
||||
student = user_model
|
||||
UserObservationLink.create(observer: observer, student: student)
|
||||
path = "/api/v1/users/#{observer.id}/observer_alert_thresholds?student_id=#{student.id}"
|
||||
params = {user_id: observer.to_param, student_id: student.to_param,
|
||||
controller: 'observer_alert_thresholds_api', action: 'index', format: 'json'}
|
||||
|
||||
api_call_as_user(@observer, :get, path, params)
|
||||
json = api_call_as_user(observer, :get, path, params)
|
||||
expect(json.length).to eq 0
|
||||
end
|
||||
|
||||
it 'errors if users are no longer linked' do
|
||||
observer = course_with_observer(course: @course, associated_user_id: @student.id, active_all: true).user
|
||||
observer_alert_threshold_model(observer: observer, student: @student, alert_type: 'course_grade_high')
|
||||
observer.enrollments.active.map(&:destroy)
|
||||
@observation_link.destroy
|
||||
path = "/api/v1/users/#{observer.id}/observer_alert_thresholds?student_id=#{@student.id}"
|
||||
params = {user_id: observer.to_param, student_id: @student.to_param,
|
||||
controller: 'observer_alert_thresholds_api', action: 'index', format: 'json'}
|
||||
|
||||
api_call_as_user(observer, :get, path, params)
|
||||
expect(response.code).to eq "401"
|
||||
end
|
||||
end
|
||||
|
||||
describe 'without student_id' do
|
||||
context 'without student_id' do
|
||||
it 'returns the thresholds' do
|
||||
link = UserObservationLink.create(observer_id: @observer, user_id: user_model)
|
||||
link.observer_alert_thresholds.create(alert_type: 'assignment_grade_high')
|
||||
observer_alert_threshold_model(observer: @observer, student: @student, alert_type: 'assignment_grade_high')
|
||||
|
||||
path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds"
|
||||
params = {user_id: @observer.to_param, controller: 'observer_alert_thresholds_api',
|
||||
|
@ -73,19 +88,32 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
expect(json.length).to eq 2
|
||||
end
|
||||
|
||||
it 'errors without proper user_observation_link' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{user.id}/observer_alert_thresholds"
|
||||
params = {user_id: user.to_param, controller: 'observer_alert_thresholds_api',
|
||||
action: 'index', format: 'json'}
|
||||
it 'returns an empty array if there arent any thresholds' do
|
||||
observer = user_model
|
||||
student = user_model
|
||||
UserObservationLink.create(observer: observer, student: student)
|
||||
path = "/api/v1/users/#{observer.id}/observer_alert_thresholds"
|
||||
params = {user_id: observer.to_param, controller: 'observer_alert_thresholds_api', action: 'index', format: 'json'}
|
||||
|
||||
api_call_as_user(user, :get, path, params)
|
||||
json = api_call_as_user(observer, :get, path, params)
|
||||
expect(json.length).to eq 0
|
||||
end
|
||||
|
||||
it 'errors if users are no longer linked' do
|
||||
observer = course_with_observer(course: @course, associated_user_id: @student.id, active_all: true).user
|
||||
observer_alert_threshold_model(observer: observer, student: @student, alert_type: 'course_grade_high')
|
||||
observer.enrollments.active.map(&:destroy)
|
||||
@observation_link.destroy
|
||||
path = "/api/v1/users/#{observer.id}/observer_alert_thresholds"
|
||||
params = {user_id: observer.to_param, controller: 'observer_alert_thresholds_api', action: 'index', format: 'json'}
|
||||
|
||||
api_call_as_user(observer, :get, path, params)
|
||||
expect(response.code).to eq "401"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context '#show' do
|
||||
describe '#show' do
|
||||
before :once do
|
||||
observer_alert_threshold_model(alert_type: 'assignment_missing')
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds/#{@observer_alert_threshold.id}"
|
||||
|
@ -96,11 +124,12 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
it 'returns the threshold' do
|
||||
json = api_call_as_user(@observer, :get, @path, @params)
|
||||
expect(json['id']).to eq @observer_alert_threshold.id
|
||||
expect(json['user_observation_link_id']).to eq @observation_link.id
|
||||
expect(json['user_id']).to eq @student.id
|
||||
expect(json['observer_id']).to eq @observer.id
|
||||
expect(json['alert_type']).to eq 'assignment_missing'
|
||||
end
|
||||
|
||||
it 'errors without proper user_observation_link' do
|
||||
it 'errors if users are not linked' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{user.id}/observer_alert_thresholds/#{@observer_alert_threshold.id}"
|
||||
params = {user_id: user.to_param, observer_alert_threshold_id: @observer_alert_threshold.to_param,
|
||||
|
@ -111,53 +140,55 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
context '#create' do
|
||||
describe '#create' do
|
||||
before :once do
|
||||
@observer = user_model
|
||||
@observee = user_model
|
||||
@uol = UserObservationLink.create(observer_id: @observer, user_id: @observee)
|
||||
@student = user_model
|
||||
@link = UserObservationLink.create(observer: @observer, student: @student)
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds"
|
||||
end
|
||||
|
||||
it 'creates the threshold' do
|
||||
create_params = {alert_type: 'assignment_grade_high', threshold: "88"}
|
||||
params = {user_id: @observer.to_param, student_id: @uol.user_id, observer_alert_threshold: create_params,
|
||||
create_params = {alert_type: 'assignment_grade_high', threshold: "88", observer_id: @observer.to_param, user_id: @student.to_param}
|
||||
params = {user_id: @observer.to_param, observer_alert_threshold: create_params,
|
||||
controller: 'observer_alert_thresholds_api', action: 'create', format: 'json'}
|
||||
json = api_call_as_user(@observer, :post, @path, params)
|
||||
expect(json['alert_type']).to eq 'assignment_grade_high'
|
||||
expect(json['user_observation_link_id']).to eq @uol.id
|
||||
expect(json['user_id']).to eq @student.id
|
||||
expect(json['observer_id']).to eq @observer.id
|
||||
expect(json['threshold']).to eq "88"
|
||||
end
|
||||
|
||||
it 'errors with bad student_id' do
|
||||
create_params = {alert_type: 'assignment_grade_high', threshold: "88"}
|
||||
params = {user_id: @observer.to_param, student_id: @uol.user_id + 100, observer_alert_threshold: create_params,
|
||||
it 'errors with bad user_id' do
|
||||
create_params = {alert_type: 'assignment_grade_high', threshold: "88", observer_id: @observer.to_param, user_id: @student.id + 100}
|
||||
params = {user_id: @observer.to_param, observer_alert_threshold: create_params,
|
||||
controller: 'observer_alert_thresholds_api', action: 'create', format: 'json'}
|
||||
api_call_as_user(@observer, :post, @path, params)
|
||||
expect(response.code).to eq "401"
|
||||
expect(response.code).to eq "400"
|
||||
end
|
||||
|
||||
it 'errors if user_observation_link doesnt belong to user' do
|
||||
it 'errors if users are not linked' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{user.id}/observer_alert_thresholds"
|
||||
create_params = {alert_type: 'assignment_grade_high', threshold: "88"}
|
||||
params = {user_id: user.to_param, student_id: @uol.user_id, observer_alert_threshold: create_params,
|
||||
create_params = {alert_type: 'assignment_grade_high', threshold: "88", observer_id: user.to_param, user_id: @student.to_param}
|
||||
params = {user_id: user.to_param, observer_alert_threshold: create_params,
|
||||
controller: 'observer_alert_thresholds_api', action: 'create', format: 'json'}
|
||||
api_call_as_user(user, :post, path, params)
|
||||
expect(response.code).to eq "401"
|
||||
expect(response.code).to eq "400"
|
||||
end
|
||||
|
||||
it 'errors without required params' do
|
||||
create_params = {threshold: "88"}
|
||||
params = {user_id: @observer.to_param, student_id: @uol.user_id, observer_alert_threshold: create_params,
|
||||
create_params = {threshold: "88", observer_id: @observer.to_param, user_id: @student.to_param}
|
||||
params = {user_id: @observer.to_param, observer_alert_threshold: create_params,
|
||||
controller: 'observer_alert_thresholds_api', action: 'create', format: 'json'}
|
||||
api_call_as_user(@observer, :post, @path, params)
|
||||
expect(response.code).to eq "400"
|
||||
end
|
||||
|
||||
it 'ignores improper params' do
|
||||
create_params = {something_sneaky: 'sneaky!', alert_type: 'assignment_grade_high', threshold: "88"}
|
||||
params = {user_id: @observer.to_param, student_id: @uol.user_id, observer_alert_threshold: create_params,
|
||||
create_params = {something_sneaky: 'sneaky!', alert_type: 'assignment_grade_high',
|
||||
threshold: "88", observer_id: @observer.to_param, user_id: @student.to_param}
|
||||
params = {user_id: @observer.to_param, observer_alert_threshold: create_params,
|
||||
controller: 'observer_alert_thresholds_api', action: 'create', format: 'json'}
|
||||
json = api_call_as_user(@observer, :post, @path, params)
|
||||
expect(response.code).to eq "200"
|
||||
|
@ -165,18 +196,18 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
end
|
||||
|
||||
it 'updates if threshold already exists' do
|
||||
observer_alert_threshold_model(uol: @uol, alert_type: 'assignment_grade_low', threshold: '50')
|
||||
create_params = {alert_type: 'assignment_grade_low', threshold: '65'}
|
||||
params = {user_id: @observer.to_param, student_id: @uol.user_id, observer_alert_threshold: create_params,
|
||||
observer_alert_threshold_model(observer: @observer, student: @student, alert_type: 'assignment_grade_low', threshold: '50')
|
||||
create_params = {alert_type: 'assignment_grade_low', threshold: '65', observer_id: @observer.to_param, user_id: @student.to_param}
|
||||
params = {user_id: @observer.to_param, observer_alert_threshold: create_params,
|
||||
controller: 'observer_alert_thresholds_api', action: 'create', format: 'json'}
|
||||
json = api_call_as_user(@observer, :post, @path, params)
|
||||
expect(json['id']).to eq @observer_alert_threshold.id
|
||||
expect(json['threshold']).to eq '65'
|
||||
expect(@uol.observer_alert_thresholds.active.where(alert_type: 'assignment_grade_low').count).to eq 1
|
||||
expect(ObserverAlertThreshold.active.where(observer: @observer, student: @student, alert_type: 'assignment_grade_low').count).to eq 1
|
||||
end
|
||||
end
|
||||
|
||||
context '#update' do
|
||||
describe '#update' do
|
||||
before :once do
|
||||
observer_alert_threshold_model(alert_type: 'assignment_grade_low', threshold: "88")
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds/#{@observer_alert_threshold.id}"
|
||||
|
@ -185,16 +216,16 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
end
|
||||
|
||||
it 'updates the threshold' do
|
||||
update_params = {threshold: "50", alert_type: "assignment_missing",
|
||||
user_observation_link_id: @observation_link.id + 100}
|
||||
update_params = {threshold: "50", alert_type: "assignment_missing"}
|
||||
params = @params.merge({observer_alert_threshold: update_params})
|
||||
json = api_call_as_user(@observer, :put, @path, params)
|
||||
expect(json['alert_type']).to eq 'assignment_grade_low'
|
||||
expect(json['threshold']).to eq "50"
|
||||
expect(json['user_observation_link_id']).to eq @observation_link.id
|
||||
expect(json['user_id']).to eq @student.id
|
||||
expect(json['observer_id']).to eq @observer.id
|
||||
end
|
||||
|
||||
it 'errors without proper user_observation_link' do
|
||||
it 'errors if users are not linked' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{user.id}/observer_alert_thresholds/#{@observer_alert_threshold.id}"
|
||||
params = @params.merge({user_id: user.to_param, observer_alert_threshold: {threshold: "50"}})
|
||||
|
@ -204,7 +235,7 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
end
|
||||
end
|
||||
|
||||
context '#destroy' do
|
||||
describe '#destroy' do
|
||||
before :once do
|
||||
observer_alert_threshold_model(alert_type: 'assignment_grade_low', threshold: "88")
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alert_thresholds/#{@observer_alert_threshold.id}"
|
||||
|
@ -216,11 +247,11 @@ describe ObserverAlertThresholdsApiController, type: :request do
|
|||
json = api_call_as_user(@observer, :delete, @path, @params)
|
||||
expect(json['id']).to eq @observer_alert_threshold.id
|
||||
|
||||
thresholds = @observation_link.observer_alert_thresholds.active.reload
|
||||
expect(thresholds.count).to eq 0
|
||||
count = ObserverAlertThreshold.active.where(observer: @observer, student: @student).count
|
||||
expect(count).to eq 0
|
||||
end
|
||||
|
||||
it 'errors without proper user_observation_link' do
|
||||
it 'errors if users are not linked' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{user.id}/observer_alert_thresholds/#{@observer_alert_threshold.id}"
|
||||
params = @params.merge({user_id: user.to_param})
|
||||
|
|
|
@ -22,21 +22,23 @@ describe ObserverAlertsApiController, type: :request do
|
|||
include Api
|
||||
include Api::V1::ObserverAlert
|
||||
|
||||
context '#alerts_by_student' do
|
||||
describe '#alerts_by_student' do
|
||||
before :once do
|
||||
@course = course_model
|
||||
@assignment = assignment_model(context: @course)
|
||||
|
||||
observer_alert_model(course: @course, alert_type: 'assignment_grade_high', context: @assignment)
|
||||
@threshold = @observer_alert_threshold
|
||||
observer_alert_threshold = @observer_alert_threshold
|
||||
|
||||
observer_alert_model(course: @course, observer: @observer, observee: @observee, uol: @observation_link,
|
||||
observer_alert_model(course: @course, observer: @observer, student: @student, link: @observation_link,
|
||||
alert_type: 'assignment_grade_low', context: @assignment)
|
||||
observer_alert_model(course: @course, observer: @observer, observee: @observee, uol: @observation_link,
|
||||
observer_alert_model(course: @course, observer: @observer, student: @student, link: @observation_link,
|
||||
alert_type: 'course_grade_high', context: @course)
|
||||
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alerts/#{@observee.id}"
|
||||
@params = {user_id: @observer.to_param, student_id: @observee.to_param,
|
||||
@observer_alert_threshold = observer_alert_threshold
|
||||
|
||||
@path = "/api/v1/users/#{@observer.id}/observer_alerts/#{@student.id}"
|
||||
@params = {user_id: @observer.to_param, student_id: @student.to_param,
|
||||
controller: 'observer_alerts_api', action: 'alerts_by_student', format: 'json'}
|
||||
end
|
||||
|
||||
|
@ -52,8 +54,9 @@ describe ObserverAlertsApiController, type: :request do
|
|||
expect(alert['alert_type']).to eq('assignment_grade_high')
|
||||
expect(alert['workflow_state']).to eq('unread')
|
||||
expect(alert['html_url']).to eq course_assignment_url(@course, @assignment)
|
||||
expect(alert['user_observation_link_id']).to eq @observation_link.id
|
||||
expect(alert['observer_alert_threshold_id']).to eq @threshold.id
|
||||
expect(alert['user_id']).to eq @student.id
|
||||
expect(alert['observer_id']).to eq @observer.id
|
||||
expect(alert['observer_alert_threshold_id']).to eq @observer_alert_threshold.id
|
||||
end
|
||||
|
||||
it 'returns all alerts for student' do
|
||||
|
@ -63,21 +66,21 @@ describe ObserverAlertsApiController, type: :request do
|
|||
|
||||
it 'doesnt return alerts for other students' do
|
||||
user = user_model
|
||||
uol = UserObservationLink.create(observer_id: @observer.id, user_id: user)
|
||||
link = UserObservationLink.create(observer: @observer, student: user)
|
||||
asg = assignment_model(context: @course)
|
||||
observer_alert_model(uol: uol, alert_type: 'assignment_grade_high', context: asg)
|
||||
observer_alert_model(link: link, observer: @observer, alert_type: 'assignment_grade_high', context: asg)
|
||||
json = api_call_as_user(@observer, :get, @path, @params)
|
||||
expect(json.length).to eq 3
|
||||
end
|
||||
|
||||
it 'errors without valid user_observation_link' do
|
||||
it 'returns empty array if users are not linked' do
|
||||
user = user_model
|
||||
path = "/api/v1/users/#{@observer.id}/observer_alerts/#{user.id}"
|
||||
params = {user_id: @observer.to_param, student_id: user.to_param,
|
||||
controller: 'observer_alerts_api', action: 'alerts_by_student', format: 'json'}
|
||||
|
||||
api_call_as_user(@observer, :get, path, params)
|
||||
expect(response.code).to eq "401"
|
||||
json = api_call_as_user(@observer, :get, path, params)
|
||||
expect(json.length).to eq 0
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -87,9 +90,10 @@ describe ObserverAlertsApiController, type: :request do
|
|||
@assignment = assignment_model(context: @course)
|
||||
|
||||
observer_alert_model(course: @course, alert_type: 'assignment_grade_high', context: @assignment, workflow_state: 'unread')
|
||||
@observee_student = @observee
|
||||
student = @student
|
||||
observer_alert_model(course: @course, alert_type: 'assignment_grade_high', context: @assignment, workflow_state: 'unread', observer: @observer)
|
||||
observer_alert_model(course: @course, alert_type: 'assignment_grade_low', context: @assignment, workflow_state: 'read', observer: @observer)
|
||||
@student = student
|
||||
end
|
||||
|
||||
it 'only returns the number of unread alerts for the user' do
|
||||
|
@ -100,8 +104,8 @@ describe ObserverAlertsApiController, type: :request do
|
|||
end
|
||||
|
||||
it 'will only return the unread count for the specific student id provided' do
|
||||
path = "/api/v1/users/self/observer_alerts/unread_count?student_id=#{@observee_student.id}"
|
||||
params = {user_id: 'self', student_id: @observee_student.to_param, controller: 'observer_alerts_api',
|
||||
path = "/api/v1/users/self/observer_alerts/unread_count?student_id=#{@student.id}"
|
||||
params = {user_id: 'self', student_id: @student.to_param, controller: 'observer_alerts_api',
|
||||
action: 'alerts_count', format: 'json'}
|
||||
|
||||
json = api_call_as_user(@observer, :get, path, params)
|
||||
|
@ -149,7 +153,7 @@ describe ObserverAlertsApiController, type: :request do
|
|||
expect(json['alert_type']).to eq 'assignment_grade_high'
|
||||
end
|
||||
|
||||
it 'errors without valid user_observation_link' do
|
||||
it 'errors if users are not linked' do
|
||||
user = user_model
|
||||
params = @params.merge(workflow_state: 'read')
|
||||
api_call_as_user(user, :put, "#{@path}/read", params)
|
||||
|
|
|
@ -18,15 +18,16 @@
|
|||
|
||||
module Factories
|
||||
def observer_alert_model(opts = {})
|
||||
if opts[:uol]
|
||||
@observation_link = opts[:uol]
|
||||
else
|
||||
@observee = opts[:observee] || course_with_student(opts).user
|
||||
@observer = opts[:observer] || user_model
|
||||
@observation_link = UserObservationLink.create!(user_id: @observee, observer_id: @observer)
|
||||
end
|
||||
|
||||
valid_attrs = [:title, :alert_type, :workflow_state, :action_date]
|
||||
opts[:observer] ||= user_model
|
||||
@observer = opts[:observer]
|
||||
opts[:student] ||= course_with_student(opts).user
|
||||
@student = opts[:student]
|
||||
|
||||
|
||||
@observation_link = opts[:link] || UserObservationLink.create!(student: @student, observer: @observer)
|
||||
|
||||
valid_attrs = [:title, :alert_type, :workflow_state, :action_date, :student, :observer]
|
||||
default_attrs = {
|
||||
title: 'value for type',
|
||||
alert_type: 'course_announcement',
|
||||
|
@ -36,8 +37,8 @@ module Factories
|
|||
|
||||
attrs = default_attrs.deep_merge(opts.slice(*valid_attrs))
|
||||
|
||||
if opts[:oat_id]
|
||||
attrs[:observer_alert_threshold_id] = opts[:oat_id]
|
||||
if opts[:threshold_id]
|
||||
attrs[:observer_alert_threshold_id] = opts[:threshold_id]
|
||||
else
|
||||
@observer_alert_threshold = observer_alert_threshold_model(opts)
|
||||
attrs[:observer_alert_threshold_id] = @observer_alert_threshold.id
|
||||
|
@ -45,6 +46,6 @@ module Factories
|
|||
|
||||
attrs[:context] = opts[:context] || nil
|
||||
|
||||
@observer_alert = @observation_link.observer_alerts.create(attrs)
|
||||
@observer_alert = ObserverAlert.create(attrs)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,15 +18,15 @@
|
|||
|
||||
module Factories
|
||||
def observer_alert_threshold_model(opts = {})
|
||||
if opts[:uol]
|
||||
@observation_link = opts[:uol]
|
||||
else
|
||||
@observee = opts[:observee] || course_with_student(opts).user
|
||||
@observer = opts[:observer] || user_model
|
||||
@observation_link = UserObservationLink.create!(user_id: @observee, observer_id: @observer)
|
||||
end
|
||||
|
||||
valid_attrs = [:alert_type, :threshold, :workflow_state]
|
||||
opts[:observer] ||= user_model
|
||||
@observer = opts[:observer]
|
||||
opts[:student] ||= course_with_student(opts).user
|
||||
@student = opts[:student]
|
||||
|
||||
@observation_link = opts[:link] || UserObservationLink.create!(student: @student, observer: @observer)
|
||||
|
||||
valid_attrs = [:alert_type, :threshold, :workflow_state, :student, :observer]
|
||||
default_attrs = {
|
||||
alert_type: 'course_announcement',
|
||||
threshold: nil,
|
||||
|
@ -34,6 +34,6 @@ module Factories
|
|||
}
|
||||
|
||||
attrs = default_attrs.deep_merge(opts.slice(*valid_attrs))
|
||||
@observer_alert_threshold = @observation_link.observer_alert_thresholds.create(attrs)
|
||||
@observer_alert_threshold = ObserverAlertThreshold.create(attrs)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,7 +52,8 @@ describe "Api::V1::ObserverAlert" do
|
|||
expect(json['title']).to eq('value for type')
|
||||
expect(json['alert_type']).to eq('course_announcement')
|
||||
expect(json['workflow_state']).to eq('unread')
|
||||
expect(json['user_observation_link_id']).to eq @observation_link.id
|
||||
expect(json['user_id']).to eq @student.id
|
||||
expect(json['observer_id']).to eq @observer.id
|
||||
expect(json['observer_alert_threshold_id']).to eq @observer_alert_threshold.id
|
||||
end
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ describe "Api::V1::ObserverAlertThreshold" do
|
|||
json = api.observer_alert_threshold_json(observer_alert_threshold, user, session)
|
||||
expect(json['alert_type']).to eq('course_announcement')
|
||||
expect(json['workflow_state']).to eq('active')
|
||||
expect(json['user_observation_link_id']).to eq @observation_link.id
|
||||
expect(json['user_id']).to eq @student.id
|
||||
expect(json['observer_id']).to eq @observer.id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,76 +21,84 @@ describe ObserverAlert do
|
|||
include Api
|
||||
include Api::V1::ObserverAlertThreshold
|
||||
|
||||
it 'can link to a threshold and observation link' do
|
||||
assignment = assignment_model()
|
||||
observer = user_factory()
|
||||
student = user_factory()
|
||||
link = UserObservationLink.create!(student: student, observer: observer, root_account: @account)
|
||||
threshold = ObserverAlertThreshold.create!(user_observation_link: link, alert_type: 'assignment_missing')
|
||||
describe 'validations' do
|
||||
before :once do
|
||||
@student = user_model
|
||||
@observer = user_model
|
||||
UserObservationLink.create(student: @student, observer: @observer)
|
||||
@threshold = ObserverAlertThreshold.create!(student: @student, observer: @observer, alert_type: 'assignment_missing')
|
||||
@assignment = assignment_model
|
||||
end
|
||||
|
||||
alert = ObserverAlert.create(user_observation_link: link, observer_alert_threshold: threshold,
|
||||
context: assignment, alert_type: 'assignment_missing', action_date: Time.zone.now,
|
||||
title: 'Assignment missing')
|
||||
it 'can link to a threshold and observer and student' do
|
||||
alert = ObserverAlert.create(student: @student, observer: @observer, observer_alert_threshold: @threshold,
|
||||
context: @assignment, alert_type: 'assignment_missing', action_date: Time.zone.now,
|
||||
title: 'Assignment missing')
|
||||
|
||||
expect(alert.valid?).to eq true
|
||||
expect(alert.user_observation_link).not_to be_nil
|
||||
expect(alert.observer_alert_threshold).not_to be_nil
|
||||
end
|
||||
expect(alert.valid?).to eq true
|
||||
expect(alert.user_id).not_to be_nil
|
||||
expect(alert.observer_id).not_to be_nil
|
||||
expect(alert.observer_alert_threshold).not_to be_nil
|
||||
end
|
||||
|
||||
it 'wont allow random types of alert_type' do
|
||||
assignment = assignment_model
|
||||
link = UserObservationLink.create!(student: user_model, observer: user_model, root_account: @account)
|
||||
threshold = ObserverAlertThreshold.create!(user_observation_link: link, alert_type: 'assignment_missing')
|
||||
alert = ObserverAlert.create(user_observation_link: link, observer_alert_threshold: threshold,
|
||||
context: assignment, alert_type: 'jigglypuff', action_date: Time.zone.now, title: 'Assignment missing')
|
||||
it 'observer must be linked to student' do
|
||||
alert = ObserverAlert.create(student: user_model, observer: @observer, observer_alert_threshold: @threshold,
|
||||
context: @assignment, alert_type: 'assignment_missing', action_date: Time.zone.now, title: 'Assignment missing')
|
||||
|
||||
expect(alert.valid?).to eq false
|
||||
expect(alert.valid?).to eq false
|
||||
end
|
||||
|
||||
it 'wont allow random alert_type' do
|
||||
alert = ObserverAlert.create(student: @student, observer: @observer, observer_alert_threshold: @threshold,
|
||||
context: @assignment, alert_type: 'jigglypuff', action_date: Time.zone.now, title: 'Assignment missing')
|
||||
|
||||
expect(alert.valid?).to eq false
|
||||
end
|
||||
end
|
||||
|
||||
describe 'course_announcement' do
|
||||
before :once do
|
||||
@course = course_factory()
|
||||
@student = student_in_course(:active_all => true, :course => @course).user
|
||||
@observer = course_with_observer(:course => @course, :associated_user_id => @student.id, :active_all => true).user
|
||||
@link = UserObservationLink.create!(student: @student, observer: @observer, root_account: @account)
|
||||
ObserverAlertThreshold.create!(user_observation_link: @link, alert_type: 'course_announcement')
|
||||
@course = course_factory
|
||||
@student = student_in_course(active_all: true, course: @course).user
|
||||
observer = course_with_observer(course: @course, associated_user_id: @student.id, active_all: true).user
|
||||
ObserverAlertThreshold.create!(student: @student, observer: @observer, alert_type: 'course_announcement')
|
||||
|
||||
# user without a threshold
|
||||
@observer2 = course_with_observer(:course => @course, :associated_user_id => @student.id, :active_all => true).user
|
||||
@link2 = UserObservationLink.create!(student: @student, observer: @observer2, root_account: @account)
|
||||
@observer2 = course_with_observer(course: @course, associated_user_id: @student.id, active_all: true).user
|
||||
@observer = observer
|
||||
end
|
||||
|
||||
it 'creates an alert when a user has a threshold for course announcements' do
|
||||
a = announcement_model(:context => @course)
|
||||
alert = ObserverAlert.where(user_observation_link: @link).first
|
||||
alert = ObserverAlert.where(student: @student, observer: @observer).first
|
||||
expect(alert).not_to be_nil
|
||||
expect(alert.context).to eq a
|
||||
expect(alert.title).to include('Announcement posted: ')
|
||||
|
||||
alert2 = ObserverAlert.where(user_observation_link: @link2).first
|
||||
alert2 = ObserverAlert.where(student: @student, observer: @observer2).first
|
||||
expect(alert2).to be_nil
|
||||
end
|
||||
|
||||
it 'creates an alert when the delayed announcement becomes active' do
|
||||
a = announcement_model(:context => @course, :delayed_post_at => Time.zone.now, :workflow_state => :post_delayed)
|
||||
alert = ObserverAlert.where(user_observation_link: @link, context: a).first
|
||||
a = announcement_model(context: @course, delayed_post_at: Time.zone.now, workflow_state: :post_delayed)
|
||||
alert = ObserverAlert.where(student: @student, observer: @observer, context: a).first
|
||||
expect(alert).to be_nil
|
||||
|
||||
a.workflow_state = 'active'
|
||||
a.save!
|
||||
|
||||
alert = ObserverAlert.where(user_observation_link: @link, context: a).first
|
||||
alert = ObserverAlert.where(student: @student, observer: @observer, context: a).first
|
||||
expect(alert).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe 'clean_up_old_alerts' do
|
||||
it 'deletes alerts older than 6 months ago but leaves newer ones' do
|
||||
observer_alert_threshold_model()
|
||||
a1 = ObserverAlert.create(user_observation_link: @observation_link, observer_alert_threshold: @observer_alert_threshold,
|
||||
observer_alert_threshold_model(alert_type: 'institution_announcement')
|
||||
a1 = ObserverAlert.create(student: @student, observer: @observer, observer_alert_threshold: @observer_alert_threshold,
|
||||
context: @account, alert_type: 'institution_announcement', title: 'announcement',
|
||||
action_date: Time.zone.now, created_at: 6.months.ago)
|
||||
a2 = ObserverAlert.create(user_observation_link: @observation_link, observer_alert_threshold: @observer_alert_threshold,
|
||||
a2 = ObserverAlert.create(student: @student, observer: @observer, observer_alert_threshold: @observer_alert_threshold,
|
||||
context: @account, alert_type: 'institution_announcement', title: 'announcement',
|
||||
action_date: Time.zone.now)
|
||||
|
||||
|
@ -103,15 +111,10 @@ describe ObserverAlert do
|
|||
describe 'institution_announcement' do
|
||||
before :once do
|
||||
@no_link_account = account_model
|
||||
@account = account_model
|
||||
@student = student_in_course(:active_all => true, :course => @course).user
|
||||
@observer = course_with_observer(:course => @course, :associated_user_id => @student.id, :active_all => true).user
|
||||
@link = UserObservationLink.create!(student: @student, observer: @observer, root_account: @account)
|
||||
ObserverAlertThreshold.create!(user_observation_link: @link, alert_type: 'institution_announcement')
|
||||
|
||||
# user without a threshold
|
||||
@observer2 = course_with_observer(:course => @course, :associated_user_id => @student.id, :active_all => true).user
|
||||
@link2 = UserObservationLink.create!(student: @student, observer: @observer2, root_account: @account)
|
||||
@student = student_in_course(active_all: true).user
|
||||
@account = @course.account
|
||||
@observer = course_with_observer(course: @course, associated_user_id: @student.id, active_all: true).user
|
||||
@threshold = ObserverAlertThreshold.create!(student: @student, observer: @observer, alert_type: 'institution_announcement')
|
||||
end
|
||||
|
||||
it 'doesnt create an alert if the notificaiton is not for the root account' do
|
||||
|
@ -165,7 +168,7 @@ describe ObserverAlert do
|
|||
|
||||
describe 'assignment_grade' do
|
||||
before :once do
|
||||
course_with_teacher()
|
||||
course_with_teacher
|
||||
@threshold1 = observer_alert_threshold_model(alert_type: 'assignment_grade_high', threshold: '80', course: @course)
|
||||
@threshold2 = observer_alert_threshold_model(alert_type: 'assignment_grade_low', threshold: '40', course: @course)
|
||||
assignment_model(context: @course)
|
||||
|
@ -181,8 +184,7 @@ describe ObserverAlert do
|
|||
|
||||
it 'doesnt create an alert if there is no threshold for that observer' do
|
||||
student = student_in_course(course: @course).user
|
||||
observer_enrollment = course_with_observer(course: @course, associated_user_id: student.id)
|
||||
UserObservationLink.create!(student: student, observer: observer_enrollment.user, root_account: @account)
|
||||
course_with_observer(course: @course, associated_user_id: student.id)
|
||||
|
||||
@assignment.grade_student(student, score: 80, grader: @teacher)
|
||||
|
||||
|
@ -191,16 +193,19 @@ describe ObserverAlert do
|
|||
end
|
||||
|
||||
it 'doesnt create an alert if the threshold is not met' do
|
||||
@assignment.grade_student(@threshold1.user_observation_link.student, score: 70, grader: @teacher)
|
||||
@assignment.grade_student(@threshold2.user_observation_link.student, score: 50, grader: @teacher)
|
||||
@assignment.grade_student(@threshold1.student, score: 70, grader: @teacher)
|
||||
@assignment.grade_student(@threshold2.student, score: 50, grader: @teacher)
|
||||
|
||||
alerts = ObserverAlert.where(context: @assignment)
|
||||
expect(alerts.count).to eq 0
|
||||
end
|
||||
|
||||
it 'creates an alert if the threshold is met' do
|
||||
@assignment.grade_student(@threshold1.user_observation_link.student, score: 100, grader: @teacher)
|
||||
@assignment.grade_student(@threshold2.user_observation_link.student, score: 10, grader: @teacher)
|
||||
@course.enroll_user(@threshold1.student, 'StudentEnrollment')
|
||||
@course.enroll_user(@threshold2.student, 'StudentEnrollment')
|
||||
|
||||
@assignment.grade_student(@threshold1.student, score: 100, grader: @teacher)
|
||||
@assignment.grade_student(@threshold2.student, score: 10, grader: @teacher)
|
||||
|
||||
alert1 = ObserverAlert.where(context: @assignment, alert_type: 'assignment_grade_high').first
|
||||
expect(alert1).not_to be_nil
|
||||
|
|
|
@ -18,20 +18,28 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
describe ObserverAlertThreshold do
|
||||
it 'can link to an user_observation_link' do
|
||||
observer = user_factory()
|
||||
student = user_factory()
|
||||
link = UserObservationLink.create!(:student => student, :observer => observer,
|
||||
:root_account => @account)
|
||||
threshold = ObserverAlertThreshold.create(:user_observation_link => link, :alert_type => 'assignment_missing')
|
||||
|
||||
expect(threshold.valid?).to eq true
|
||||
expect(threshold.user_observation_link).not_to be_nil
|
||||
before :once do
|
||||
@student = user_model
|
||||
@observer = user_model
|
||||
UserObservationLink.create(student: @student, observer: @observer)
|
||||
end
|
||||
|
||||
it 'wont allow random types of alert_type' do
|
||||
link = UserObservationLink.create!(student: user_model, observer: user_model, root_account: @account)
|
||||
threshold = ObserverAlertThreshold.create(user_observation_link: link, alert_type: 'jigglypuff')
|
||||
it 'can link to an user_observation_link' do
|
||||
threshold = ObserverAlertThreshold.create(student: @student, observer: @observer, alert_type: 'assignment_missing')
|
||||
|
||||
expect(threshold.valid?).to eq true
|
||||
expect(threshold.user_id).not_to be_nil
|
||||
expect(threshold.observer_id).not_to be_nil
|
||||
end
|
||||
|
||||
it 'wont allow random alert_type' do
|
||||
threshold = ObserverAlertThreshold.create(student: @student, observer: @observer, alert_type: 'jigglypuff')
|
||||
|
||||
expect(threshold.valid?).to eq false
|
||||
end
|
||||
|
||||
it 'observer must be linked to student' do
|
||||
threshold = ObserverAlertThreshold.create(student: user_model, observer: @observer, alert_type: 'assignment_missing')
|
||||
|
||||
expect(threshold.valid?).to eq false
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue