diff --git a/doc/swagger.v1.yml b/doc/swagger.v1.yml index a00ee8a9cd..4ab93e5f0d 100644 --- a/doc/swagger.v1.yml +++ b/doc/swagger.v1.yml @@ -20,7 +20,7 @@ paths: - 1. User responses: 200: - description: user data + description: success schema: type: object properties: @@ -43,7 +43,7 @@ paths: - $ref: '#/parameters/per_page' responses: 200: - description: article categories + description: success schema: type: object properties: @@ -57,14 +57,14 @@ paths: - foodsoft_auth: ['all'] /article_categories/{id}: parameters: - - $ref: '#/parameters/idQ' + - $ref: '#/parameters/idInUrl' get: summary: find article category by id tags: - 2. Category responses: 200: - description: article category + description: success schema: type: object properties: @@ -101,14 +101,14 @@ paths: - foodsoft_auth: ['all'] /orders/{id}: parameters: - - $ref: '#/parameters/idQ' + - $ref: '#/parameters/idInUrl' get: summary: find order by id tags: - 3. Order responses: 200: - description: order + description: success schema: type: object properties: @@ -131,7 +131,7 @@ paths: - $ref: '#/parameters/per_page' responses: 200: - description: order articles + description: success schema: type: object properties: @@ -145,14 +145,14 @@ paths: - foodsoft_auth: ['all'] /order_articles/{id}: parameters: - - $ref: '#/parameters/idQ' + - $ref: '#/parameters/idInUrl' get: summary: find order article by id tags: - 4. OrderArticle responses: 200: - description: order article + description: success schema: type: object properties: @@ -175,7 +175,7 @@ paths: - $ref: '#/parameters/per_page' responses: 200: - description: order articles + description: success schema: type: object properties: @@ -191,16 +191,53 @@ paths: $ref: '#/definitions/Error403' security: - foodsoft_auth: ['all'] + post: + summary: create a new group order article + tags: + - 5. GroupOrderArticle + parameters: + - name: data + in: body + required: true + schema: + type: object + properties: + order_article_id: + $ref: '#/definitions/GroupOrderArticle/properties/order_article_id' + quantity: + $ref: '#/definitions/GroupOrderArticle/properties/quantity' + tolerance: + $ref: '#/definitions/GroupOrderArticle/properties/tolerance' + required: ['order_article_id'] + responses: + 200: + description: success + schema: + type: object + description: newly created group order article + properties: + data: + $ref: '#/definitions/GroupOrderArticle' + 403: + description: user has no ordergroup, or minimum balance is below the limit + schema: + $ref: '#/definitions/Error403' + 422: + description: invalid input (e.g. change not acceptable in boxfill phase) + schema: + $ref: '#/definitions/Error422' + security: + - foodsoft_auth: ['all'] /group_order_articles/{id}: parameters: - - $ref: '#/parameters/idQ' + - $ref: '#/parameters/idInUrl' get: summary: find a member's group order article by id tags: - 5. GroupOrderArticle responses: 200: - description: order article + description: success schema: type: object properties: @@ -216,18 +253,77 @@ paths: $ref: '#/definitions/Error404' security: - foodsoft_auth: ['all'] + patch: + summary: update a group order article + tags: + - 5. GroupOrderArticle + parameters: + - name: data + in: body + required: true + schema: + type: object + properties: + quantity: + $ref: '#/definitions/GroupOrderArticle/properties/quantity' + tolerance: + $ref: '#/definitions/GroupOrderArticle/properties/tolerance' + responses: + 200: + description: success + schema: + type: object + description: updated group order article + properties: + data: + $ref: '#/definitions/GroupOrderArticle' + 403: + description: user has no ordergroup, or minimum balance is below the limit + schema: + $ref: '#/definitions/Error403' + 404: + description: not found + schema: + $ref: '#/definitions/Error404' + 422: + description: invalid input (e.g. change not acceptable in boxfill phase) + schema: + $ref: '#/definitions/Error422' + security: + - foodsoft_auth: ['all'] + delete: + summary: remove an group order article + tags: + - 5. GroupOrderArticle + responses: + 204: + description: success + 403: + description: user has no ordergroup, or minimum balance is below the limit + schema: + $ref: '#/definitions/Error403' + 404: + description: not found + schema: + $ref: '#/definitions/Error404' + 422: + description: invalid input (e.g. change not acceptable in boxfill phase) + schema: + $ref: '#/definitions/Error422' + security: + - foodsoft_auth: ['all'] /financial_transactions: get: summary: financial transactions of the member's ordergroup tags: - - 6. Financial Transaction + - 6. FinancialTransaction parameters: - $ref: '#/parameters/page' - $ref: '#/parameters/per_page' responses: 200: - description: financial transactions + description: success schema: type: object properties: @@ -245,14 +341,14 @@ paths: - foodsoft_auth: ['all'] /financial_transactions/{id}: parameters: - - $ref: '#/parameters/idQ' + - $ref: '#/parameters/idInUrl' get: summary: find financial transaction by id tags: - - 6. Financial Transaction + - 6. FinancialTransaction responses: 200: - description: financial transaction + description: success schema: type: object properties: @@ -271,7 +367,7 @@ paths: parameters: # url parameters - idQ: + idInUrl: name: id type: integer in: path diff --git a/spec/api/v1/swagger_spec.rb b/spec/api/v1/swagger_spec.rb index 593070d3ae..bafc1e5acb 100644 --- a/spec/api/v1/swagger_spec.rb +++ b/spec/api/v1/swagger_spec.rb @@ -78,24 +78,92 @@ def fetch_swagger! let!(:other_goa_1) { create :group_order_article, group_order: other_go, order_article: oa_1 } context 'without ordergroup' do - it { is_expected.to validate(:get, '/group_order_articles', 403, auth) } - it { is_expected.to validate(:get, '/group_order_articles/{id}', 403, auth({'id' => other_goa_1.id})) } + it { is_expected.to validate(:post, '/group_order_articles', 403, auth({'_data' => {'data' => {'order_article_id' => oa_2.id}}})) } + it { is_expected.to validate(:get, '/group_order_articles', 403, auth) } + # this could return either 404 or 403 - but we want to test this path somehow + it { is_expected.to validate(:get, '/group_order_articles/{id}', 403, auth({'id' => other_goa_1.id})) } + it { is_expected.to validate(:delete, '/group_order_articles/{id}', 403, auth({'id' => other_goa_1.id})) } end context 'in ordergroup' do let(:user) { create :user, :ordergroup } - let(:go) { create :group_order, order: order, ordergroup: user.ordergroup } - let!(:goa_1) { create :group_order_article, group_order: go, order_article: oa_1 } - let!(:goa_2) { create :group_order_article, group_order: go, order_article: oa_2 } - - it { is_expected.to validate(:get, '/group_order_articles', 200, auth) } - it { is_expected.to validate(:get, '/group_order_articles/{id}', 200, auth({'id' => goa_2.id})) } - it { is_expected.to validate(:get, '/group_order_articles/{id}', 404, auth({'id' => other_goa_1.id})) } - it { is_expected.to validate(:get, '/group_order_articles/{id}', 404, auth({'id' => GroupOrderArticle.last.id + 1})) } + + shared_examples "create group_order_articles" do + let(:quantity) { 1 + rand(10) } + + # creating a new group_order_article with zero quantity and tolerance currently creates a new record, but in the future this may not be so + it { is_expected.to validate(:post, '/group_order_articles', 200, auth({'_data' => {'data' => {'order_article_id' => oa_2.id}}})) } + it { is_expected.to validate(:post, '/group_order_articles', 200, auth({'_data' => {'data' => {'order_article_id' => oa_2.id, 'quantity' => quantity}}})) } + it { is_expected.to validate(:post, '/group_order_articles', 200, auth({'_data' => {'data' => {'order_article_id' => oa_2.id, 'tolerance' => quantity}}})) } + + context 'with balance below minimum' do + before { FoodsoftConfig[:minimum_balance] = user.ordergroup.account_balance + 5_000 } + it { is_expected.to validate(:post, '/group_order_articles', 403, auth({'_data' => {'data' => {'order_article_id' => oa_2.id, 'quantity' => 1}}})) } + end + end + + shared_examples "modify group_order_articles" do + let(:quantity) { 1 + rand(10) } + it { is_expected.to validate(:patch, '/group_order_articles/{id}', 200, auth({'id' => goa_2.id, '_data' => {'data' => {'quantity' => quantity}}})) } + it { is_expected.to validate(:patch, '/group_order_articles/{id}', 200, auth({'id' => goa_2.id, '_data' => {'data' => {'tolerance' => quantity}}})) } + it { is_expected.to validate(:patch , '/group_order_articles/{id}', 404, auth({'id' => other_goa_1.id, '_data' => {'data' => {'quantity' => quantity}}})) } + it { is_expected.to validate(:patch , '/group_order_articles/{id}', 404, auth({'id' => GroupOrderArticle.last.id + 1, '_data' => {'data' => {'quantity' => quantity}}})) } + it { is_expected.to validate(:delete, '/group_order_articles/{id}', 204, auth({'id' => goa_2.id})) } + it { is_expected.to validate(:delete, '/group_order_articles/{id}', 404, auth({'id' => other_goa_1.id})) } + it { is_expected.to validate(:delete, '/group_order_articles/{id}', 404, auth({'id' => GroupOrderArticle.last.id + 1})) } + + context 'with balance below minimum' do + before { FoodsoftConfig[:minimum_balance] = user.ordergroup.account_balance + 5_000 } + it { is_expected.to validate(:patch, '/group_order_articles/{id}', 403, auth({'id' => goa_2.id, '_data' => {'data' => {'quantity' => 1}}})) } + it { is_expected.to validate(:delete, '/group_order_articles/{id}', 204, auth({'id' => goa_2.id})) } + end + end + + context 'without existing group_order' do + include_examples "create group_order_articles" + + context 'in boxfill phase' do + before { FoodsoftConfig[:use_boxfill] = true } + let!(:order) { create :order, article_count: 3, starts: 2.minutes.ago, boxfill: 1.minute.ago } + it { is_expected.to validate(:post, '/group_order_articles', 422, auth({'_data' => {'data' => {'order_article_id' => oa_1.id, 'quantity' => 1}}})) } + end + end + + context 'without existing group_order_articles' do + let(:go) { create :group_order, order: order, ordergroup: user.ordergroup } + include_examples "create group_order_articles" + end + + context 'with existing group_order_articles' do + let(:go) { create :group_order, order: order, ordergroup: user.ordergroup } + let!(:goa_1) { create :group_order_article, group_order: go, order_article: oa_1 } + let!(:goa_2) { create :group_order_article, group_order: go, order_article: oa_2 } + + include_examples "modify group_order_articles" + it { is_expected.to validate(:get, '/group_order_articles', 200, auth) } + it { is_expected.to validate(:get, '/group_order_articles/{id}', 200, auth({'id' => goa_2.id})) } + it { is_expected.to validate(:get, '/group_order_articles/{id}', 404, auth({'id' => other_goa_1.id})) } + it { is_expected.to validate(:get, '/group_order_articles/{id}', 404, auth({'id' => GroupOrderArticle.last.id + 1})) } + + context 'in boxfill phase' do + before { FoodsoftConfig[:use_boxfill] = true } + let!(:order) { create :order, article_count: 3, starts: 2.minutes.ago } + before do + oa_1.article.update_attributes! unit_quantity: 10 + goa_1.update_quantities 3, 2 + other_goa_1.update_quantities 1, 0 + oa_1.update_results! + order.update_attributes! boxfill: 1.minute.ago + end + + it { is_expected.to validate(:patch, '/group_order_articles/{id}', 200, auth({'id' => goa_1.id, '_data' => {'data' => {'quantity' => 4}}})) } + it { is_expected.to validate(:patch, '/group_order_articles/{id}', 422, auth({'id' => goa_1.id, '_data' => {'data' => {'quantity' => 2}}})) } + it { is_expected.to validate(:patch, '/group_order_articles/{id}', 422, auth({'id' => goa_1.id, '_data' => {'data' => {'quantity' => 10}}})) } + it { is_expected.to validate(:delete, '/group_order_articles/{id}', 422, auth({'id' => goa_1.id})) } + end + end end end - - # @todo finish end # financial_transactions