From 2d91a61dcb38de9ec0b57b1b4498f62a9dfff33d Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Tue, 5 Sep 2023 15:11:02 +1000 Subject: [PATCH 1/6] Add DFC API EnterpriseGroups#show --- .../enterprise_groups_controller.rb | 12 +++++++++ .../app/services/enterprise_builder.rb | 8 ++++++ engines/dfc_provider/config/routes.rb | 1 + .../spec/requests/enterprise_groups_spec.rb | 23 +++++++++++++++++ swagger/dfc.yaml | 25 +++++++++++++++++++ 5 files changed, 69 insertions(+) create mode 100644 engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb create mode 100644 engines/dfc_provider/spec/requests/enterprise_groups_spec.rb diff --git a/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb new file mode 100644 index 0000000000..bd4b6632e6 --- /dev/null +++ b/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +# OFN EnterpriseGroup is represented as DFC Enterprise. +module DfcProvider + class EnterpriseGroupsController < DfcProvider::ApplicationController + def show + group = EnterpriseGroup.find(params[:id]) + enterprise = EnterpriseBuilder.enterprise_group(group) + render json: DfcIo.export(enterprise) + end + end +end diff --git a/engines/dfc_provider/app/services/enterprise_builder.rb b/engines/dfc_provider/app/services/enterprise_builder.rb index bc9a4e1cbd..3885cf4d29 100644 --- a/engines/dfc_provider/app/services/enterprise_builder.rb +++ b/engines/dfc_provider/app/services/enterprise_builder.rb @@ -18,4 +18,12 @@ class EnterpriseBuilder < DfcBuilder e.addLocalization(address) end end + + def self.enterprise_group(group) + DataFoodConsortium::Connector::Enterprise.new( + urls.enterprise_group_url(group.id), + name: group.name, + description: group.description, + ) + end end diff --git a/engines/dfc_provider/config/routes.rb b/engines/dfc_provider/config/routes.rb index 4064a83fca..e42909ac56 100644 --- a/engines/dfc_provider/config/routes.rb +++ b/engines/dfc_provider/config/routes.rb @@ -6,5 +6,6 @@ DfcProvider::Engine.routes.draw do resources :catalog_items, only: [:index, :show, :update] resources :supplied_products, only: [:create, :show, :update] end + resources :enterprise_groups, only: [:show] resources :persons, only: [:show] end diff --git a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb new file mode 100644 index 0000000000..78682c6302 --- /dev/null +++ b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative "../swagger_helper" + +describe "EnterpriseGroups", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: true do + let(:user) { create(:oidc_user) } + let(:group) { create(:enterprise_group, id: 60_000) } + + before { login_as user } + + path "/api/dfc/enterprise_groups/{id}" do + get "Show groups" do + parameter name: :id, in: :path, type: :string + produces "application/json" + + response "200", "successful" do + let(:id) { group.id } + + run_test! + end + end + end +end diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index e0920b29c1..e15d14fdcb 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -234,6 +234,31 @@ paths: "@type": "@id" dfc-b:stockLimitation: '3' dfc-b:sku: new-sku + "/api/dfc/enterprise_groups/{id}": + get: + summary: Show groups + parameters: + - name: id + in: path + required: true + schema: + type: string + tags: + - EnterpriseGroups + responses: + '200': + description: successful + content: + application/json: + examples: + test_example: + value: + "@context": https://www.datafoodconsortium.org + "@id": http://test.host/api/dfc/enterprise_groups/60000 + "@type": dfc-b:Enterprise + dfc-b:hasName: Enterprise group + dfc-b:hasDescription: this is a group + dfc-b:VATnumber: '' "/api/dfc/enterprises/{id}": get: summary: Show enterprise From a03fb01a8c2fe119deb9b48409e5cca2fd982cb9 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Tue, 5 Sep 2023 17:04:20 +1000 Subject: [PATCH 2/6] List enterprises within groups on DFC API --- .../app/services/enterprise_builder.rb | 12 +++++++++++- .../spec/requests/enterprise_groups_spec.rb | 15 +++++++++++++-- swagger/dfc.yaml | 3 ++- 3 files changed, 26 insertions(+), 4 deletions(-) diff --git a/engines/dfc_provider/app/services/enterprise_builder.rb b/engines/dfc_provider/app/services/enterprise_builder.rb index 3885cf4d29..a32d63dfcb 100644 --- a/engines/dfc_provider/app/services/enterprise_builder.rb +++ b/engines/dfc_provider/app/services/enterprise_builder.rb @@ -20,10 +20,20 @@ class EnterpriseBuilder < DfcBuilder end def self.enterprise_group(group) + members = group.enterprises.map do |member| + urls.enterprise_url(member.id) + end + DataFoodConsortium::Connector::Enterprise.new( urls.enterprise_group_url(group.id), name: group.name, description: group.description, - ) + ).tap do |enterprise| + # This property has been agreed by the DFC but hasn't made it's way into + # the Connector yet. + enterprise.registerSemanticProperty("dfc-b:affiliatedBy") do + members + end + end end end diff --git a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb index 78682c6302..148fd3ae75 100644 --- a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb +++ b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb @@ -4,7 +4,13 @@ require_relative "../swagger_helper" describe "EnterpriseGroups", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: true do let(:user) { create(:oidc_user) } - let(:group) { create(:enterprise_group, id: 60_000) } + let(:group) { + create( + :enterprise_group, + id: 60_000, name: "Sustainable Farmers", enterprises: [enterprise], + ) + } + let(:enterprise) { create(:enterprise, id: 10_000) } before { login_as user } @@ -16,7 +22,12 @@ describe "EnterpriseGroups", type: :request, swagger_doc: "dfc.yaml", rswag_auto response "200", "successful" do let(:id) { group.id } - run_test! + run_test! do + expect(json_response).to include( + "dfc-b:hasName" => "Sustainable Farmers", + "dfc-b:affiliatedBy" => "http://test.host/api/dfc/enterprises/10000", + ) + end end end end diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index e15d14fdcb..e7939356a3 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -256,9 +256,10 @@ paths: "@context": https://www.datafoodconsortium.org "@id": http://test.host/api/dfc/enterprise_groups/60000 "@type": dfc-b:Enterprise - dfc-b:hasName: Enterprise group + dfc-b:hasName: Sustainable Farmers dfc-b:hasDescription: this is a group dfc-b:VATnumber: '' + dfc-b:affiliatedBy: http://test.host/api/dfc/enterprises/10000 "/api/dfc/enterprises/{id}": get: summary: Show enterprise From 95d39877525388993cda9e662342dfafb7e23541 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 7 Sep 2023 13:28:12 +1000 Subject: [PATCH 3/6] List enterprise groups on DFC API --- .../enterprise_groups_controller.rb | 10 +++++++ engines/dfc_provider/config/routes.rb | 2 +- .../spec/requests/enterprise_groups_spec.rb | 30 +++++++++++++++++-- swagger/dfc.yaml | 24 +++++++++++++++ 4 files changed, 63 insertions(+), 3 deletions(-) diff --git a/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb index bd4b6632e6..362b540d1d 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb @@ -3,6 +3,16 @@ # OFN EnterpriseGroup is represented as DFC Enterprise. module DfcProvider class EnterpriseGroupsController < DfcProvider::ApplicationController + def index + person = PersonBuilder.person(current_user) + groups = current_user.owned_groups + enterprises = groups.map do |group| + EnterpriseBuilder.enterprise_group(group) + end + person.affiliatedOrganizations = enterprises + render json: DfcIo.export(person, *enterprises) + end + def show group = EnterpriseGroup.find(params[:id]) enterprise = EnterpriseBuilder.enterprise_group(group) diff --git a/engines/dfc_provider/config/routes.rb b/engines/dfc_provider/config/routes.rb index e42909ac56..0f81066b3a 100644 --- a/engines/dfc_provider/config/routes.rb +++ b/engines/dfc_provider/config/routes.rb @@ -6,6 +6,6 @@ DfcProvider::Engine.routes.draw do resources :catalog_items, only: [:index, :show, :update] resources :supplied_products, only: [:create, :show, :update] end - resources :enterprise_groups, only: [:show] + resources :enterprise_groups, only: [:index, :show] resources :persons, only: [:show] end diff --git a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb index 148fd3ae75..3346a62499 100644 --- a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb +++ b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb @@ -3,17 +3,43 @@ require_relative "../swagger_helper" describe "EnterpriseGroups", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: true do - let(:user) { create(:oidc_user) } + let(:user) { create(:oidc_user, id: 12_345) } let(:group) { create( :enterprise_group, - id: 60_000, name: "Sustainable Farmers", enterprises: [enterprise], + id: 60_000, owner: user, name: "Sustainable Farmers", + enterprises: [enterprise], ) } let(:enterprise) { create(:enterprise, id: 10_000) } before { login_as user } + path "/api/dfc/enterprise_groups" do + get "List groups" do + produces "application/json" + + response "200", "successful" do + let!(:groups) { [group] } + + run_test! do + graph = json_response["@graph"] + + expect(graph[0]["@type"]).to eq "dfc-b:Person" + expect(graph[0]).to include( + "dfc-b:affiliates" => "http://test.host/api/dfc/enterprise_groups/60000", + ) + + expect(graph[1]["@type"]).to eq "dfc-b:Enterprise" + expect(graph[1]).to include( + "dfc-b:hasName" => "Sustainable Farmers", + "dfc-b:affiliatedBy" => "http://test.host/api/dfc/enterprises/10000", + ) + end + end + end + end + path "/api/dfc/enterprise_groups/{id}" do get "Show groups" do parameter name: :id, in: :path, type: :string diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index e7939356a3..20de0aba81 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -234,6 +234,30 @@ paths: "@type": "@id" dfc-b:stockLimitation: '3' dfc-b:sku: new-sku + "/api/dfc/enterprise_groups": + get: + summary: List groups + tags: + - EnterpriseGroups + responses: + '200': + description: successful + content: + application/json: + examples: + test_example: + value: + "@context": https://www.datafoodconsortium.org + "@graph": + - "@id": http://test.host/api/dfc/persons/12345 + "@type": dfc-b:Person + dfc-b:affiliates: http://test.host/api/dfc/enterprise_groups/60000 + - "@id": http://test.host/api/dfc/enterprise_groups/60000 + "@type": dfc-b:Enterprise + dfc-b:hasName: Sustainable Farmers + dfc-b:hasDescription: this is a group + dfc-b:VATnumber: '' + dfc-b:affiliatedBy: http://test.host/api/dfc/enterprises/10000 "/api/dfc/enterprise_groups/{id}": get: summary: Show groups From cf18229e5b59951ef478211531856c994a2067cc Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 7 Sep 2023 13:36:24 +1000 Subject: [PATCH 4/6] Avoid loading DFC catalog for Person or Groups endpoint --- .../controllers/dfc_provider/catalog_items_controller.rb | 6 ++++++ engines/dfc_provider/app/services/person_builder.rb | 7 ------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/engines/dfc_provider/app/controllers/dfc_provider/catalog_items_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/catalog_items_controller.rb index 27cf9a824f..c8b2ba59ff 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/catalog_items_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/catalog_items_controller.rb @@ -8,6 +8,12 @@ module DfcProvider def index person = PersonBuilder.person(current_user) + + enterprises = current_user.enterprises.map do |enterprise| + EnterpriseBuilder.enterprise(enterprise) + end + person.affiliatedOrganizations = enterprises + render json: DfcIo.export( person, *person.affiliatedOrganizations, diff --git a/engines/dfc_provider/app/services/person_builder.rb b/engines/dfc_provider/app/services/person_builder.rb index ce3c4beefa..69f22f6495 100644 --- a/engines/dfc_provider/app/services/person_builder.rb +++ b/engines/dfc_provider/app/services/person_builder.rb @@ -6,13 +6,6 @@ class PersonBuilder < DfcBuilder urls.person_url(user.id), firstName: user.bill_address&.firstname, lastName: user.bill_address&.lastname, - affiliatedOrganizations: enterprises(user), ) end - - def self.enterprises(user) - user.enterprises.map do |enterprise| - EnterpriseBuilder.enterprise(enterprise) - end - end end From 88a3615de7c6c8bc1bff622994c10955ea2ef059 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 7 Sep 2023 14:13:39 +1000 Subject: [PATCH 5/6] List groups when showing DFC Enterprise --- .../dfc_provider/enterprises_controller.rb | 6 ++++++ .../dfc_provider/spec/requests/enterprises_spec.rb | 11 +++++++++++ swagger/dfc.yaml | 1 + 3 files changed, 18 insertions(+) diff --git a/engines/dfc_provider/app/controllers/dfc_provider/enterprises_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/enterprises_controller.rb index 74cb1b0ccd..5793d2819f 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/enterprises_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/enterprises_controller.rb @@ -7,6 +7,12 @@ module DfcProvider def show enterprise = EnterpriseBuilder.enterprise(current_enterprise) + + group_ids = current_enterprise.groups.map do |group| + DfcProvider::Engine.routes.url_helpers.enterprise_group_url(group.id) + end + enterprise.registerSemanticProperty("dfc-b:affiliates") { group_ids } + render json: DfcIo.export( enterprise, *enterprise.localizations, diff --git a/engines/dfc_provider/spec/requests/enterprises_spec.rb b/engines/dfc_provider/spec/requests/enterprises_spec.rb index ebe66f827b..3c3835452f 100644 --- a/engines/dfc_provider/spec/requests/enterprises_spec.rb +++ b/engines/dfc_provider/spec/requests/enterprises_spec.rb @@ -12,6 +12,13 @@ describe "Enterprises", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: address: build(:address, id: 40_000, address1: "42 Doveton Street"), ) end + let!(:enterprise_group) do + create( + :enterprise_group, + id: 60_000, owner: user, name: "Local Farmers", + enterprises: [enterprise], + ) + end let!(:product) { create( :base_product, @@ -48,6 +55,10 @@ describe "Enterprises", type: :request, swagger_doc: "dfc.yaml", rswag_autodoc: expect(response.body).to include "123 456" expect(response.body).to include "Apple" expect(response.body).to include "42 Doveton Street" + + expect(json_response["@graph"][0]).to include( + "dfc-b:affiliates" => "http://test.host/api/dfc/enterprise_groups/60000", + ) end end end diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index 20de0aba81..3c24165d27 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -313,6 +313,7 @@ paths: dfc-b:VATnumber: 123 456 dfc-b:supplies: http://test.host/api/dfc/enterprises/10000/supplied_products/10001 dfc-b:manages: http://test.host/api/dfc/enterprises/10000/catalog_items/10001 + dfc-b:affiliates: http://test.host/api/dfc/enterprise_groups/60000 - "@id": http://test.host/api/dfc/addresses/40000 "@type": dfc-b:Address dfc-b:hasStreet: 42 Doveton Street From 7e222ad83ea4efc1d6f5e0a9774c67fa39832dbd Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Thu, 7 Sep 2023 15:06:53 +1000 Subject: [PATCH 6/6] Include address when showing group It may be nice to show more data like social media URLs but the DFC Connector hasn't implemented that yet and it's not specified in the current issue. --- .../enterprise_groups_controller.rb | 4 +++- .../spec/requests/enterprise_groups_spec.rb | 14 +++++++++++-- swagger/dfc.yaml | 20 +++++++++++++------ 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb b/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb index 362b540d1d..55600c1ccd 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/enterprise_groups_controller.rb @@ -15,8 +15,10 @@ module DfcProvider def show group = EnterpriseGroup.find(params[:id]) + address = AddressBuilder.address(group.address) enterprise = EnterpriseBuilder.enterprise_group(group) - render json: DfcIo.export(enterprise) + enterprise.addLocalization(address) + render json: DfcIo.export(enterprise, address) end end end diff --git a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb index 3346a62499..cf1d356707 100644 --- a/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb +++ b/engines/dfc_provider/spec/requests/enterprise_groups_spec.rb @@ -7,10 +7,11 @@ describe "EnterpriseGroups", type: :request, swagger_doc: "dfc.yaml", rswag_auto let(:group) { create( :enterprise_group, - id: 60_000, owner: user, name: "Sustainable Farmers", + id: 60_000, owner: user, name: "Sustainable Farmers", address:, enterprises: [enterprise], ) } + let(:address) { create(:address, id: 40_000, address1: "8 Acres Drive") } let(:enterprise) { create(:enterprise, id: 10_000) } before { login_as user } @@ -49,10 +50,19 @@ describe "EnterpriseGroups", type: :request, swagger_doc: "dfc.yaml", rswag_auto let(:id) { group.id } run_test! do - expect(json_response).to include( + graph = json_response["@graph"] + + expect(graph[0]).to include( + "@type" => "dfc-b:Enterprise", "dfc-b:hasName" => "Sustainable Farmers", + "dfc-b:hasAddress" => "http://test.host/api/dfc/addresses/40000", "dfc-b:affiliatedBy" => "http://test.host/api/dfc/enterprises/10000", ) + + expect(graph[1]).to include( + "@type" => "dfc-b:Address", + "dfc-b:hasStreet" => "8 Acres Drive", + ) end end end diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index 3c24165d27..8927ccfc1d 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -278,12 +278,20 @@ paths: test_example: value: "@context": https://www.datafoodconsortium.org - "@id": http://test.host/api/dfc/enterprise_groups/60000 - "@type": dfc-b:Enterprise - dfc-b:hasName: Sustainable Farmers - dfc-b:hasDescription: this is a group - dfc-b:VATnumber: '' - dfc-b:affiliatedBy: http://test.host/api/dfc/enterprises/10000 + "@graph": + - "@id": http://test.host/api/dfc/enterprise_groups/60000 + "@type": dfc-b:Enterprise + dfc-b:hasAddress: http://test.host/api/dfc/addresses/40000 + dfc-b:hasName: Sustainable Farmers + dfc-b:hasDescription: this is a group + dfc-b:VATnumber: '' + dfc-b:affiliatedBy: http://test.host/api/dfc/enterprises/10000 + - "@id": http://test.host/api/dfc/addresses/40000 + "@type": dfc-b:Address + dfc-b:hasStreet: 8 Acres Drive + dfc-b:hasPostalCode: '20170' + dfc-b:hasCity: Herndon + dfc-b:hasCountry: Australia "/api/dfc/enterprises/{id}": get: summary: Show enterprise