Continue on fail of Litefarm import

And report validation errors.
This commit is contained in:
Maikel Linke
2025-12-12 12:38:49 +11:00
parent f90f71cf68
commit f9d255a266
5 changed files with 177 additions and 546 deletions

View File

@@ -33,9 +33,14 @@ module DfcProvider
return
end
DfcImporter.new.import_enterprise_profiles(current_user.id, enterprises_url)
importer = DfcImporter.new
importer.import_enterprise_profiles(current_user.id, enterprises_url)
render json: { success: true }
if importer.errors.blank?
render json: { success: true }
else
render json: { success: true, messages: error_messages(importer.errors) }
end
end
private
@@ -47,5 +52,12 @@ module DfcProvider
def render_message(status, message)
render status:, json: { success: false, message: }
end
def error_messages(errors)
errors.map do |error|
id = error.record.try(:semantic_link)&.semantic_id
"#{id}: #{error.message}"
end
end
end
end

View File

@@ -2,6 +2,8 @@
# Fetch data from another platform and store it locally.
class DfcImporter
attr_reader :errors
def import_enterprise_profiles(platform, enterprises_url)
raise "unsupported platform" if platform != "lf-dev"
@@ -17,6 +19,10 @@ class DfcImporter
enterprise = EnterpriseImporter.new(owner, farm).import
enterprise.save! if enterprise.changed?
enterprise.address.save! if enterprise.address.changed?
rescue ActiveRecord::RecordInvalid => e
Alert.raise(e, farm: DfcIo.export(farm))
@errors ||= []
@errors << e
end
def find_or_import_user(farm)

View File

@@ -76,12 +76,50 @@ RSpec.describe "Events", swagger_doc: "dfc.yaml" do
before do
stub_request(:post, %r{openid-connect/token$})
stub_request(:get, "https://api.beta.litefarm.org/dfc/enterprises/")
.to_return(body: "[]")
end
run_test! do
expect(json_response["success"]).to eq true
describe "when some records fail" do
before do
body = {
'@context': "https://www.datafoodconsortium.org",
'@graph': [
{
'@id': "http://some-id",
'@type': "dfc-b:Enterprise",
'dfc-b:hasMainContact': "http://some-person",
'dfc-b:hasAddress': "http://address",
},
{
'@id': "http://some-person",
'@type': "dfc-b:Person",
'dfc-b:email': "community@litefarm.org",
},
{
'@id': "http://address",
'@type': "dfc-b:Address",
},
]
}.to_json
stub_request(:get, "https://api.beta.litefarm.org/dfc/enterprises/")
.to_return(body:)
end
run_test! do
expect(json_response["success"]).to eq true
expect(json_response["messages"].first)
.to match "http://some-id: Validation failed: Address address1 can't be blank"
end
end
describe "importing an empty list" do
before do
stub_request(:get, "https://api.beta.litefarm.org/dfc/enterprises/")
.to_return(body: "[]")
end
run_test! do
expect(json_response["success"]).to eq true
end
end
end
end

View File

@@ -9,30 +9,37 @@ require_relative "../spec_helper"
# OPENID_APP_SECRET="..."
RSpec.describe DfcImporter do
let(:endpoint) { "https://api.beta.litefarm.org/dfc/enterprises/" }
let(:semantic_id) {
"https://api.beta.litefarm.org/dfc/enterprises/23bfd9b1-98b5-4b91-88e5-efa7cb36219d"
}
it "fetches a list of enterprises", :vcr do
expect {
subject.import_enterprise_profiles("lf-dev", endpoint)
}.to have_enqueued_mail(Spree::UserMailer, :confirmation_instructions).thrice
.and have_enqueued_mail(EnterpriseMailer, :welcome).thrice
}.to have_enqueued_mail(Spree::UserMailer, :confirmation_instructions).exactly(7)
.and have_enqueued_mail(EnterpriseMailer, :welcome).exactly(6)
# You can show the emails in your browser.
# Consider creating a test helper if you find this useful elsewhere.
# allow(ApplicationMailer).to receive(:delivery_method).and_return(:letter_opener)
# perform_enqueued_jobs(only: ActionMailer::MailDeliveryJob)
enterprise = Enterprise.first
expect(enterprise.semantic_link.semantic_id).to match /litefarm\.org/
# Repeating works without creating duplicates:
expect {
subject.import_enterprise_profiles("lf-dev", endpoint)
}.not_to have_enqueued_mail
expect(enterprise.name).to eq "DFC Test Farm Beta Edited (All Supplied Fields)"
enterprise = Enterprise.joins(:semantic_link).find_by(semantic_link: { semantic_id: })
expect(enterprise.name).to eq "DFC Test Farm Beta (All Supplied Fields)"
expect(enterprise.email_address).to eq "dfcshop@example.com"
expect(enterprise.logo.blob.content_type).to eq "image/webp"
expect(enterprise.logo.blob.byte_size).to eq 8974
expect(enterprise.visible).to eq "public"
expect(subject.errors.count).to eq 2
expect(subject.errors.first.record.semantic_link.semantic_id)
.to eq "https://api.beta.litefarm.org/dfc/enterprises/13152ea2-8d19-4309-a443-c95d8879d299"
expect(subject.errors.first.message)
.to eq "Validation failed: Address zipcode can't be blank, Address is invalid"
end
end

File diff suppressed because one or more lines are too long