From 92e8a060da79b883d17a0100412945e695d8ac11 Mon Sep 17 00:00:00 2001 From: Philipp Rothmann Date: Mon, 28 Nov 2022 17:30:20 +0100 Subject: [PATCH] add order_articles_spec --- spec/api/v1/order_articles_spec.rb | 59 +++++++++++ spec/requests/api/order_articles_spec.rb | 125 +++++++++++++++++++++++ spec/swagger_helper.rb | 89 ++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 spec/api/v1/order_articles_spec.rb create mode 100644 spec/requests/api/order_articles_spec.rb diff --git a/spec/api/v1/order_articles_spec.rb b/spec/api/v1/order_articles_spec.rb new file mode 100644 index 00000000..85249401 --- /dev/null +++ b/spec/api/v1/order_articles_spec.rb @@ -0,0 +1,59 @@ +require 'spec_helper' + +# Most routes are tested in the swagger_spec, this tests (non-ransack) parameters. +describe Api::V1::OrderArticlesController, type: :controller do + include ApiOAuth + let(:api_scopes) { ['orders:read'] } + + let(:json_order_articles) { json_response['order_articles'] } + let(:json_order_article_ids) { json_order_articles.map { |joa| joa["id"] } } + + describe "GET :index" do + context "with param q[ordered]" do + let(:order) { create(:order, article_count: 4) } + let(:order_articles) { order.order_articles } + + before do + order_articles[0].update_attributes! quantity: 0, tolerance: 0, units_to_order: 0 + order_articles[1].update_attributes! quantity: 1, tolerance: 0, units_to_order: 0 + order_articles[2].update_attributes! quantity: 0, tolerance: 1, units_to_order: 0 + order_articles[3].update_attributes! quantity: 0, tolerance: 0, units_to_order: 1 + end + + it "(unset)" do + get :index, params: { foodcoop: 'f' } + expect(json_order_articles.count).to eq 4 + end + + it "all" do + get :index, params: { foodcoop: 'f', q: { ordered: 'all' } } + expect(json_order_article_ids).to match_array order_articles[1..2].map(&:id) + end + + it "supplier" do + get :index, params: { foodcoop: 'f', q: { ordered: 'supplier' } } + expect(json_order_article_ids).to match_array [order_articles[3].id] + end + + it "member" do + get :index, params: { foodcoop: 'f', q: { ordered: 'member' } } + expect(json_order_articles.count).to eq 0 + end + + context "when ordered by user" do + let(:user) { create(:user, :ordergroup) } + let(:go) { create(:group_order, order: order, ordergroup: user.ordergroup) } + + before do + create(:group_order_article, group_order: go, order_article: order_articles[1], quantity: 1) + create(:group_order_article, group_order: go, order_article: order_articles[2], tolerance: 0) + end + + it "member" do + get :index, params: { foodcoop: 'f', q: { ordered: 'member' } } + expect(json_order_article_ids).to match_array order_articles[1..2].map(&:id) + end + end + end + end +end diff --git a/spec/requests/api/order_articles_spec.rb b/spec/requests/api/order_articles_spec.rb new file mode 100644 index 00000000..6935fe62 --- /dev/null +++ b/spec/requests/api/order_articles_spec.rb @@ -0,0 +1,125 @@ +require 'swagger_helper' + +describe 'Order Articles', type: :request do + include ApiHelper + + path '/order_articles' do + get 'order articles' do + tags 'Order' + produces 'application/json' + parameter name: 'page[number]', in: :query, type: :integer, required: false + parameter name: 'page[size]', in: :query, type: :integer, required: false + parameter name: 'q', in: :query, required: false, + description: "'member' show articles ordered by the user's ordergroup, 'all' by all members, and 'supplier' ordered at the supplier", + schema: { + type: :object, + ordered: { + type: :string, + enum: %w[member all supplier] + } + } + let(:api_scopes) { ['orders:read', 'orders:write'] } + let(:order) { create(:order, article_count: 4) } + let(:order_articles) { order.order_articles } + + before do + order_articles[0].update_attributes! quantity: 0, tolerance: 0, units_to_order: 0 + order_articles[1].update_attributes! quantity: 1, tolerance: 0, units_to_order: 0 + order_articles[2].update_attributes! quantity: 0, tolerance: 1, units_to_order: 0 + order_articles[3].update_attributes! quantity: 0, tolerance: 0, units_to_order: 1 + end + + response '200', 'success' do + schema type: :object, properties: { + meta: { + '$ref' => '#/components/schemas/Meta' + }, + order_articles: { + type: :array, + items: { + '$ref': '#/components/schemas/OrderArticle' + } + } + } + describe '(unset)' do + run_test! + end + + describe 'all' do + let(:q) { { q: { ordered: 'all' } } } + + run_test! do |response| + json_order_articles = JSON.parse(response.body)['order_articles'] + json_order_article_ids = json_order_articles.map { |d| d['id'].to_i } + expect(json_order_article_ids).to match_array order_articles[1..2].map(&:id) + end + end + + describe 'supplier' do + let(:q) { { q: { ordered: 'supplier' } } } + + run_test! do |response| + json_order_articles = JSON.parse(response.body)['order_articles'] + json_order_article_ids = json_order_articles.map { |d| d['id'].to_i } + expect(json_order_article_ids).to match_array [order_articles[3].id] + end + end + + describe 'member' do + let(:q) { { q: { ordered: 'member' } } } + + run_test! do |response| + json_order_articles = JSON.parse(response.body)['order_articles'] + expect(json_order_articles.count).to eq 0 + end + end + + context 'when ordered by user' do + let(:user) { create(:user, :ordergroup) } + let(:go) { create(:group_order, order: order, ordergroup: user.ordergroup) } + + before do + create(:group_order_article, group_order: go, order_article: order_articles[1], quantity: 1) + create(:group_order_article, group_order: go, order_article: order_articles[2], tolerance: 0) + end + + describe 'member' do + let(:q) { { q: { ordered: 'member' } } } + + run_test! do |response| + json_order_articles = JSON.parse(response.body)['order_articles'] + json_order_article_ids = json_order_articles.map { |d| d['id'].to_i } + expect(json_order_article_ids).to match_array order_articles[1..2].map(&:id) + end + end + end + end + + it_handles_invalid_token_and_scope + end + end + + path '/order_articles/{id}' do + get 'order articles' do + tags 'Order' + produces 'application/json' + parameter name: 'id', in: :path, type: :integer, minimum: 1, required: true + + let(:api_scopes) { ['orders:read', 'orders:write'] } + let(:order) { create(:order, article_count: 1) } + let(:id) { order.order_articles.first.id } + + response '200', 'success' do + schema type: :object, properties: { + order_article: { + '$ref': '#/components/schemas/OrderArticle' + } + } + + run_test! + end + + it_handles_invalid_token_and_scope + end + end +end diff --git a/spec/swagger_helper.rb b/spec/swagger_helper.rb index 8c26d089..080fde20 100644 --- a/spec/swagger_helper.rb +++ b/spec/swagger_helper.rb @@ -24,6 +24,95 @@ RSpec.configure do |config| paths: {}, components: { schemas: { + pagination: { + type: :object, + properties: { + recordCount: { type: :integer }, + pageCount: { type: :integer }, + currentPage: { type: :integer }, + pageSize: { type: :integer } + }, + required: %w(recordCount pageCount currentPage pageSize) + }, + Article: { + type: :object, + properties: { + id: { + type: :integer + }, + name: { + type: :string + }, + supplier_id: { + type: :integer, + description: 'id of supplier, or 0 for stock articles' + }, + supplier_name: { + type: %w[string null], + description: 'name of the supplier, or null for stock articles' + }, + unit: { + type: :string, + description: 'amount of each unit, e.g. "100 g" or "kg"' + }, + unit_quantity: { + type: :integer, + description: 'units can only be ordered from the supplier in multiples of unit_quantity' + }, + note: { + type: %w[string null], + description: 'generic note' + }, + manufacturer: { + type: %w[string null], + description: 'manufacturer' + }, + origin: { + type: %w[string null], + description: 'origin, preferably (starting with a) 2-letter ISO country code' + }, + article_category_id: { + type: :integer, + description: 'id of article category' + }, + quantity_available: { + type: :integer, + description: 'number of units available (only present on stock articles)' + } + }, + required: %w[id name supplier_id supplier_name unit unit_quantity note manufacturer origin article_category_id] + }, + OrderArticle: { + type: :object, + properties: { + id: { + type: :integer + }, + order_id: { + type: :integer, + description: 'id of order this order article belongs to' + }, + price: { + type: :float, + description: 'foodcoop price' + }, + quantity: { + type: :integer, + description: 'number of units ordered by members' + }, + tolerance: { + type: :integer, + description: 'number of extra units that members are willing to buy to fill a box' + }, + units_to_order: { + type: :integer, + description: 'number of units to order from the supplier' + }, + article: { + '$ref': '#/components/schemas/Article' + } + } + }, ArticleCategory: { type: :object, properties: {