add back ability to fetch temp enrollment provider recipients

refs FOO-4041
refs FOO-4019
flag = temporary_enrollments

test plan:
 • enable temporary enrollments feature flag
 • have a temporary enrollment recipient and provider
 • make a call to GET /api/v1/users/:user_id/temporary_enrollment_status
  • verify the response contains the recipient and provider
    temporary enrollment status if that user is a recipient or provider
 /doc/api/enrollments.html#method.enrollments_api.temporary_enrollments
  • create a user with an active temporary enrollment and an
    enrollment that is completed
  • fetch /api/v1/users/:id/enrollments with the provided args
     • temporary_enrollments_for_recipient=true
     • include=temporary_enrollment_providers
     • state=current_and_future
  • verify that the response includes the current temporary enrollment
    with an included "temporary_enrollment_provider" object
  • fetch /api/v1/users/:id/enrollments with the provided args
     • temporary_enrollment_recipients_for_provider=true
     • state=current_and_future
  • verify that the response includes the current temporary enrollment
    for the specified provider

Change-Id: Ie547fea0cf2a0ee383a94a5e44a07a7ad24de0f7
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/332550
Tested-by: Service Cloud Jenkins <svc.cloudjenkins@instructure.com>
Reviewed-by: Michael Hulse <michael.hulse@instructure.com>
QA-Review: Michael Hulse <michael.hulse@instructure.com>
Product-Review: Michael Hulse <michael.hulse@instructure.com>
This commit is contained in:
August Thornton 2023-11-09 20:02:48 -07:00
parent 003d396aa4
commit a777dcb99a
3 changed files with 129 additions and 40 deletions

View File

@ -910,7 +910,7 @@ class EnrollmentsApiController < ApplicationController
end
end
# @API Fetch Temporary Enrollment recipient and provider status
# @API Show Temporary Enrollment recipient and provider status
# @beta
#
# Returns a JSON Object containing the temporary enrollment status for a user.
@ -919,21 +919,20 @@ class EnrollmentsApiController < ApplicationController
# {
# "is_provider": false, "is_recipient": true
# }
def temporary_enrollments
def show_temporary_enrollment_status
GuardRail.activate(:secondary) do
user = api_find(User, params[:user_id])
if user&.account&.grants_right?(@current_user, session, :read_roster) &&
@domain_root_account&.feature_enabled?(:temporary_enrollments)
if (user = api_find(User, params[:user_id])) && @domain_root_account&.feature_enabled?(:temporary_enrollments)
if user.account.grants_right?(@current_user, session, :read_roster)
current_and_future = %w[active invited creation_pending pending_active pending_invited]
enrollment_scope = Enrollment.joins(:enrollment_state).where(enrollment_states: { state: current_and_future })
current_and_future = %w[active invited creation_pending pending_active pending_invited]
enrollment_scope = Enrollment.joins(:enrollment_state).where(enrollment_states: { state: current_and_future })
is_provider = enrollment_scope.temporary_enrollment_recipients_for_provider(user).exists?
is_recipient = enrollment_scope.temporary_enrollments_for_recipient(user).exists?
is_provider = enrollment_scope.temporary_enrollment_recipients_for_provider(user).exists?
is_recipient = enrollment_scope.temporary_enrollments_for_recipient(user).exists?
render json: { is_provider:, is_recipient: }
else
render_unauthorized_action and return false
render json: { is_provider:, is_recipient: }
else
render_unauthorized_action and return false
end
end
end
end
@ -981,17 +980,14 @@ class EnrollmentsApiController < ApplicationController
user = api_find(User, params[:user_id])
if user && @domain_root_account&.feature_enabled?(:temporary_enrollments)
if value_to_boolean(params[:temporary_enrollments]) && user.account.grants_right?(@current_user, session, :read_roster)
enrollments = Enrollment.temporary_enrollments_for_recipient(user)
return false unless enrollments.present?
if params[:state].present?
enrollments = enrollments.joins(:enrollment_state)
.where(enrollment_states: { state: enrollment_states_for_state_param })
temp_enroll_params = params.slice(:temporary_enrollments_for_recipient,
:temporary_enrollment_recipients_for_provider)
if temp_enroll_params.present?
if user.account.grants_right?(@current_user, session, :read_roster)
return temporary_enrollment_conditions(user, temp_enroll_params)
else
render_unauthorized_action and return false
end
return enrollments
else
render_unauthorized_action and return false
end
end
@ -1117,6 +1113,25 @@ class EnrollmentsApiController < ApplicationController
[clauses.join(" AND "), replacements]
end
# Internal: Collect provider and recipient enrollments that @current_user
# has permissions to read.
#
# Returns an ActiveRecord scope of enrollments if present, otherwise false.
def temporary_enrollment_conditions(user, temp_enroll_params)
if value_to_boolean(temp_enroll_params[:temporary_enrollments_for_recipient])
enrollments = Enrollment.temporary_enrollments_for_recipient(user)
elsif value_to_boolean(temp_enroll_params[:temporary_enrollment_recipients_for_provider])
enrollments = Enrollment.temporary_enrollment_recipients_for_provider(user)
end
return false unless enrollments.present?
if params[:state].present?
enrollments = enrollments.joins(:enrollment_state).where(enrollment_states: { state: enrollment_states_for_state_param })
end
enrollments
end
def enrollment_states_for_state_param
states = Array(params[:state]).uniq
states.push("active", "invited") if states.delete "current_and_invited"

View File

@ -1183,7 +1183,7 @@ CanvasRails::Application.routes.draw do
get "courses/:course_id/enrollments", action: :index, as: "course_enrollments"
get "sections/:section_id/enrollments", action: :index, as: "section_enrollments"
get "users/:user_id/enrollments", action: :index, as: "user_enrollments"
get "users/:user_id/temporary_enrollments", action: :temporary_enrollments, as: "user_temporary_enrollments"
get "users/:user_id/temporary_enrollment_status", action: :show_temporary_enrollment_status
get "accounts/:account_id/enrollments/:id", action: :show, as: "enrollment"
post "courses/:course_id/enrollments", action: :create

View File

@ -1176,22 +1176,36 @@ describe EnrollmentsApiController, type: :request do
end
context "when feature flag is enabled" do
it "returns appropriate status for a provider" do
user_path = "/api/v1/users/#{@provider.id}/temporary_enrollments"
user_params = { controller: "enrollments_api", action: "temporary_enrollments", user_id: @provider.id, format: "json" }
json = api_call_as_user(account_admin_user, :get, user_path, user_params)
it "returns recipient temporary enrollments" do
user_path = "/api/v1/users/#{@recipient.id}/enrollments"
json = api_call_as_user(account_admin_user,
:get,
user_path,
@user_params.merge(temporary_enrollments_for_recipient: true,
user_id: @recipient.id))
expect(json.length).to eq(2)
expect(json["is_provider"]).to be_truthy
expect(json["is_recipient"]).to be_falsey
expect(json.first["user_id"]).to eq(@recipient.id)
end
it "returns appropriate status for a recipient" do
user_path = "/api/v1/users/#{@recipient.id}/temporary_enrollments"
user_params = { controller: "enrollments_api", action: "temporary_enrollments", user_id: @recipient.id, format: "json" }
json = api_call_as_user(account_admin_user, :get, user_path, user_params)
it "returns recipient enrollments for a provider" do
user_path = "/api/v1/users/#{@provider.id}/enrollments"
json = api_call_as_user(account_admin_user,
:get,
user_path,
@user_params.merge(temporary_enrollment_recipients_for_provider: true,
user_id: @provider.id))
expect(json.length).to eq(2)
expect(json["is_provider"]).to be_falsey
expect(json["is_recipient"]).to be_truthy
expect(json.first["user_id"]).to eq(@recipient.id)
end
it "returns default behavior if temporary enrollment args are not provided" do
user_path = "/api/v1/users/#{@recipient.id}/enrollments"
json = api_call_as_user(account_admin_user,
:get,
user_path,
@user_params.merge(user_id: @recipient.id))
expect(json.length).to eq(2)
expect(json.first["user_id"]).to eq(@recipient.id)
end
it "returns temporary enrollments with included providers" do
@ -1199,7 +1213,7 @@ describe EnrollmentsApiController, type: :request do
json = api_call_as_user(account_admin_user,
:get,
user_path,
@user_params.merge(temporary_enrollments: true,
@user_params.merge(temporary_enrollments_for_recipient: true,
user_id: @recipient.id,
include: ["temporary_enrollment_providers"]))
expect(json.length).to eq(2)
@ -1214,7 +1228,7 @@ describe EnrollmentsApiController, type: :request do
json = api_call_as_user(account_admin_user,
:get,
user_path,
@user_params.merge(temporary_enrollments: true,
@user_params.merge(temporary_enrollments_for_recipient: true,
user_id: @recipient.id,
state: "current_and_future",
include: ["temporary_enrollment_providers"]))
@ -1227,7 +1241,7 @@ describe EnrollmentsApiController, type: :request do
api_call_as_user(@provider,
:get,
user_path,
@user_params.merge(temporary_enrollment_providers: true,
@user_params.merge(temporary_enrollments_for_recipient: true,
user_id: @recipient.id))
expect(response).to have_http_status(:unauthorized)
end
@ -1243,7 +1257,7 @@ describe EnrollmentsApiController, type: :request do
json = api_call_as_user(account_admin_user,
:get,
user_path,
@user_params.merge(temporary_enrollment_providers: true,
@user_params.merge(temporary_enrollments_for_recipient: true,
user_id: @recipient.id))
expect(json.length).to eq(2)
expect(json.first["user_id"]).to eq(@recipient.id)
@ -3485,4 +3499,64 @@ describe EnrollmentsApiController, type: :request do
expect(json["error"]).to eq "membership not activated"
end
end
describe "#show_temporary_enrollment_status" do
let_once(:start_at) { 1.day.ago }
let_once(:end_at) { 1.day.from_now }
before(:once) do
Account.default.enable_feature!(:temporary_enrollments)
@provider = user_factory(active_all: true)
@recipient = user_factory(active_all: true)
course1 = course_with_teacher(active_all: true, user: @provider).course
course2 = course_with_teacher(active_all: true, user: @provider).course
temporary_enrollment_pairing = TemporaryEnrollmentPairing.create!(root_account: Account.default)
course1.enroll_user(
@recipient,
"TeacherEnrollment",
{
role: teacher_role,
temporary_enrollment_source_user_id: @provider.id,
temporary_enrollment_pairing_id: temporary_enrollment_pairing.id,
start_at:,
end_at:
}
)
course2.enroll_user(
@recipient,
"TeacherEnrollment",
{
role: teacher_role,
temporary_enrollment_source_user_id: @provider.id,
temporary_enrollment_pairing_id: temporary_enrollment_pairing.id,
start_at:,
end_at:
}
)
end
it "returns appropriate status for a provider" do
user_path = "/api/v1/users/#{@provider.id}/temporary_enrollment_status"
user_params = { controller: "enrollments_api",
action: "show_temporary_enrollment_status",
user_id: @provider.id,
format: "json" }
json = api_call_as_user(account_admin_user, :get, user_path, user_params)
expect(json.length).to eq(2)
expect(json["is_provider"]).to be_truthy
expect(json["is_recipient"]).to be_falsey
end
it "returns appropriate status for a recipient" do
user_path = "/api/v1/users/#{@recipient.id}/temporary_enrollment_status"
user_params = { controller: "enrollments_api",
action: "show_temporary_enrollment_status",
user_id: @recipient.id,
format: "json" }
json = api_call_as_user(account_admin_user, :get, user_path, user_params)
expect(json.length).to eq(2)
expect(json["is_provider"]).to be_falsey
expect(json["is_recipient"]).to be_truthy
end
end
end