Skip to content

Commit

Permalink
[CPDLP-3072] Add rake task to create good test data for lead provider…
Browse files Browse the repository at this point in the history
…s in separation environment (#1384)

* [CPDLP-3072] Add rake task to create good test data for lead providers in separation environment

* [CPDLP-3072] Refactor valid test data generators

* [CPDLP-3072] Address PR comments

* [CPDLP-3072] Allow scripts to run on review app as well for PO testing

* Fix typo on separation environment docs
  • Loading branch information
leandroalemao authored May 30, 2024
1 parent bd4dcff commit 265f883
Show file tree
Hide file tree
Showing 8 changed files with 340 additions and 6 deletions.
98 changes: 98 additions & 0 deletions app/services/valid_test_data_generators/applications_populater.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# frozen_string_literal: true

module ValidTestDataGenerators
class ApplicationsPopulater
class << self
def populate(lead_provider:, cohort:, number_of_participants: 50)
new(lead_provider:, cohort:, number_of_participants:).populate
end
end

def populate
return unless Rails.env.in?(%w[development review separation])

logger.info "ApplicationsPopulater: Started!"

ActiveRecord::Base.transaction do
create_participants!
end

logger.info "ApplicationsPopulater: Finished!"
end

private

attr_reader :lead_provider, :cohort, :number_of_participants, :courses, :logger

def initialize(lead_provider:, cohort:, number_of_participants:, logger: Rails.logger)
@lead_provider = lead_provider
@cohort = cohort
@number_of_participants = number_of_participants
@logger = logger
@courses = Course.all.reject { |c| c.identifier == "npq-early-headship-coaching-offer" }
end

def create_participants!
number_of_participants.times { create_participant(school: School.open.order("RANDOM()").first) }
end

def create_participant(school:)
course = courses.sample

user = FactoryBot.create(:user,
:with_get_an_identity_id,
:with_random_name,
date_of_birth: Date.new(1990, 1, 1),
trn: Faker::Number.unique.number(digits: 7),
trn_verified: true,
trn_auto_verified: true)

application = FactoryBot.create(:application,
:pending,
:with_random_work_setting,
school:,
lead_provider:,
user:,
cohort:,
course:,
headteacher_status: Application.headteacher_statuses.keys.sample,
eligible_for_funding: Faker::Boolean.boolean,
itt_provider: IttProvider.currently_approved.order("RANDOM()").first)

methods = %i[accept_application reject_application]

return if Faker::Boolean.boolean

send(methods.sample, application)

return if Faker::Boolean.boolean

application = FactoryBot.create(:application,
:pending,
:with_random_work_setting,
school:,
lead_provider:,
user:,
cohort:,
course: courses.reject { |c| c.identifier == course.identifier }.sample,
headteacher_status: Application.headteacher_statuses.keys.sample,
eligible_for_funding: Faker::Boolean.boolean,
itt_provider: IttProvider.currently_approved.order("RANDOM()").first)

return if Faker::Boolean.boolean

send(methods.sample, application)
end

def accept_application(application)
# TODO: replace by Applications::Accept.new(application:).accept when service class is added
application.update!(lead_provider_approval_status: "accepted")
application.reload
end

def reject_application(application)
Applications::Reject.new(application:).reject
application.reload
end
end
end
93 changes: 93 additions & 0 deletions app/services/valid_test_data_generators/statements_populater.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# frozen_string_literal: true

module ValidTestDataGenerators
class StatementsPopulater
class << self
def populate(lead_provider:, cohort:)
new(lead_provider:, cohort:).populate
end
end

def populate
return unless Rails.env.in?(%w[development review separation])

logger.info "StatementsPopulater: Started!"

ActiveRecord::Base.transaction do
create_statements!
end

logger.info "StatementsPopulater: Finished!"
end

private

attr_reader :lead_provider, :cohort, :logger

def initialize(lead_provider:, cohort:, logger: Rails.logger)
@lead_provider = lead_provider
@cohort = cohort
@logger = logger
end

def create_statements!
logger.info "StatementsPopulater: Creating #{cohort.start_year} cohort statements for #{lead_provider.name}"

statements_names(cohort.start_year).each_with_index do |statements_name, index|
month = statements_name[0]
year = statements_name[1]

logger.info "StatementsPopulater: Creating Statement #{month}/#{year}"

statement = Statement.find_by(
month:,
year:,
lead_provider:,
cohort:,
)

next if statement

deadline_date = Date.new(cohort.start_year, 12, 25) + index.months
payment_date = Date.new(cohort.start_year.succ, 1, 25) + index.months

state = state_for(payment_date, deadline_date)

FactoryBot.create(:statement,
month:,
year:,
lead_provider:,
deadline_date:,
payment_date:,
cohort:,
output_fee: [true, false].sample,
state:,
marked_as_paid_at: state == :paid ? payment_date : nil,
ecf_id: SecureRandom.uuid)

logger.info "StatementsPopulater: Statement #{month}/#{year} successfully created!"
end

logger.info "StatementsPopulater: #{cohort.start_year} cohort statements for #{lead_provider.name} successfully created!"
end

def state_for(payment_date, deadline_date)
return :paid if payment_date < Date.current
return :payable if Date.current.between?(deadline_date, payment_date)

:open
end

def statements_names(cohort_start_year)
1.upto(3).map { |i|
month_names(cohort_start_year + i)
}.flatten(1)
end

def month_names(year)
1.upto(12).map do |month|
Date.new(year, month).strftime("%-m %Y").split
end
end
end
end
6 changes: 2 additions & 4 deletions docs/environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ There are three permanent environments for NPQ and a fourth set of transient env
- Temporary environment for NPQ separation work.
- Enables lead providers and other external users to explore the NPQ separation endpoints.
- Migration feature (for NPQ separation) is currently disabled as we have no corresponding environment in ECF to pull from.
- https://npq-registration-seoaration-web.teacherservices.cloud
- [View deployed commit](https://npq-registration-seoaration-web.teacherservices.cloud/healthcheck.json)
- https://npq-registration-separation-web.teacherservices.cloud
- [View deployed commit](https://npq-registration-separation-web.teacherservices.cloud/healthcheck.json)

## Production

Expand All @@ -63,5 +63,3 @@ There are three permanent environments for NPQ and a fourth set of transient env
- The production environment is the live system, users that are applying for NPQs fill in the forms in this system. Once submitted applications are pushed to the production ECF environment and then out to lead providers.
- https://register-national-professional-qualifications.education.gov.uk
- [View deployed commit](https://register-national-professional-qualifications.education.gov.uk/healthcheck.json)


21 changes: 21 additions & 0 deletions lib/tasks/valid_test_data_generators/separation_data.rake
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# frozen_string_literal: true

namespace :lead_providers do
desc "seed good test data for lead providers for API testing"
task :seed_statements_and_applications, %i[lead_provider_name cohort_start_year] => :environment do |_t, args|
return unless Rails.env.in?(%w[development review separation])

lead_provider = LeadProvider.find_by(name: args[:lead_provider_name])
raise "LeadProvider not found: #{args[:lead_provider_name]}" if args[:lead_provider_name] && !lead_provider

cohort = Cohort.find_by(start_year: args[:cohort_start_year])
raise "Cohort not found: #{args[:cohort_start_year]}" if args[:cohort_start_year] && !cohort

Array.wrap(lead_provider || LeadProvider.all).each do |lp|
Array.wrap(cohort || Cohort.all).each do |c|
ValidTestDataGenerators::ApplicationsPopulater.populate(lead_provider: lp, cohort: c, number_of_participants: 100)
ValidTestDataGenerators::StatementsPopulater.populate(lead_provider: lp, cohort: c)
end
end
end
end
2 changes: 1 addition & 1 deletion spec/factories/applications.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
teacher_catchment_iso_country_code { "GBR" }
itt_provider
funding_choice { Application.funding_choices.keys.sample }
lead_mentor { true }
lead_mentor { Faker::Boolean.boolean }

trait :application_for_school do
school { build(:school) }
Expand Down
2 changes: 1 addition & 1 deletion spec/factories/users.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FactoryBot.define do
factory :user do
sequence(:full_name) { |n| "John Doe #{n}" }
sequence(:email) { |n| "user#{n}@example.com" }
sequence(:email) { Faker::Internet.email(name: full_name) }
trn { "1234567" }
date_of_birth { 30.years.ago }
ecf_id { SecureRandom.uuid }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe ValidTestDataGenerators::ApplicationsPopulater do
let(:lead_provider) { create(:lead_provider) }
let(:cohort) { create(:cohort) }

before { allow(Rails).to receive(:env) { environment.inquiry } }

subject { described_class.new(lead_provider:, cohort:, number_of_participants: 30) }

describe "#populate" do
context "when running in other environment other than separation or development" do
let(:environment) { "test" }

it "returns nil" do
expect(subject.populate).to be_nil
end
end

context "when running in development or separation environments" do
let(:environment) { "separation" }

it "creates users # given in the params" do
expect {
subject.populate
}.to change(User, :count).by(30)
end

it "creates applications" do
expect {
subject.populate
}.to(change(Application, :count))
end

it "creates applications for the given cohort" do
subject.populate

expect(Application.all.map(&:cohort).uniq.first).to eq(cohort)
end

it "creates applications for the given lead provider" do
subject.populate

expect(Application.all.map(&:lead_provider).uniq.first).to eq(lead_provider)
end

it "creates accepted applications" do
expect {
subject.populate
}.to(change { Application.accepted.count })
end

it "creates rejected applications" do
expect {
subject.populate
}.to(change { Application.rejected.count })
end

it "creates eligible for funding applications" do
expect {
subject.populate
}.to(change { Application.eligible_for_funding.count })
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

require "rails_helper"

RSpec.describe ValidTestDataGenerators::StatementsPopulater do
let(:lead_provider) { create(:lead_provider) }
let(:cohort) { create(:cohort, start_year: 2021) }

before { allow(Rails).to receive(:env) { environment.inquiry } }

subject { described_class.new(lead_provider:, cohort:) }

describe "#populate" do
context "when running in other environment other than separation or development" do
let(:environment) { "test" }

it "returns nil" do
expect(subject.populate).to be_nil
end
end

context "when running in development or separation environments" do
let(:environment) { "separation" }

it "creates statements" do
expect {
subject.populate
}.to change(Statement, :count).by(36)
end

it "creates statements for the given cohort" do
subject.populate

expect(Statement.all.map(&:cohort).uniq.first).to eq(cohort)
end

it "creates statements for the given lead provider" do
subject.populate

expect(Statement.all.map(&:lead_provider).uniq.first).to eq(lead_provider)
end

it "creates paid statements" do
expect {
subject.populate
}.to(change { Statement.paid.count })
end

it "creates unpaid statements" do
expect {
subject.populate
}.to(change { Statement.unpaid.count })
end
end
end
end

0 comments on commit 265f883

Please sign in to comment.