diff --git a/rails/app/controllers/api/v1/classes_controller.rb b/rails/app/controllers/api/v1/classes_controller.rb index 524a2ab30..0eaf1b4e7 100644 --- a/rails/app/controllers/api/v1/classes_controller.rb +++ b/rails/app/controllers/api/v1/classes_controller.rb @@ -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)) diff --git a/rails/spec/controllers/api/v1/classes_controller_spec.rb b/rails/spec/controllers/api/v1/classes_controller_spec.rb index 66f023368..ed04181b0 100644 --- a/rails/spec/controllers/api/v1/classes_controller_spec.rb +++ b/rails/spec/controllers/api/v1/classes_controller_spec.rb @@ -1,7 +1,8 @@ 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}) } @@ -9,10 +10,18 @@ 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 @@ -20,20 +29,49 @@ 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 diff --git a/rails/spec/models/user_spec.rb b/rails/spec/models/user_spec.rb index 4e513da4a..2d04c26f7 100644 --- a/rails/spec/models/user_spec.rb +++ b/rails/spec/models/user_spec.rb @@ -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