From d21e6f99bb01e56ec792eb7f7c7979ebcd0265c7 Mon Sep 17 00:00:00 2001 From: Maikel Linke Date: Mon, 26 Jun 2023 17:57:10 +1000 Subject: [PATCH] Swaggerise CatalogItems spec --- .../spec/requests/catalog_items_spec.rb | 177 ++++++++++-------- swagger/dfc-v1.7/swagger.yaml | 162 ++++++++++++++++ 2 files changed, 257 insertions(+), 82 deletions(-) diff --git a/engines/dfc_provider/spec/requests/catalog_items_spec.rb b/engines/dfc_provider/spec/requests/catalog_items_spec.rb index 5119e946e3..959bb2b0e4 100644 --- a/engines/dfc_provider/spec/requests/catalog_items_spec.rb +++ b/engines/dfc_provider/spec/requests/catalog_items_spec.rb @@ -1,115 +1,128 @@ # frozen_string_literal: true +require "swagger_helper" require DfcProvider::Engine.root.join("spec/spec_helper") -describe "CatalogItems", type: :request do - let(:user) { create(:oidc_user) } - let(:enterprise) { create(:distributor_enterprise, owner: user) } - let(:product) { create(:simple_product, supplier: enterprise ) } - let(:variant) { product.variants.first } +describe "CatalogItems", type: :request, swagger_doc: "dfc-v1.7/swagger.yaml", + rswag_autodoc: true do + let(:user) { create(:oidc_user, id: 12_345) } + let(:enterprise) { create(:distributor_enterprise, id: 10_000, owner: user) } + let(:product) { + create( + :base_product, + supplier: enterprise, name: "Apple", description: "Red", + variants: [variant], + ) + } + let(:variant) { build(:base_variant, id: 10_001, unit_value: 1, sku: "AR") } - describe :index do - it "returns not_found without enterprise" do - items_path = enterprise_catalog_items_path(enterprise_id: "default") + before { login_as user } - get items_path, headers: auth_header(user.uid) + path "/api/dfc-v1.7/enterprises/{enterprise_id}/catalog_items" do + parameter name: :enterprise_id, in: :path, type: :string - expect(response).to have_http_status :not_found - end + get "List CatalogItems" do + produces "application/json" - context "with existing variant" do - before { variant } - it "lists catalog items with offers of default enterprise" do - items_path = enterprise_catalog_items_path(enterprise_id: "default") + response "404", "not found" do + context "without enterprises" do + let(:enterprise_id) { "default" } - get items_path, headers: auth_header(user.uid) + run_test! + end - expect(response).to have_http_status :ok - expect(response.body).to include variant.name - expect(response.body).to include variant.sku - expect(response.body).to include "offers/#{variant.id}" + context "with unrelated enterprise" do + let(:enterprise_id) { create(:enterprise).id } + + run_test! + end end - it "lists catalog items with offers of requested enterprise" do - items_path = enterprise_catalog_items_path(enterprise_id: enterprise.id) + response "200", "success" do + before { product } - get items_path, headers: auth_header(user.uid) + context "with default enterprise id" do + let(:enterprise_id) { "default" } - expect(response).to have_http_status :ok - expect(response.body).to include variant.name - expect(response.body).to include variant.sku - expect(response.body).to include "offers/#{variant.id}" + run_test! do + expect(response.body).to include "Apple" + expect(response.body).to include "AR" + expect(response.body).to include "offers/10001" + end + end + + context "with given enterprise id" do + let(:enterprise_id) { 10_000 } + + run_test! do + expect(response.body).to include "Apple" + expect(response.body).to include "AR" + expect(response.body).to include "offers/10001" + end + end end - it "returns not_found for unrelated enterprises" do - other_enterprise = create(:enterprise) - items_path = enterprise_catalog_items_path(enterprise_id: other_enterprise.id) + response "401", "unauthorized" do + let(:enterprise_id) { "default" } - get items_path, headers: auth_header(user.uid) + before { login_as nil } - expect(response).to have_http_status :not_found - end - - it "returns unauthorized for unauthenticated users" do - items_path = enterprise_catalog_items_path(enterprise_id: "default") - - get items_path, headers: {} - - expect(response).to have_http_status :unauthorized - end - - it "recognises app user sessions as logins" do - items_path = enterprise_catalog_items_path(enterprise_id: "default") - login_as user - - get items_path, headers: {} - - expect(response).to have_http_status :ok + run_test! end end end - describe :show do - it "returns a catalog item with offer" do - item_path = enterprise_catalog_item_path( - variant, - enterprise_id: enterprise.id - ) + path "/api/dfc-v1.7/enterprises/{enterprise_id}/catalog_items/{id}" do + parameter name: :enterprise_id, in: :path, type: :string + parameter name: :id, in: :path, type: :string - get item_path, headers: auth_header(user.uid) + get "Show CatalogItem" do + produces "application/json" - expect(response).to have_http_status :ok - expect(response.body).to include "dfc-b:CatalogItem" - expect(response.body).to include "offers/#{variant.id}" + before { product } + + response "200", "success" do + let(:enterprise_id) { 10_000 } + let(:id) { 10_001 } + + run_test! do + expect(response.body).to include "dfc-b:CatalogItem" + expect(response.body).to include "offers/10001" + end + end + + response "404", "not found" do + let(:enterprise_id) { 10_000 } + let(:id) { create(:variant).id } + + run_test! + end end - it "returns not_found for unrelated variant" do - item_path = enterprise_catalog_item_path( - create(:variant), - enterprise_id: enterprise.id - ) + put "Update CatalogItem" do + consumes "application/json" - get item_path, headers: auth_header(user.uid) + parameter name: :catalog_item, in: :body, schema: { + example: JSON.parse(DfcProvider::Engine.root.join("spec/support/patch_catalog_item.json").read) + } - expect(response).to have_http_status :not_found - end - end + before { product } - describe :update do - it "updates a variant's attributes" do - params = { enterprise_id: enterprise.id, id: variant.id } - request_body = DfcProvider::Engine.root.join("spec/support/patch_catalog_item.json").read + response "204", "no content" do + let(:enterprise_id) { 10_000 } + let(:id) { 10_001 } + let(:catalog_item) do |example| + example.metadata[:operation][:parameters].first[:schema][:example] + end - expect { - put( - enterprise_catalog_item_path(params), - params: request_body, - headers: auth_header(user.uid) - ) - expect(response).to have_http_status :success - variant.reload - }.to change { variant.on_hand }.to(3) - .and change { variant.sku }.to("new-sku") + it "updates a variant" do |example| + expect { + submit_request(example.metadata) + variant.reload + }.to change { variant.on_hand }.to(3) + .and change { variant.sku }.to("new-sku") + end + end end end end diff --git a/swagger/dfc-v1.7/swagger.yaml b/swagger/dfc-v1.7/swagger.yaml index 17886e6542..7c8410fae6 100644 --- a/swagger/dfc-v1.7/swagger.yaml +++ b/swagger/dfc-v1.7/swagger.yaml @@ -25,6 +25,168 @@ security: - ofn_api_token: [] - ofn_session: [] paths: + "/api/dfc-v1.7/enterprises/{enterprise_id}/catalog_items": + parameters: + - name: enterprise_id + in: path + required: true + schema: + type: string + get: + summary: List CatalogItems + responses: + '404': + description: not found + '200': + description: success + content: + application/json: + examples: + test_example: + value: + "@context": http://static.datafoodconsortium.org/ontologies/context.json + "@graph": + - "@id": http://test.host/api/dfc-v1.7/persons/12345 + "@type": dfc-b:Person + dfc-b:affiliates: http://test.host/api/dfc-v1.7/enterprises/10000 + - "@id": http://test.host/api/dfc-v1.7/enterprises/10000 + "@type": dfc-b:Enterprise + dfc-b:hasName: '' + dfc-b:hasDescription: '' + dfc-b:VATnumber: '' + dfc-b:supplies: http://test.host/api/dfc-v1.7/enterprises/10000/supplied_products/10001 + dfc-b:manages: http://test.host/api/dfc-v1.7/enterprises/10000/catalog_items/10001 + - "@id": http://test.host/api/dfc-v1.7/enterprises/10000/catalog_items/10001 + "@type": dfc-b:CatalogItem + dfc-b:references: http://test.host/api/dfc-v1.7/enterprises/10000/supplied_products/10001 + dfc-b:sku: AR + dfc-b:stockLimitation: 0 + dfc-b:offeredThrough: http://test.host/api/dfc-v1.7/enterprises/10000/offers/10001 + - "@id": http://test.host/api/dfc-v1.7/enterprises/10000/supplied_products/10001 + "@type": dfc-b:SuppliedProduct + dfc-b:name: Apple + dfc-b:description: Red + dfc-b:hasType: dfc-pt:non-local-vegetable + dfc-b:hasQuantity: + "@type": dfc-b:QuantitativeValue + dfc-b:hasUnit: dfc-m:Gram + dfc-b:value: 1.0 + dfc-b:alcoholPercentage: 0.0 + dfc-b:lifetime: '' + dfc-b:usageOrStorageCondition: '' + dfc-b:totalTheoreticalStock: 0.0 + - "@id": http://test.host/api/dfc-v1.7/enterprises/10000/offers/10001 + "@type": dfc-b:Offer + dfc-b:price: 19.99 + dfc-b:stockLimitation: 0 + '401': + description: unauthorized + "/api/dfc-v1.7/enterprises/{enterprise_id}/catalog_items/{id}": + parameters: + - name: enterprise_id + in: path + required: true + schema: + type: string + - name: id + in: path + required: true + schema: + type: string + get: + summary: Show CatalogItem + responses: + '200': + description: success + content: + application/json: + examples: + test_example: + value: + "@context": http://static.datafoodconsortium.org/ontologies/context.json + "@graph": + - "@id": http://test.host/api/dfc-v1.7/enterprises/10000/catalog_items/10001 + "@type": dfc-b:CatalogItem + dfc-b:references: http://test.host/api/dfc-v1.7/enterprises/10000/supplied_products/10001 + dfc-b:sku: AR + dfc-b:stockLimitation: 0 + dfc-b:offeredThrough: http://test.host/api/dfc-v1.7/enterprises/10000/offers/10001 + - "@id": http://test.host/api/dfc-v1.7/enterprises/10000/offers/10001 + "@type": dfc-b:Offer + dfc-b:price: 19.99 + dfc-b:stockLimitation: 0 + '404': + description: not found + put: + summary: Update CatalogItem + parameters: [] + responses: + '204': + description: no content + requestBody: + content: + application/json: + schema: + example: + "@context": + rdfs: http://www.w3.org/2000/01/rdf-schema# + skos: http://www.w3.org/2004/02/skos/core# + dfc: http://static.datafoodconsortium.org/ontologies/DFC_FullModel.owl# + dc: http://purl.org/dc/elements/1.1/# + dfc-b: http://static.datafoodconsortium.org/ontologies/DFC_BusinessOntology.owl# + dfc-p: http://static.datafoodconsortium.org/ontologies/DFC_ProductOntology.owl# + dfc-t: http://static.datafoodconsortium.org/ontologies/DFC_TechnicalOntology.owl# + dfc-m: http://static.datafoodconsortium.org/data/measures.rdf# + dfc-pt: http://static.datafoodconsortium.org/data/productTypes.rdf# + dfc-f: http://static.datafoodconsortium.org/data/facets.rdf# + dfc-p:hasUnit: + "@type": "@id" + dfc-b:hasUnit: + "@type": "@id" + dfc-b:hasQuantity: + "@type": "@id" + dfc-p:hasType: + "@type": "@id" + dfc-b:hasType: + "@type": "@id" + dfc-b:references: + "@type": "@id" + dfc-b:referencedBy: + "@type": "@id" + dfc-b:offeres: + "@type": "@id" + dfc-b:supplies: + "@type": "@id" + dfc-b:defines: + "@type": "@id" + dfc-b:affiliates: + "@type": "@id" + dfc-b:manages: + "@type": "@id" + dfc-b:offeredThrough: + "@type": "@id" + dfc-b:hasBrand: + "@type": "@id" + dfc-b:hasGeographicalOrigin: + "@type": "@id" + dfc-b:hasClaim: + "@type": "@id" + dfc-b:hasAllergenDimension: + "@type": "@id" + dfc-b:hasNutrimentDimension: + "@type": "@id" + dfc-b:hasPhysicalDimension: + "@type": "@id" + dfc:owner: + "@type": "@id" + dfc-t:hostedBy: + "@type": "@id" + dfc-t:hasPivot: + "@type": "@id" + dfc-t:represent: + "@type": "@id" + dfc-b:stockLimitation: '3' + dfc-b:sku: new-sku "/api/dfc-v1.7/enterprises/{id}": get: summary: Show enterprise