Skip to content

Commit

Permalink
feat: Add tests for research access to classes and offerings [PT-1872…
Browse files Browse the repository at this point in the history
  • Loading branch information
dougmartin committed Mar 25, 2024
1 parent 048f6df commit eb7657d
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 12 deletions.
2 changes: 1 addition & 1 deletion rails/app/controllers/api/v1/classes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def show
return error('The requested class was not found')
end

# NOTE: these checks are set so only one of these can be true and researcher access is checked before teacher access
# NOTE: these checks are set so only one of these can be true and teacher access is checked before researcher access
student_in_class = user.portal_student && user.portal_student.has_clazz?(clazz)
teacher_in_class = !student_in_class || (user.portal_teacher && user.portal_teacher.has_clazz?(clazz))
researcher_in_class = !teacher_in_class || (role[:is_project_researcher] && user.is_researcher_for_clazz?(clazz))
Expand Down
60 changes: 49 additions & 11 deletions rails/spec/controllers/api/v1/classes_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -1,39 +1,77 @@
require 'spec_helper'

describe API::V1::ClassesController do
let(:teacher) { FactoryBot.create(:portal_teacher) }
let(:cohort) { FactoryBot.create(:admin_cohort) }
let(:teacher) { FactoryBot.create(:portal_teacher, cohorts: [cohort]) }
let(:clazz) { FactoryBot.create(:portal_clazz, name: 'test class', teachers: [teacher]) }
let(:runnable_a) { FactoryBot.create(:external_activity, name: 'Test Sequence') }
let(:offering_a) { FactoryBot.create(:portal_offering, {clazz: clazz, runnable: runnable_a}) }
let(:runnable_b) { FactoryBot.create(:external_activity, name: 'Archived Test Sequence', is_archived: true) }
let(:offering_b) { FactoryBot.create(:portal_offering, {clazz: clazz, runnable: runnable_b}) }
let(:runnable_c) { FactoryBot.create(:external_activity, name: 'Test Sequence 2') }
let(:offering_c) { FactoryBot.create(:portal_offering, {clazz: clazz, runnable: runnable_c}) }
let(:learner) { FactoryBot.create(:full_portal_learner, { offering: offering_a }) }

let(:other_teacher) { FactoryBot.create(:portal_teacher) }
let(:other_clazz) { FactoryBot.create(:portal_clazz, name: 'other class', teachers: [other_teacher]) }

let(:project) { FactoryBot.create(:project, cohorts: [cohort]) }
let(:researcher_user) {
researcher = FactoryBot.generate(:researcher_user)
researcher.researcher_for_projects << project
researcher
}

describe "GET #show" do
before (:each) do
# initialize the clazz
clazz
offering_a
offering_b
offering_c
sign_in teacher.user
end

it "returns a 200 code for a valid class" do
get :show, params: { id: clazz.id }
expect(response.status).to eql(200)
describe "as a teacher" do
before (:each) do
learner
clazz.reload
sign_in teacher.user
end

it "returns a 200 code for a valid class with non-anonymized student info" do
get :show, params: { id: clazz.id }
expect(response.status).to eql(200)
expect(JSON.parse(response.body)["students"].length).to eq 1
expect(JSON.parse(response.body)["students"][0]["first_name"]).to eq learner.student.first_name
expect(JSON.parse(response.body)["students"][0]["last_name"]).to eq learner.student.last_name
end

it "returns only non archived offerings" do
get :show, params: { id: clazz.id }
json = JSON.parse(response.body)
expect(json['offerings'].size).to eq 2
expect(json['offerings'][0]['id']).to eq offering_a.id
expect(json['offerings'][1]['id']).to eq offering_c.id
end
end

it "returns only non archived offerings" do
get :show, params: { id: clazz.id }
json = JSON.parse(response.body)
expect(json['offerings'].size).to eq 2
expect(json['offerings'][0]['id']).to eq offering_a.id
expect(json['offerings'][1]['id']).to eq offering_c.id
describe "as a researcher" do
before (:each) do
researcher_user
project
learner
clazz.reload
researcher_user.reload
sign_in researcher_user
end

it "returns a 200 code for a valid class with anonymized student info" do
get :show, params: { id: clazz.id }
expect(response.status).to eql(200)
expect(JSON.parse(response.body)["students"].length).to eq 1
expect(JSON.parse(response.body)["students"][0]["first_name"]).to eq "Student"
expect(JSON.parse(response.body)["students"][0]["last_name"]).to eq "#{learner.student.id}"
end
end
end

Expand Down
32 changes: 32 additions & 0 deletions rails/spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1044,6 +1044,38 @@ def create_user(options = {})
end
end

describe "is_researcher_for_clazz?" do
let(:cohort) { FactoryBot.create(:admin_cohort) }
let(:teacher) { FactoryBot.create(:portal_teacher, cohorts: [cohort]) }
let(:clazz) { FactoryBot.create(:portal_clazz, name: 'test class', teachers: [teacher]) }
let(:project) { FactoryBot.create(:project, cohorts: [cohort]) }
let(:user) { FactoryBot.create(:user) }

subject { user.is_researcher_for_clazz?(clazz) }

context "when the user is not a researcher for the class" do
it { is_expected.to be false}
end

context "when the user is a researcher for the class" do
let(:user) {
researcher = FactoryBot.generate(:researcher_user)
researcher.researcher_for_projects << project
researcher
}
it { is_expected.to be true}
end

context "when the user is a researcher but not for the class" do
let(:user) {
researcher = FactoryBot.generate(:researcher_user)
researcher.researcher_for_projects << FactoryBot.create(:project, cohorts: [])
researcher
}
it { is_expected.to be false}
end
end

# TODO: auto-generated
describe '#is_project_researcher?' do
it 'is_project_researcher?' do
Expand Down

0 comments on commit eb7657d

Please sign in to comment.