From 4d59343f6c2d29d8e73eb50ce02e0de615ffd519 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 15 Sep 2025 15:20:35 +1000 Subject: [PATCH] List enterprises on DFC API --- .../dfc_provider/enterprises_controller.rb | 17 +++- engines/dfc_provider/config/routes.rb | 2 +- .../spec/requests/enterprises_spec.rb | 77 +++++++++++++++++ swagger/dfc.yaml | 84 +++++++++++++++++++ 4 files changed, 178 insertions(+), 2 deletions(-) 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 5575d13f14..00487b3018 100644 --- a/engines/dfc_provider/app/controllers/dfc_provider/enterprises_controller.rb +++ b/engines/dfc_provider/app/controllers/dfc_provider/enterprises_controller.rb @@ -3,7 +3,22 @@ # Controller used to provide the CatalogItem API for the DFC application module DfcProvider class EnterprisesController < DfcProvider::ApplicationController - before_action :check_enterprise + before_action :check_enterprise, except: :index + + def index + enterprises = current_user.enterprises.map do |enterprise| + EnterpriseBuilder.enterprise(enterprise) + end + + render json: DfcIo.export( + *enterprises, + *enterprises.map(&:mainContact), + *enterprises.flat_map(&:localizations), + *enterprises.flat_map(&:suppliedProducts), + *enterprises.flat_map(&:catalogItems), + *enterprises.flat_map(&:socialMedias), + ) + end def show enterprise = EnterpriseBuilder.enterprise(current_enterprise) diff --git a/engines/dfc_provider/config/routes.rb b/engines/dfc_provider/config/routes.rb index 6c7c487040..28870be6b2 100644 --- a/engines/dfc_provider/config/routes.rb +++ b/engines/dfc_provider/config/routes.rb @@ -2,7 +2,7 @@ DfcProvider::Engine.routes.draw do resources :addresses, only: [:show] - resources :enterprises, only: [:show] do + resources :enterprises, only: [:index, :show] do resources :catalog_items, only: [:index, :show, :update] resources :offers, only: [:show, :update] resources :platforms, only: [:index, :show, :update] diff --git a/engines/dfc_provider/spec/requests/enterprises_spec.rb b/engines/dfc_provider/spec/requests/enterprises_spec.rb index d5b1dc0a7a..fb67ec8666 100644 --- a/engines/dfc_provider/spec/requests/enterprises_spec.rb +++ b/engines/dfc_provider/spec/requests/enterprises_spec.rb @@ -18,6 +18,14 @@ RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do address: build(:address, id: 40_000, address1: "42 Doveton Street"), ) end + let!(:other_enterprise) do + create( + :distributor_enterprise, + id: 10_001, owner: user, abn: "123 457", name: "Fred's Icecream", + description: "We use our strawberries to make icecream.", + address: build(:address, id: 40_001, address1: "42 Doveton Street"), + ) + end let!(:enterprise_group) do create( :enterprise_group, @@ -46,6 +54,75 @@ RSpec.describe "Enterprises", swagger_doc: "dfc.yaml" do before { login_as user } + path "/api/dfc/enterprises" do + get "List enterprises" do + produces "application/json" + + response "200", "successful" do + context "as platform user" do + include_context "authenticated as platform" + + context "without permissions" do + run_test! do + expect(response.body).to eq "" + end + end + + context "with access to one enterprise" do + before do + DfcPermission.create!( + user:, enterprise_id: enterprise.id, + scope: "ReadEnterprise", grantee: "cqcm-dev", + ) + end + + run_test! do + expect(response.body).to include "Fred's Farm" + expect(response.body).not_to include "Fred's Icecream" + end + end + + context "with access to two enterprises" do + before do + DfcPermission.create!( + user:, enterprise_id: enterprise.id, + scope: "ReadEnterprise", grantee: "cqcm-dev", + ) + DfcPermission.create!( + user:, enterprise_id: other_enterprise.id, + scope: "ReadEnterprise", grantee: "cqcm-dev", + ) + end + + run_test! do + expect(response.body).to include "Fred's Farm" + expect(response.body).to include "Fred's Icecream" + end + end + end + + context "as user owning two enterprises" do + run_test! do + expect(response.body).to include "Fred's Farm" + expect(response.body).to include "Fred's Icecream" + + # Insert static value to keep documentation deterministic: + response.body.gsub!( + %r{active_storage/[0-9A-Za-z/=-]*/logo-white.png}, + "active_storage/url/logo-white.png", + ).gsub!( + %r{active_storage/[0-9A-Za-z/=-]*/logo.png}, + "active_storage/url/logo.png", + ).gsub!( + %r{active_storage/[0-9A-Za-z/=-]*/promo.png}, + "active_storage/url/promo.png", + ) + end + end + end + end + end + path "/api/dfc/enterprises/{id}" do get "Show enterprise" do parameter name: :id, in: :path, type: :string diff --git a/swagger/dfc.yaml b/swagger/dfc.yaml index a6a630b9f1..b0d0c0901b 100644 --- a/swagger/dfc.yaml +++ b/swagger/dfc.yaml @@ -407,6 +407,90 @@ paths: dfc-b:hasCity: Herndon dfc-b:hasCountry: Australia dfc-b:region: Victoria + "/api/dfc/enterprises": + get: + summary: List enterprises + tags: + - Enterprises + responses: + '200': + description: successful + content: + application/json: + examples: + test_example: + value: + "@context": https://www.datafoodconsortium.org + "@graph": + - "@id": http://test.host/api/dfc/enterprises/10001 + "@type": dfc-b:Enterprise + dfc-b:hasAddress: http://test.host/api/dfc/addresses/40001 + dfc-b:name: Fred's Icecream + dfc-b:hasDescription: We use our strawberries to make icecream. + dfc-b:VATnumber: 123 457 + dfc-b:hasMainContact: http://test.host/api/dfc/enterprises/10001#mainContact + ofn:long_description: "

Hello, world!

This is a paragraph.

" + - "@id": http://test.host/api/dfc/enterprises/10000 + "@type": dfc-b:Enterprise + dfc-b:hasAddress: http://test.host/api/dfc/addresses/40000 + dfc-b:hasPhoneNumber: 0404 444 000 200 + dfc-b:email: hello@example.org + dfc-b:websitePage: https://openfoodnetwork.org + dfc-b:hasSocialMedia: http://test.host/api/dfc/enterprises/10000/social_medias/facebook + dfc-b:logo: http://test.host/rails/active_storage/url/logo.png + dfc-b:name: Fred's Farm + dfc-b:hasDescription: This is an awesome enterprise + dfc-b:VATnumber: 123 456 + dfc-b:manages: http://test.host/api/dfc/enterprises/10000/catalog_items/10001 + dfc-b:supplies: http://test.host/api/dfc/enterprises/10000/supplied_products/10001 + dfc-b:hasMainContact: http://test.host/api/dfc/enterprises/10000#mainContact + ofn:long_description: "

Hello, world!

This is a paragraph.

" + ofn:contact_name: Fred Farmer + ofn:logo_url: http://test.host/rails/active_storage/url/logo.png + ofn:promo_image_url: http://test.host/rails/active_storage/url/promo.png + - "@id": http://test.host/api/dfc/enterprises/10001#mainContact + "@type": dfc-b:Person + - "@id": http://test.host/api/dfc/enterprises/10000#mainContact + "@type": dfc-b:Person + dfc-b:firstName: Fred + dfc-b:familyName: Farmer + - "@id": http://test.host/api/dfc/addresses/40001 + "@type": dfc-b:Address + dfc-b:hasStreet: 42 Doveton Street + dfc-b:hasPostalCode: '20170' + dfc-b:hasCity: Herndon + dfc-b:hasCountry: Australia + dfc-b:region: Victoria + - "@id": http://test.host/api/dfc/addresses/40000 + "@type": dfc-b:Address + dfc-b:hasStreet: 42 Doveton Street + dfc-b:hasPostalCode: '20170' + dfc-b:hasCity: Herndon + dfc-b:hasCountry: Australia + dfc-b:region: Victoria + - "@id": http://test.host/api/dfc/enterprises/10000/supplied_products/10001 + "@type": dfc-b:SuppliedProduct + dfc-b:name: Apple - 1g + dfc-b:description: Round + dfc-b:hasQuantity: + "@type": dfc-b:QuantitativeValue + dfc-b:hasUnit: dfc-m:Gram + dfc-b:value: 1.0 + dfc-b:image: http://test.host/rails/active_storage/url/logo-white.png + dfc-b:isVariantOf: http://test.host/api/dfc/product_groups/90000 + ofn:spree_product_id: 90000 + ofn:spree_product_uri: http://test.host/api/dfc/enterprises/10000?spree_product_id=90000 + ofn:image: http://test.host/rails/active_storage/url/logo-white.png + - "@id": http://test.host/api/dfc/enterprises/10000/catalog_items/10001 + "@type": dfc-b:CatalogItem + dfc-b:references: http://test.host/api/dfc/enterprises/10000/supplied_products/10001 + dfc-b:sku: APP + dfc-b:stockLimitation: 5 + dfc-b:offeredThrough: http://test.host/api/dfc/enterprises/10000/offers/10001 + - "@id": http://test.host/api/dfc/enterprises/10000/social_medias/facebook + "@type": dfc-b:SocialMedia + dfc-b:name: facebook + dfc-b:URL: https://facebook.com/user "/api/dfc/enterprises/{id}": get: summary: Show enterprise