Browse Source

Move tests

pull/2438/head
Kat 2 years ago
parent
commit
b85793b967
  1. 74
      app/services/documentation_generator.rb
  2. 2
      config/initializers/rails_admin.rb
  3. 16
      lib/tasks/generate_lettings_documentation.rake
  4. 4
      lib/tasks/generate_sales_documentation.rake
  5. 187
      spec/lib/tasks/generate_lettings_documentation_spec.rb
  6. 187
      spec/lib/tasks/generate_sales_documentation_spec.rb
  7. 230
      spec/services/documentation_generator_spec.rb

74
app/services/documentation_generator.rb

@ -13,7 +13,7 @@ class DocumentationGenerator
form = FormHandler.instance.forms["current_#{log_type}"] form = FormHandler.instance.forms["current_#{log_type}"]
all_validation_methods.each do |meth| all_validation_methods.each do |meth|
if LogValidation.where(validation_name: meth.to_s, bulk_upload_specific: false).exists? if LogValidation.where(validation_name: meth.to_s, bulk_upload_specific: false, log_type:).exists?
Rails.logger.info("Validation #{meth} already exists") Rails.logger.info("Validation #{meth} already exists")
next next
end end
@ -41,7 +41,7 @@ class DocumentationGenerator
def describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type) def describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type)
all_validation_methods.each do |meth| all_validation_methods.each do |meth|
if LogValidation.where(validation_name: meth.to_s, bulk_upload_specific: true, from: form.start_date).exists? if LogValidation.where(validation_name: meth.to_s, bulk_upload_specific: true, from: form.start_date, log_type:).exists?
Rails.logger.info("Validation #{meth} already exists for #{form.start_date.year}") Rails.logger.info("Validation #{meth} already exists for #{form.start_date.year}")
next next
end end
@ -265,17 +265,17 @@ Look at these helper methods where needed to understand what is being checked in
result["cases"].each do |case_info| result["cases"].each do |case_info|
case_info["errors"].each do |error| case_info["errors"].each do |error|
LogValidation.create!(log_type:, LogValidation.create!(log_type:,
validation_name: meth.to_s, validation_name: meth.to_s,
description: result["description"], description: result["description"],
field: error["field"], field: error["field"],
error_message: error["error_message"], error_message: error["error_message"],
case: case_info["case_description"], case: case_info["case_description"],
section: form.get_question(error["field"], nil)&.subsection&.id, section: form.get_question(error["field"], nil)&.subsection&.id,
from: case_info["from"] || "", from: case_info["from"] || "",
to: case_info["to"] || "", to: case_info["to"] || "",
validation_type: case_info["validation_type"], validation_type: case_info["validation_type"],
hard_soft: "hard", hard_soft: "hard",
other_validated_models: case_info["other_validated_models"]) other_validated_models: case_info["other_validated_models"])
end end
end end
@ -289,18 +289,18 @@ Look at these helper methods where needed to understand what is being checked in
error_fields = [error["field"]] if error_fields.empty? error_fields = [error["field"]] if error_fields.empty?
error_fields.each do |error_field| error_fields.each do |error_field|
LogValidation.create!(log_type:, LogValidation.create!(log_type:,
validation_name: meth.to_s, validation_name: meth.to_s,
description: result["description"], description: result["description"],
field: error_field, field: error_field,
error_message: error["error_message"], error_message: error["error_message"],
case: case_info["case_description"], case: case_info["case_description"],
section: form.get_question(error_field, nil)&.subsection&.id, section: form.get_question(error_field, nil)&.subsection&.id,
from: form.start_date, from: form.start_date,
to: form.start_date + 1.year, to: form.start_date + 1.year,
validation_type: case_info["validation_type"], validation_type: case_info["validation_type"],
hard_soft: "hard", hard_soft: "hard",
other_validated_models: case_info["other_validated_models"], other_validated_models: case_info["other_validated_models"],
bulk_upload_specific: true) bulk_upload_specific: true)
end end
end end
end end
@ -333,7 +333,7 @@ Look at these helper methods where needed to understand what is being checked in
return return
end end
if LogValidation.where(validation_name: validation_depends_on_hash.keys.first, field: page_the_validation_applied_to.questions.first.id, from: form.start_date).exists? if LogValidation.where(validation_name: validation_depends_on_hash.keys.first, field: page_the_validation_applied_to.questions.first.id, from: form.start_date, log_type:).exists?
Rails.logger.info("Validation #{validation_depends_on_hash.keys.first} already exists for #{page_the_validation_applied_to.questions.first.id} for start year #{form.start_date.year}") Rails.logger.info("Validation #{validation_depends_on_hash.keys.first} already exists for #{page_the_validation_applied_to.questions.first.id} for start year #{form.start_date.year}")
return return
end end
@ -354,17 +354,17 @@ Look at these helper methods where needed to understand what is being checked in
case_info = page.depends_on.first.values.first ? "Provided values fulfill the description" : "Provided values do not fulfill the description" case_info = page.depends_on.first.values.first ? "Provided values fulfill the description" : "Provided values do not fulfill the description"
LogValidation.create!(log_type:, LogValidation.create!(log_type:,
validation_name: validation_depends_on_hash.keys.first.to_s, validation_name: validation_depends_on_hash.keys.first.to_s,
description: result["description"], description: result["description"],
field: page_the_validation_applied_to.questions.first.id, field: page_the_validation_applied_to.questions.first.id,
error_message:, error_message:,
case: case_info, case: case_info,
section: form.get_question(page_the_validation_applied_to.questions.first.id, nil)&.subsection&.id, section: form.get_question(page_the_validation_applied_to.questions.first.id, nil)&.subsection&.id,
from: form.start_date, from: form.start_date,
to: form.start_date + 1.year, to: form.start_date + 1.year,
validation_type: result["validation_type"], validation_type: result["validation_type"],
hard_soft: "soft", hard_soft: "soft",
other_validated_models: result["other_validated_models"]) other_validated_models: result["other_validated_models"])
Rails.logger.info("******** described #{validation_depends_on_hash.keys.first} for #{page_the_validation_applied_to.questions.first.id} ********") Rails.logger.info("******** described #{validation_depends_on_hash.keys.first} for #{page_the_validation_applied_to.questions.first.id} ********")
end end

2
config/initializers/rails_admin.rb

@ -26,7 +26,7 @@ RailsAdmin.config do |config|
## == Gravatar integration == ## == Gravatar integration ==
## To disable Gravatar integration in Navigation Bar set to false ## To disable Gravatar integration in Navigation Bar set to false
# config.show_gravatar = true # config.show_gravatar = true
config.included_models = %w[Validation] config.included_models = %w[LogValidation]
config.actions do config.actions do
dashboard # mandatory dashboard # mandatory

16
lib/tasks/generate_lettings_documentation.rake

@ -77,14 +77,14 @@ namespace :generate_lettings_documentation do
end end
LogValidation.create!(log_type: "lettings", LogValidation.create!(log_type: "lettings",
validation_name:, validation_name:,
description: validation_description, description: validation_description,
field:, field:,
error_message:, error_message:,
case: validation_description, case: validation_description,
section: form.get_question(field, nil)&.subsection&.id, section: form.get_question(field, nil)&.subsection&.id,
validation_type: validation_name, validation_type: validation_name,
hard_soft: "hard") hard_soft: "hard")
end end
end end
end end

4
lib/tasks/generate_sales_documentation.rake

@ -69,13 +69,13 @@ namespace :generate_sales_documentation do
validation_description = "Field value is lower than the minimum value or higher than the maximum value" validation_description = "Field value is lower than the minimum value or higher than the maximum value"
end end
if Validation.where(validation_name:, field:).exists? if LogValidation.where(validation_name:, field:).exists?
Rails.logger.info("Validation #{validation_name} already exists for #{field}") Rails.logger.info("Validation #{validation_name} already exists for #{field}")
next next
end end
Validation.create!(log_type: "sales", LogValidation.create!(log_type: "sales",
validation_name:, validation_name:,
description: validation_description, description: validation_description,
field:, field:,

187
spec/lib/tasks/generate_lettings_documentation_spec.rb

@ -2,189 +2,6 @@ require "rails_helper"
require "rake" require "rake"
RSpec.describe "generate_lettings_documentation" do RSpec.describe "generate_lettings_documentation" do
describe ":describe_lettings_validations", type: :task do
subject(:task) { Rake::Task["generate_lettings_documentation:describe_lettings_validations"] }
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"cases\": [\n {\n \"case_description\": \"Previous postcode is known and current postcode is blank\",\n \"errors\": [\n {\n \"error_message\": \"Enter a valid postcode\",\n \"field\": \"ppostcode_full\"\n }\n ],\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\" }]\n}" } }] } }] }
end
before do
Rake.application.rake_require("tasks/generate_lettings_documentation")
Rake::Task.define_task(:environment)
task.reenable
allow(OpenAI::Client).to receive(:new).and_return(client)
allow(client).to receive(:chat).and_return(response)
end
context "when the rake task is run" do
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { task.invoke }.to change(Validation, :count)
expect(LogValidation.where(validation_name: "validate_numeric_min_max").count).to eq(1)
expect(LogValidation.where(validation_name: "validate_layear").count).to eq(1)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).to be_nil
expect(any_validation.to).to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("lettings")
end
it "calls openAI client" do
expect(client).to receive(:chat)
task.invoke
end
it "skips if the validation already exists in the database" do
task.invoke
expect { task.invoke }.not_to change(Validation, :count)
end
context "when openAI response is not a JSON" do
let(:response) { "not a JSON" }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
context "when openAI response does not have expected fields" do
let(:response) { { "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" => "{}" } }] } }] } }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
end
end
describe ":describe_soft_lettings_validations", type: :task do
subject(:task) { Rake::Task["generate_lettings_documentation:describe_soft_lettings_validations"] }
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\"}" } }] } }] }
end
before do
Rake.application.rake_require("tasks/generate_lettings_documentation")
Rake::Task.define_task(:environment)
task.reenable
allow(OpenAI::Client).to receive(:new).and_return(client)
allow(client).to receive(:chat).and_return(response)
end
context "when the rake task is run" do
it "creates new validation documentation records" do
expect { task.invoke }.to change(Validation, :count)
expect(LogValidation.where(validation_name: "rent_in_soft_min_range?").count).to be_positive
expect(LogValidation.where(validation_name: "major_repairs_date_in_soft_range?").count).to be_positive
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).not_to be_empty
expect(any_validation.error_message).not_to be_empty
expect(any_validation.case).to eq("Provided values fulfill the description")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("soft")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("lettings")
end
it "calls openAI client" do
expect(client).to receive(:chat)
task.invoke
end
it "skips if the validation already exists in the database" do
task.invoke
expect { task.invoke }.not_to change(Validation, :count)
end
end
end
describe ":describe_bu_lettings_validations", type: :task do
subject(:task) { Rake::Task["generate_lettings_documentation:describe_bu_lettings_validations"] }
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"cases\": [\n {\n \"case_description\": \"Previous postcode is known and current postcode is blank\",\n \"errors\": [\n {\n \"error_message\": \"Enter a valid postcode\",\n \"field\": \"ppostcode_full\"\n }\n ],\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\" }]\n}" } }] } }] }
end
before do
Rake.application.rake_require("tasks/generate_lettings_documentation")
Rake::Task.define_task(:environment)
task.reenable
allow(OpenAI::Client).to receive(:new).and_return(client)
allow(client).to receive(:chat).and_return(response)
end
context "when the rake task is run" do
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { task.invoke }.to change(Validation, :count)
expect(LogValidation.where(validation_name: "validate_needs_type_present").count).to eq(2) # for both years
expect(LogValidation.where(validation_name: "validate_data_types").count).to eq(2)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("lettings")
end
it "calls openAI client" do
expect(client).to receive(:chat)
task.invoke
end
it "skips if the validation already exists in the database" do
task.invoke
expect { task.invoke }.not_to change(Validation, :count)
end
context "when openAI response is not a JSON" do
let(:response) { "not a JSON" }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
context "when openAI response does not have expected fields" do
let(:response) { { "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" => "{}" } }] } }] } }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
end
end
describe ":add_numeric_lettings_validations", type: :task do describe ":add_numeric_lettings_validations", type: :task do
subject(:task) { Rake::Task["generate_lettings_documentation:add_numeric_lettings_validations"] } subject(:task) { Rake::Task["generate_lettings_documentation:add_numeric_lettings_validations"] }
@ -196,7 +13,7 @@ RSpec.describe "generate_lettings_documentation" do
context "when the rake task is run" do context "when the rake task is run" do
it "creates new validation documentation records" do it "creates new validation documentation records" do
expect { task.invoke }.to change(Validation, :count) expect { task.invoke }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "minimum").count).to be_positive expect(LogValidation.where(validation_name: "minimum").count).to be_positive
expect(LogValidation.where(validation_name: "range").count).to be_positive expect(LogValidation.where(validation_name: "range").count).to be_positive
any_min_validation = LogValidation.where(validation_name: "minimum").first any_min_validation = LogValidation.where(validation_name: "minimum").first
@ -214,7 +31,7 @@ RSpec.describe "generate_lettings_documentation" do
it "skips if the validation already exists in the database" do it "skips if the validation already exists in the database" do
task.invoke task.invoke
expect { task.invoke }.not_to change(Validation, :count) expect { task.invoke }.not_to change(LogValidation, :count)
end end
end end
end end

187
spec/lib/tasks/generate_sales_documentation_spec.rb

@ -2,189 +2,6 @@ require "rails_helper"
require "rake" require "rake"
RSpec.describe "generate_sales_documentation" do RSpec.describe "generate_sales_documentation" do
describe ":describe_sales_validations", type: :task do
subject(:task) { Rake::Task["generate_sales_documentation:describe_sales_validations"] }
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"cases\": [\n {\n \"case_description\": \"Previous postcode is known and current postcode is blank\",\n \"errors\": [\n {\n \"error_message\": \"Enter a valid postcode\",\n \"field\": \"ppostcode_full\"\n }\n ],\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\" }]\n}" } }] } }] }
end
before do
Rake.application.rake_require("tasks/generate_sales_documentation")
Rake::Task.define_task(:environment)
task.reenable
allow(OpenAI::Client).to receive(:new).and_return(client)
allow(client).to receive(:chat).and_return(response)
end
context "when the rake task is run" do
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { task.invoke }.to change(Validation, :count)
expect(LogValidation.where(validation_name: "validate_saledate_collection_year").count).to eq(1)
expect(LogValidation.where(validation_name: "validate_partner_count").count).to eq(1)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).to be_nil
expect(any_validation.to).to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("sales")
end
it "calls openAI client" do
expect(client).to receive(:chat)
task.invoke
end
it "skips if the validation already exists in the database" do
task.invoke
expect { task.invoke }.not_to change(Validation, :count)
end
context "when openAI response is not a JSON" do
let(:response) { "not a JSON" }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
context "when openAI response does not have expected fields" do
let(:response) { { "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" => "{}" } }] } }] } }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
end
end
describe ":describe_soft_sales_validations", type: :task do
subject(:task) { Rake::Task["generate_sales_documentation:describe_soft_sales_validations"] }
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\"}" } }] } }] }
end
before do
Rake.application.rake_require("tasks/generate_sales_documentation")
Rake::Task.define_task(:environment)
task.reenable
allow(OpenAI::Client).to receive(:new).and_return(client)
allow(client).to receive(:chat).and_return(response)
end
context "when the rake task is run" do
it "creates new validation documentation records" do
expect { task.invoke }.to change(Validation, :count)
expect(LogValidation.where(validation_name: "income2_under_soft_min?").count).to be_positive
expect(LogValidation.where(validation_name: "deposit_over_soft_max?").count).to be_positive
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).not_to be_empty
expect(any_validation.error_message).not_to be_empty
expect(any_validation.case).to eq("Provided values fulfill the description")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("soft")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("sales")
end
it "calls openAI client" do
expect(client).to receive(:chat)
task.invoke
end
it "skips if the validation already exists in the database" do
task.invoke
expect { task.invoke }.not_to change(Validation, :count)
end
end
end
describe ":describe_bu_sales_validations", type: :task do
subject(:task) { Rake::Task["generate_sales_documentation:describe_bu_sales_validations"] }
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"cases\": [\n {\n \"case_description\": \"Previous postcode is known and current postcode is blank\",\n \"errors\": [\n {\n \"error_message\": \"Enter a valid postcode\",\n \"field\": \"ppostcode_full\"\n }\n ],\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\" }]\n}" } }] } }] }
end
before do
Rake.application.rake_require("tasks/generate_sales_documentation")
Rake::Task.define_task(:environment)
task.reenable
allow(OpenAI::Client).to receive(:new).and_return(client)
allow(client).to receive(:chat).and_return(response)
end
context "when the rake task is run" do
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { task.invoke }.to change(Validation, :count)
expect(LogValidation.where(validation_name: "validate_owning_org_data_given").count).to eq(2) # for both years
expect(LogValidation.where(validation_name: "validate_assigned_to_exists").count).to eq(2)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("sales")
end
it "calls openAI client" do
expect(client).to receive(:chat)
task.invoke
end
it "skips if the validation already exists in the database" do
task.invoke
expect { task.invoke }.not_to change(Validation, :count)
end
context "when openAI response is not a JSON" do
let(:response) { "not a JSON" }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
context "when openAI response does not have expected fields" do
let(:response) { { "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" => "{}" } }] } }] } }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
task.invoke
end
end
end
end
describe ":add_numeric_sales_validations", type: :task do describe ":add_numeric_sales_validations", type: :task do
subject(:task) { Rake::Task["generate_sales_documentation:add_numeric_sales_validations"] } subject(:task) { Rake::Task["generate_sales_documentation:add_numeric_sales_validations"] }
@ -196,7 +13,7 @@ RSpec.describe "generate_sales_documentation" do
context "when the rake task is run" do context "when the rake task is run" do
it "creates new validation documentation records" do it "creates new validation documentation records" do
expect { task.invoke }.to change(Validation, :count) expect { task.invoke }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "minimum").count).to be_positive expect(LogValidation.where(validation_name: "minimum").count).to be_positive
expect(LogValidation.where(validation_name: "range").count).to be_positive expect(LogValidation.where(validation_name: "range").count).to be_positive
any_min_validation = LogValidation.where(validation_name: "minimum").first any_min_validation = LogValidation.where(validation_name: "minimum").first
@ -214,7 +31,7 @@ RSpec.describe "generate_sales_documentation" do
it "skips if the validation already exists in the database" do it "skips if the validation already exists in the database" do
task.invoke task.invoke
expect { task.invoke }.not_to change(Validation, :count) expect { task.invoke }.not_to change(LogValidation, :count)
end end
end end
end end

230
spec/services/documentation_generator_spec.rb

@ -0,0 +1,230 @@
require "rails_helper"
describe DocumentationGenerator do
let(:client) { instance_double(OpenAI::Client) }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"cases\": [\n {\n \"case_description\": \"Previous postcode is known and current postcode is blank\",\n \"errors\": [\n {\n \"error_message\": \"Enter a valid postcode\",\n \"field\": \"ppostcode_full\"\n }\n ],\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\" }]\n}" } }] } }] }
end
let(:all_validation_methods) { %w[validate_numeric_min_max] }
let(:all_helper_methods) { [] }
let(:log_type) { "lettings" }
before do
allow(client).to receive(:chat).and_return(response)
end
describe ":describe_hard_validations" do
context "when the service is run with lettings type" do
let(:log_type) { "lettings" }
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type) }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "validate_numeric_min_max").count).to eq(1)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).to be_nil
expect(any_validation.to).to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("lettings")
end
it "calls the client" do
expect(client).to receive(:chat)
described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type)
end
it "skips if the validation already exists in the database" do
described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type)
expect { described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type) }.not_to change(LogValidation, :count)
end
context "when the response is not a JSON" do
let(:response) { "not a JSON" }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type)
end
end
context "when the response does not have expected fields" do
let(:response) { { "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" => "{}" } }] } }] } }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type)
end
end
end
context "when the service is run with sales type" do
let(:log_type) { "sales" }
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { described_class.new.describe_hard_validations(client, all_validation_methods, all_helper_methods, log_type) }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "validate_numeric_min_max").count).to eq(1)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).to be_nil
expect(any_validation.to).to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("sales")
end
end
end
describe ":describe_soft_validations" do
let(:all_validation_methods) { ["rent_in_soft_min_range?"] }
let(:response) do
{ "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" =>
"{\n \"description\": \"Validates the format.\",\n \"validation_type\": \"format\",\n \"other_validated_models\": \"User\"}" } }] } }] }
end
context "when the service is run for lettings" do
let(:log_type) { "lettings" }
it "creates new validation documentation records" do
expect { described_class.new.describe_soft_validations(client, all_validation_methods, all_helper_methods, log_type) }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "rent_in_soft_min_range?").count).to be_positive
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).not_to be_empty
expect(any_validation.error_message).not_to be_empty
expect(any_validation.case).to eq("Provided values fulfill the description")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("soft")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("lettings")
end
it "calls the client" do
expect(client).to receive(:chat)
described_class.new.describe_soft_validations(client, all_validation_methods, all_helper_methods, log_type)
end
it "skips if the validation already exists in the database" do
described_class.new.describe_soft_validations(client, all_validation_methods, all_helper_methods, log_type)
expect { described_class.new.describe_soft_validations(client, all_validation_methods, all_helper_methods, log_type) }.not_to change(LogValidation, :count)
end
end
context "when the service is run for sales" do
let(:log_type) { "sales" }
let(:all_validation_methods) { ["income2_under_soft_min?"] }
it "creates new validation documentation records" do
expect { described_class.new.describe_soft_validations(client, all_validation_methods, all_helper_methods, log_type) }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "income2_under_soft_min?").count).to be_positive
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).not_to be_empty
expect(any_validation.error_message).not_to be_empty
expect(any_validation.case).to eq("Provided values fulfill the description")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("soft")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("sales")
end
end
end
describe ":describe_bu_validations", type: :task do
let(:all_validation_methods) { %w[validate_owning_org_data_given] }
let(:field_mapping_for_errors) { row_parser_class.new.send("field_mapping_for_errors") }
context "when the service is run for lettings" do
let(:log_type) { "lettings" }
let(:form) { FormHandler.instance.forms[FormHandler.instance.form_name_from_start_year(2023, "lettings")] }
let(:row_parser_class) { BulkUpload::Lettings::Year2023::RowParser }
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type) }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "validate_owning_org_data_given").count).to eq(1)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("lettings")
end
it "calls the client" do
expect(client).to receive(:chat)
described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type)
end
it "skips if the validation already exists in the database" do
described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type)
expect { described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type) }.not_to change(LogValidation, :count)
end
context "when the response is not a JSON" do
let(:response) { "not a JSON" }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type)
end
end
context "when the response does not have expected fields" do
let(:response) { { "choices" => [{ "message" => { "tool_calls" => [{ "function" => { "arguments" => "{}" } }] } }] } }
it "raises an error" do
expect(Rails.logger).to receive(:error).with(/Failed to save/).at_least(:once)
expect(Rails.logger).to receive(:error).with(/Error/).at_least(:once)
described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type)
end
end
end
context "when the service is run for sales" do
let(:log_type) { "sales" }
let(:form) { FormHandler.instance.forms[FormHandler.instance.form_name_from_start_year(2023, "sales")] }
let(:row_parser_class) { BulkUpload::Sales::Year2023::RowParser }
it "creates new validation documentation records" do
expect(Rails.logger).to receive(:info).with(/described/).at_least(:once)
expect { described_class.new.describe_bu_validations(client, form, row_parser_class, all_validation_methods, all_helper_methods, field_mapping_for_errors, log_type) }.to change(LogValidation, :count)
expect(LogValidation.where(validation_name: "validate_owning_org_data_given").count).to eq(1)
any_validation = LogValidation.first
expect(any_validation.description).to eq("Validates the format.")
expect(any_validation.field).to eq("ppostcode_full")
expect(any_validation.error_message).to eq("Enter a valid postcode")
expect(any_validation.case).to eq("Previous postcode is known and current postcode is blank")
expect(any_validation.from).not_to be_nil
expect(any_validation.to).not_to be_nil
expect(any_validation.validation_type).to eq("format")
expect(any_validation.hard_soft).to eq("hard")
expect(any_validation.other_validated_models).to eq("User")
expect(any_validation.log_type).to eq("sales")
end
end
end
end
Loading…
Cancel
Save