mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-27 01:43:22 +00:00
Add service to access FDC API
The current implementation of the FDC is not adhering to the DFC standard. The difference is added in this compatibility layer. This should be temporary code. The FDC dev team should change their API in their next development cycle.
This commit is contained in:
33
engines/dfc_provider/app/services/fdc_request.rb
Normal file
33
engines/dfc_provider/app/services/fdc_request.rb
Normal file
@@ -0,0 +1,33 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require "private_address_check"
|
||||
require "private_address_check/tcpsocket_ext"
|
||||
|
||||
# Request a JSON document from the FDC API with authentication.
|
||||
#
|
||||
# Currently, the API doesn't quite comply with the DFC standard and we need
|
||||
# to authenticate a little bit differently.
|
||||
#
|
||||
# And then we get slightly different data as well.
|
||||
class FdcRequest < DfcRequest
|
||||
# Override main method to POST authorization data.
|
||||
def call(url, data = {})
|
||||
response = request(url, auth_data.merge(data).to_json)
|
||||
|
||||
if response.status >= 400 && token_stale?
|
||||
refresh_access_token!
|
||||
response = request(url, auth_data.merge(data).to_json)
|
||||
end
|
||||
|
||||
response.body
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def auth_data
|
||||
{
|
||||
userId: @user.oidc_account.uid,
|
||||
accessToken: @user.oidc_account.token,
|
||||
}
|
||||
end
|
||||
end
|
||||
36
engines/dfc_provider/spec/services/fdc_request_spec.rb
Normal file
36
engines/dfc_provider/spec/services/fdc_request_spec.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
require_relative "../spec_helper"
|
||||
|
||||
RSpec.describe FdcRequest do
|
||||
subject(:api) { FdcRequest.new(user) }
|
||||
|
||||
let(:user) { build(:oidc_user) }
|
||||
let(:account) { user.oidc_account }
|
||||
let(:url) {
|
||||
"https://food-data-collaboration-produc-fe870152f634.herokuapp.com/fdc/products?shop=test-hodmedod.myshopify.com"
|
||||
}
|
||||
|
||||
it "refreshes the access token and retrieves a catalog", vcr: true do
|
||||
# A refresh is only attempted if the token is stale.
|
||||
account.uid = "testdfc@protonmail.com"
|
||||
account.refresh_token = ENV.fetch("OPENID_REFRESH_TOKEN")
|
||||
account.updated_at = 1.day.ago
|
||||
|
||||
response = nil
|
||||
expect {
|
||||
response = api.call(url)
|
||||
}.to change {
|
||||
account.token
|
||||
}.and change {
|
||||
account.refresh_token
|
||||
}
|
||||
|
||||
json = JSON.parse(response)
|
||||
expect(json["message"]).to eq "Products retrieved successfully"
|
||||
|
||||
graph = DfcIo.import(json["products"])
|
||||
products = graph.select { |s| s.semanticType == "dfc-b:SuppliedProduct" }
|
||||
expect(products).to be_present
|
||||
end
|
||||
end
|
||||
206
spec/fixtures/vcr_cassettes/FdcRequest/refreshes_the_access_token_and_retrieves_a_catalog.yml
vendored
Normal file
206
spec/fixtures/vcr_cassettes/FdcRequest/refreshes_the_access_token_and_retrieves_a_catalog.yml
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -40,4 +40,9 @@ VCR.configure do |config|
|
||||
config.filter_sensitive_data('<HIDDEN-OPENID-TOKEN>') { |interaction|
|
||||
interaction.response.body.match(/"refresh_token":"([^"]+)"/)&.public_send(:[], 1)
|
||||
}
|
||||
|
||||
# FDC specific parameter:
|
||||
config.filter_sensitive_data('<HIDDEN-OPENID-TOKEN>') { |interaction|
|
||||
interaction.request.body.match(/"accessToken":"([^"]+)"/)&.public_send(:[], 1)
|
||||
}
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user