Skip to content

Commit 5e33ae4

Browse files
committed
Test coverage for CSV school import.
These tests cover the core functionality and some additional complex edge cases.
1 parent 065eed4 commit 5e33ae4

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe 'Importing schools', type: :request do
6+
let(:headers) { { Authorization: UserProfileMock::TOKEN } }
7+
8+
let(:csv_content) do
9+
<<~CSV
10+
name,website,address_line_1,municipality,country_code,owner_email
11+
Test School 1,https://test1.example.com,123 Main St,Springfield,US,owner1@example.com
12+
Test School 2,https://test2.example.com,456 Oak Ave,Boston,US,owner2@example.com
13+
CSV
14+
end
15+
16+
describe 'POST /api/schools/import' do
17+
let(:csv_file) do
18+
tempfile = Tempfile.new(['schools', '.csv'])
19+
tempfile.write(csv_content)
20+
tempfile.rewind
21+
Rack::Test::UploadedFile.new(tempfile.path, 'text/csv')
22+
end
23+
24+
context 'when user is an experience_cs_admin' do
25+
let(:admin_user) { create(:user, roles: 'experience-cs-admin') }
26+
27+
before do
28+
authenticated_in_hydra_as(admin_user)
29+
allow(UserInfoApiClient).to receive(:find_user_by_email).and_return({ id: SecureRandom.uuid, email: 'owner@example.com' })
30+
allow(SchoolImportJob).to receive(:perform_later).and_return(instance_double(SchoolImportJob, job_id: 'test-job-id'))
31+
end
32+
33+
it 'accepts CSV file and returns 202 Accepted' do
34+
post('/api/schools/import', headers:, params: { csv_file: csv_file })
35+
36+
expect(response).to have_http_status(:accepted)
37+
data = JSON.parse(response.body, symbolize_names: true)
38+
expect(data[:job_id]).to eq('test-job-id')
39+
expect(data[:total_schools]).to eq(2)
40+
end
41+
end
42+
43+
context 'when CSV file is missing' do
44+
let(:admin_user) { create(:user, roles: 'experience-cs-admin') }
45+
46+
before do
47+
authenticated_in_hydra_as(admin_user)
48+
end
49+
50+
it 'responds 422 Unprocessable Entity' do
51+
post('/api/schools/import', headers:)
52+
53+
expect(response).to have_http_status(:unprocessable_entity)
54+
data = JSON.parse(response.body, symbolize_names: true)
55+
expect(data[:error_code]).to eq('CSV_FILE_REQUIRED')
56+
end
57+
end
58+
59+
context 'when user is not an admin' do
60+
let(:regular_user) { create(:user, roles: '') }
61+
62+
before do
63+
authenticated_in_hydra_as(regular_user)
64+
end
65+
66+
it 'responds 403 Forbidden' do
67+
post('/api/schools/import', headers:, params: { csv_file: csv_file })
68+
69+
expect(response).to have_http_status(:forbidden)
70+
end
71+
end
72+
end
73+
74+
describe 'GET /api/school_import_jobs/:id' do
75+
let(:admin_user) { create(:user, roles: 'experience-cs-admin') }
76+
let(:job_id) { SecureRandom.uuid }
77+
78+
before do
79+
authenticated_in_hydra_as(admin_user)
80+
end
81+
82+
context 'when job exists and is completed' do
83+
before do
84+
GoodJob::Execution.create!(
85+
id: SecureRandom.uuid,
86+
active_job_id: job_id,
87+
queue_name: 'import_schools_job',
88+
job_class: 'SchoolImportJob',
89+
serialized_params: {},
90+
created_at: 1.hour.ago,
91+
finished_at: Time.current
92+
)
93+
94+
SchoolImportResult.create!(
95+
job_id: job_id,
96+
user_id: admin_user.id,
97+
results: {
98+
successful: [{ name: 'Test School', id: SecureRandom.uuid, code: '12-34-56' }],
99+
failed: []
100+
}
101+
)
102+
end
103+
104+
it 'returns job status with results' do
105+
get("/api/school_import_jobs/#{job_id}", headers:)
106+
107+
expect(response).to have_http_status(:ok)
108+
data = JSON.parse(response.body, symbolize_names: true)
109+
110+
expect(data[:status]).to eq('completed')
111+
expect(data[:results][:successful].count).to eq(1)
112+
end
113+
end
114+
115+
context 'when job does not exist' do
116+
it 'returns 404' do
117+
get("/api/school_import_jobs/#{SecureRandom.uuid}", headers:)
118+
119+
expect(response).to have_http_status(:not_found)
120+
end
121+
end
122+
123+
context 'when user is not an admin' do
124+
let(:regular_user) { create(:user) }
125+
126+
before do
127+
authenticated_in_hydra_as(regular_user)
128+
end
129+
130+
it 'responds 403 Forbidden' do
131+
get("/api/school_import_jobs/#{job_id}", headers:)
132+
133+
expect(response).to have_http_status(:forbidden)
134+
end
135+
end
136+
end
137+
end

0 commit comments

Comments
 (0)