Skip to content

Commit 7867f7c

Browse files
committed
1 parent 2fd3474 commit 7867f7c

File tree

4 files changed

+96
-8
lines changed

4 files changed

+96
-8
lines changed

lib/concepts/school_student/list.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ def call(school:, token:)
1616
private
1717

1818
def list_students(school, token)
19-
response = ProfileApiClient.list_school_students(token:, organisation_id: school.id)
19+
student_ids = Role.student.where(school:).map(&:user_id)
20+
response = ProfileApiClient.list_school_students(token:, school_id: school.id, student_ids:)
2021
user_ids = response.fetch(:ids)
2122

2223
User.from_userinfo(ids: user_ids)

lib/profile_api_client.rb

+10-6
Original file line numberDiff line numberDiff line change
@@ -141,15 +141,19 @@ def remove_school_teacher(token:, teacher_id:, organisation_id:)
141141
#
142142
# The API should respond:
143143
# - 422 Unprocessable if the constraints are not met
144-
def list_school_students(token:, organisation_id:)
144+
def list_school_students(token:, school_id:, student_ids:)
145145
return [] if token.blank?
146146

147-
_ = organisation_id
147+
response = connection(token).post("/api/v1/schools/#{school_id}/students/list") do |request|
148+
request.body = student_ids
149+
end
148150

149-
# TODO: We should make Faraday raise a Ruby error for a non-2xx status
150-
# code so that SchoolOwner::Invite propagates the error in the response.
151-
response = { 'ids' => ['99999999-9999-9999-9999-999999999999'] }
152-
response.deep_symbolize_keys
151+
return [] if response.status == 404
152+
unless response.status == 200
153+
raise "Students cannot be listed in Profile API. HTTP response code: #{response.status}"
154+
end
155+
156+
response.body.map(&:deep_symbolize_keys)
153157
end
154158

155159
# The API should enforce these constraints:

spec/concepts/school_student/list_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
described_class.call(school:, token:)
2222

2323
# TODO: Replace with WebMock assertion once the profile API has been built.
24-
expect(ProfileApiClient).to have_received(:list_school_students).with(token:, organisation_id: school.id)
24+
expect(ProfileApiClient).to have_received(:list_school_students).with(token:, school_id: school.id, student_ids: [student.id])
2525
end
2626

2727
it 'returns the school students in the operation response' do

spec/lib/profile_api_client_spec.rb

+83
Original file line numberDiff line numberDiff line change
@@ -388,4 +388,87 @@ def create_school_student
388388
described_class.create_school_student(token:, username:, password:, name:, school_id: school.id)
389389
end
390390
end
391+
392+
describe '.list_school_student' do
393+
let(:school) { build(:school, id: SecureRandom.uuid) }
394+
let(:list_students_url) { "#{api_url}/api/v1/schools/#{school.id}/students/list" }
395+
let(:student_ids) { [SecureRandom.uuid] }
396+
397+
before do
398+
stub_request(:post, list_students_url).to_return(status: 200, body: '[]', headers: { 'content-type' => 'application/json' })
399+
end
400+
401+
it 'makes a request to the profile api host' do
402+
list_school_students
403+
expect(WebMock).to have_requested(:post, list_students_url)
404+
end
405+
406+
it 'includes token in the authorization request header' do
407+
list_school_students
408+
expect(WebMock).to have_requested(:post, list_students_url).with(headers: { authorization: "Bearer #{token}" })
409+
end
410+
411+
it 'includes the profile api key in the x-api-key request header' do
412+
list_school_students
413+
expect(WebMock).to have_requested(:post, list_students_url).with(headers: { 'x-api-key' => api_key })
414+
end
415+
416+
it 'sets content-type of request to json' do
417+
list_school_students
418+
expect(WebMock).to have_requested(:post, list_students_url).with(headers: { 'content-type' => 'application/json' })
419+
end
420+
421+
it 'sets accept header to json' do
422+
list_school_students
423+
expect(WebMock).to have_requested(:post, list_students_url).with(headers: { 'accept' => 'application/json' })
424+
end
425+
426+
it 'sets body to the student IDs' do
427+
list_school_students
428+
expect(WebMock).to have_requested(:post, list_students_url).with(body: student_ids)
429+
end
430+
431+
# rubocop:disable RSpec/ExampleLength
432+
it 'returns a hash representing the student(s) if successful' do
433+
response = [
434+
{
435+
id: '549e4674-6ffd-4ac6-9a97-b4d7e5c0e5c5',
436+
schoolId: '132383f1-702a-46a0-9eb2-a40dd4f212e3',
437+
name: 'student-name',
438+
username: 'student-username',
439+
createdAt: '2024-07-03T13:00:40.041Z',
440+
updatedAt: '2024-07-03T13:00:40.041Z',
441+
discardedAt: nil
442+
}
443+
]
444+
stub_request(:post, list_students_url)
445+
.to_return(status: 200, body: response.to_json)
446+
expect(list_school_students).to eq(response)
447+
end
448+
# rubocop:enable RSpec/ExampleLength
449+
450+
it "returns empty array if the API returns a 404 because one or more of the student IDs aren't found" do
451+
stub_request(:post, list_students_url)
452+
.to_return(status: 404, body: '')
453+
expect(list_school_students).to eq([])
454+
end
455+
456+
it 'raises exception if anything other than a 200 status code is returned' do
457+
stub_request(:post, list_students_url)
458+
.to_return(status: 500)
459+
460+
expect { list_school_students }.to raise_error(RuntimeError)
461+
end
462+
463+
it 'includes details of underlying response when exception is raised' do
464+
stub_request(:post, list_students_url)
465+
.to_return(status: 401)
466+
467+
expect { list_school_students }.to raise_error('Students cannot be listed in Profile API. HTTP response code: 401')
468+
end
469+
470+
def list_school_students
471+
described_class.list_school_students(token:, school_id: school.id, student_ids:)
472+
end
473+
end
391474
end

0 commit comments

Comments
 (0)