Skip to content

Commit

Permalink
Add requests specs for api
Browse files Browse the repository at this point in the history
  • Loading branch information
ddippolito committed Jan 17, 2025
1 parent 8fb7ad6 commit e7dfeee
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 97 deletions.
18 changes: 13 additions & 5 deletions app/services/publishers/ats_api/organisation_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,19 @@ module OrganisationFetcher
def fetch_organisations(school_params)
return [] unless school_params

if school_params[:trust_uid].present?
SchoolGroup.trusts.find_by(uid: school_params[:trust_uid]).schools&.where(urn: school_params[:school_urns]) || []
else
School.where(urn: school_params[:school_urns])
end
trust_uid = school_params[:trust_uid]
school_urns = school_params[:school_urns]

# When having both trust and schools, only return the schools that are in the trust if any.
# Otherwise, return the trust itself.
multi_academy_trust = SchoolGroup.trusts.find_by(uid: trust_uid)
schools = ::Organisation.where(urn: school_urns) if school_urns.present?

return [] if multi_academy_trust.blank? && schools.blank?
return schools.to_a if multi_academy_trust.blank?
return Array(multi_academy_trust) if schools.blank?

multi_academy_trust.schools.where(urn: school_urns).order(:created_at).to_a.presence || Array(multi_academy_trust)
end
end
end
Expand Down
121 changes: 121 additions & 0 deletions spec/requests/publishers/ats_api/v1/vacancies_requests_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
require "rails_helper"

RSpec.describe "Publishers::AtsApi::V1::Vacancies API" do
let!(:client) { create(:publisher_ats_api_client) }

describe "GET /ats-api/v1/vacancies" do
it "only returns vacancies for the authenticated client" do
other_client = create(:publisher_ats_api_client)
school = create(:school)
create_list(:vacancy, 2, :external, publisher_ats_api_client: client, organisations: [school])
create_list(:vacancy, 3, :external, publisher_ats_api_client: other_client, organisations: [school])

get "/ats-api/v1/vacancies", headers: { "X-Api-Key" => client.api_key, "Accept" => "application/json" }

expect(response).to have_http_status(:ok)
body = response.parsed_body
expect(body["data"].size).to eq(2)
end

it "returns paginated results" do
create_list(:vacancy, 10, :external, publisher_ats_api_client: client)

get "/ats-api/v1/vacancies", headers: { "X-Api-Key" => client.api_key, "Accept" => "application/json" }

expect(response).to have_http_status(:ok)
body = response.parsed_body
expect(body["data"].size).to eq(10)
expect(body["meta"]["totalPages"]).to eq(1)
end
end

describe "POST /ats-api/v1/vacancies" do
subject(:request) do
post "/ats-api/v1/vacancies", params: vacancy_params, headers: { "X-Api-Key" => client.api_key, "Accept" => "application/json" }
end

let(:source) { build(:vacancy, :external) }
let!(:school1) { create(:school, name: "Test School", urn: "111111", phase: :primary) }
let(:schools) { [school1] }

let(:organisation_ids) do
{
school_urns: schools.map { |school| school.urn.to_i },
}
end

let(:vacancy_params) do
{
vacancy: {
external_advert_url: source.external_advert_url,
expires_at: source.expires_at,
job_title: source.job_title,
job_advert: source.job_advert,
skills_and_experience: source.skills_and_experience,
salary: source.salary,
visa_sponsorship_available: source.visa_sponsorship_available,
external_reference: source.external_reference,
publisher_ats_api_client_id: client.id,
is_job_share: source.is_job_share,
job_roles: source.job_roles,
working_patterns: source.working_patterns,
contract_type: source.contract_type,
phases: source.phases,
schools: organisation_ids,
},
}
end

let(:created_vacancy) { Vacancy.last }

describe "with a single school" do
it "creates a vacancy and links it to a single school" do
expect { request }.to change(Vacancy, :count).by(1)
expect(created_vacancy.organisations).to eq([school1])
end
end

describe "with multiple schools" do
let!(:school2) { create(:school, name: "Test School 2", urn: "222222", phase: :primary) }
let(:schools) { [school1, school2] }

it "creates a vacancy and links it to multiple schools" do
request
expect(created_vacancy.organisations).to eq([school1, school2])
end
end

describe "with a trust central office and no schools" do
let(:organisation_ids) do
{
trust_uid: school_group.uid,
}
end
let(:school_group) { create(:trust, uid: "12345") }

it "creates a vacancy and links it to the trusts schools" do
request
expect(created_vacancy.organisations).to eq([school_group])
end
end

describe "with a trust central office and some schools" do
let(:organisation_ids) do
{
trust_uid: school_group.uid,
school_urns: schools.map { |school| school.urn.to_i },
}
end

let!(:school2) { create(:school, name: "Test School 2", urn: "222222", phase: :primary) }
let(:schools) { [school1, school2] }

let(:school_group) { create(:trust, uid: "12345", schools: schools) }

it "creates a vacancy and links it to the trusts schools" do
request
expect(created_vacancy.organisations).to eq([school1, school2])
end
end
end
end
160 changes: 69 additions & 91 deletions spec/requests/publishers/ats_api/v1/vacancies_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

# rubocop:disable RSpec/VariableName
# rubocop:disable RSpec/ScatteredSetup
# rubocop:disable RSpec/EmptyExampleGroup
RSpec.describe "ats-api/v1/vacancies", openapi_spec: "v1/swagger.yaml" do
let!(:client) { create(:publisher_ats_api_client) }
let(:"X-Api-Key") { client.api_key }
Expand Down Expand Up @@ -82,30 +83,6 @@
end
end

it "only returns vacancies for the authenticated client" do
other_client = create(:publisher_ats_api_client)
school = create(:school)
create_list(:vacancy, 2, :external, publisher_ats_api_client: client, organisations: [school])
create_list(:vacancy, 3, :external, publisher_ats_api_client: other_client, organisations: [school])

get "/ats-api/v1/vacancies", headers: { "X-Api-Key" => client.api_key, "Accept" => "application/json" }

expect(response).to have_http_status(:ok)
body = response.parsed_body
expect(body["data"].size).to eq(2)
end

it "returns paginated results" do
create_list(:vacancy, 10, :external, publisher_ats_api_client: client)

get "/ats-api/v1/vacancies", headers: { "X-Api-Key" => client.api_key, "Accept" => "application/json" }

expect(response).to have_http_status(:ok)
body = response.parsed_body
expect(body["data"].size).to eq(10)
expect(body["meta"]["totalPages"]).to eq(1)
end

post("create a vacancy") do
tags "Vacancies"
description "create a vacancy for the client's ATS"
Expand Down Expand Up @@ -375,73 +352,73 @@
run_test!
end

# response(422, "Validation error") do
# schema "$ref" => "#/components/schemas/validation_error"
#
# let(:school) { create(:school) }
# let(:source) { build(:vacancy, :external) }
# let(:school_urns) { [school].map { |school| school.urn.to_i } }
# let(:vacancy) do
# {
# vacancy: {
# external_advert_url: source.external_advert_url,
# expires_at: source.expires_at,
# job_title: nil,
# job_advert: source.job_advert,
# skills_and_experience: source.skills_and_experience,
# salary: source.salary,
# visa_sponsorship_available: source.visa_sponsorship_available,
# external_reference: source.external_reference,
# is_job_share: source.is_job_share,
# job_roles: source.job_roles,
# working_patterns: source.working_patterns,
# contract_type: source.contract_type,
# phases: source.phases,
# schools: {
# school_urns: school_urns,
# },
# },
# }
# end
#
# run_test!
# end

# response(500, "Internal server error") do
# schema "$ref" => "#/components/schemas/internal_server_error"
#
# let(:school) { create(:school) }
# let(:source) { build(:vacancy, :external) }
# let(:school_urns) { [school].map { |school| school.urn.to_i } }
# let(:vacancy) do
# {
# vacancy: {
# external_advert_url: source.external_advert_url,
# expires_at: source.expires_at,
# job_title: source.job_title,
# job_advert: source.job_advert,
# skills_and_experience: source.skills_and_experience,
# salary: source.salary,
# visa_sponsorship_available: source.visa_sponsorship_available,
# external_reference: source.external_reference,
# is_job_share: source.is_job_share,
# job_roles: source.job_roles,
# working_patterns: source.working_patterns,
# contract_type: source.contract_type,
# phases: source.phases,
# schools: {
# school_urns: school_urns,
# },
# },
# }
# end
#
# before do
# allow(Vacancy).to receive(:find_by).and_raise(StandardError.new("Internal server error"))
# end
#
# run_test!
# end
response(422, "Validation error") do
schema "$ref" => "#/components/schemas/validation_error"

let(:school) { create(:school) }
let(:source) { build(:vacancy, :external) }
let(:school_urns) { [school].map { |school| school.urn.to_i } }
let(:vacancy) do
{
vacancy: {
external_advert_url: source.external_advert_url,
expires_at: source.expires_at,
job_title: nil,
job_advert: source.job_advert,
skills_and_experience: source.skills_and_experience,
salary: source.salary,
visa_sponsorship_available: source.visa_sponsorship_available,
external_reference: source.external_reference,
is_job_share: source.is_job_share,
job_roles: source.job_roles,
working_patterns: source.working_patterns,
contract_type: source.contract_type,
phases: source.phases,
schools: {
school_urns: school_urns,
},
},
}
end

run_test!
end

response(500, "Internal server error") do
schema "$ref" => "#/components/schemas/internal_server_error"

let(:school) { create(:school) }
let(:source) { build(:vacancy, :external) }
let(:school_urns) { [school].map { |school| school.urn.to_i } }
let(:vacancy) do
{
vacancy: {
external_advert_url: source.external_advert_url,
expires_at: source.expires_at,
job_title: source.job_title,
job_advert: source.job_advert,
skills_and_experience: source.skills_and_experience,
salary: source.salary,
visa_sponsorship_available: source.visa_sponsorship_available,
external_reference: source.external_reference,
is_job_share: source.is_job_share,
job_roles: source.job_roles,
working_patterns: source.working_patterns,
contract_type: source.contract_type,
phases: source.phases,
schools: {
school_urns: school_urns,
},
},
}
end

before do
allow(Vacancy).to receive(:find_by).and_raise(StandardError.new("Internal server error"))
end

run_test!
end
end
end

Expand Down Expand Up @@ -865,3 +842,4 @@
end
# rubocop:enable RSpec/VariableName
# rubocop:enable RSpec/ScatteredSetup
# rubocop:enable RSpec/EmptyExampleGroup
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@

it "raises ActiveRecord::RecordNotFound" do
expect { create_vacancy_service }.to raise_error(
Publishers::AtsApi::CreateVacancyService::InvalidOrganisationError,
Publishers::AtsApi::CreateVacancyService::InvalidOrganisationError,
"No valid organisations found",
)
end
Expand Down

0 comments on commit e7dfeee

Please sign in to comment.