Replace apivore with rswag for api tests (#969)

* Replace apivore api tests with rswag
* move to OpenAPI Spec 3.0.1
* a swagger UI is now reachable at http://localhost:3000/api-docs/index.html
*  swagger file is generated by running  `RAILS_ENV=test rails rswag`
    and it was moved from /docs/swagger.v1.yml to /swagger/v1/swagger.yml

---------

Co-authored-by: viehlieb <pf@pragma-shift.net>
This commit is contained in:
Philipp Rothmann 2023-05-12 11:11:48 +02:00 committed by GitHub
parent 8604e27fe9
commit c67e9b5be8
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 1478 additions and 1858 deletions

View file

@ -0,0 +1,53 @@
require 'swagger_helper'
describe 'Article Categories', type: :request do
include ApiHelper
path '/article_categories' do
get 'article categories' do
tags 'Category'
produces 'application/json'
pagination_param
let(:order_article) { create(:order, article_count: 1).order_articles.first }
let(:stock_article) { create(:stock_article) }
let(:stock_order_article) { create(:stock_order, article_ids: [stock_article.id]).order_articles.first }
response '200', 'success' do
schema type: :object, properties: {
article_categories: {
type: :array,
items: {
'$ref': '#/components/schemas/ArticleCategory'
}
}
}
run_test!
end
it_handles_invalid_token
end
end
path '/article_categories/{id}' do
get 'find article category by id' do
tags 'Category'
produces 'application/json'
id_url_param
response '200', 'article category found' do
schema type: :object, properties: {
article_categories: {
type: :array,
items: {
'$ref': '#/components/schemas/ArticleCategory'
}
}
}
let(:id) { create(:article_category, name: 'dairy').id }
run_test!
end
it_handles_invalid_token_with_id
it_cannot_find_object
end
end
end

View file

@ -0,0 +1,20 @@
require 'swagger_helper'
describe 'Config', type: :request do
include ApiHelper
path '/config' do
get 'configuration variables' do
tags 'General'
produces 'application/json'
let(:api_scopes) { ['config:user'] }
response '200', 'success' do
schema type: :object, properties: {}
run_test!
end
it_handles_invalid_token_and_scope
end
end
end

View file

@ -0,0 +1,54 @@
require 'swagger_helper'
describe 'Financial Transaction Classes', type: :request do
include ApiHelper
path '/financial_transaction_classes' do
get 'financial transaction classes' do
tags 'Category'
produces 'application/json'
pagination_param
let(:financial_transaction_class) { create(:financial_transaction_class) }
response '200', 'success' do
schema type: :object, properties: {
meta: { '$ref' => '#/components/schemas/Meta' },
financial_transaction_class: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransactionClass'
}
}
}
run_test!
end
it_handles_invalid_token
end
end
path '/financial_transaction_classes/{id}' do
get 'Retrieves a financial transaction class' do
tags 'Category'
produces 'application/json'
id_url_param
response '200', 'financial transaction class found' do
schema type: :object, properties: {
financial_transaction_classes: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransactionClass'
}
}
}
let(:id) { create(:financial_transaction_class).id }
run_test!
end
it_handles_invalid_token_with_id
it_cannot_find_object 'financial transaction class not found'
end
end
end

View file

@ -0,0 +1,52 @@
require 'swagger_helper'
describe 'Financial Transaction types', type: :request do
include ApiHelper
path '/financial_transaction_types' do
get 'financial transaction types' do
tags 'Category'
produces 'application/json'
pagination_param
let(:financial_transaction_type) { create(:financial_transaction_type) }
response '200', 'success' do
schema type: :object, properties: {
meta: { '$ref' => '#/components/schemas/Meta' },
financial_transaction_type: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransactionType'
}
}
}
run_test!
end
it_handles_invalid_token
end
end
path '/financial_transaction_types/{id}' do
get 'find financial transaction type by id' do
tags 'Category'
produces 'application/json'
id_url_param
response '200', 'financial transaction type found' do
schema type: :object, properties: {
financial_transaction_types: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransactionType'
}
}
}
let(:id) { create(:financial_transaction_type).id }
run_test!
end
it_handles_invalid_token_with_id
it_cannot_find_object 'financial transaction type not found'
end
end
end

View file

@ -0,0 +1,56 @@
require 'swagger_helper'
describe 'Financial Transaction', type: :request do
include ApiHelper
let!(:finance_user) { create(:user, groups: [create(:workgroup, role_finance: true)]) }
let!(:api_scopes) { ['finance:read', 'finance:write'] }
let(:api_access_token) { create(:oauth2_access_token, resource_owner_id: finance_user.id, scopes: api_scopes&.join(' ')).token }
let(:financial_transaction) { create(:financial_transaction, user: user) }
path '/financial_transactions' do
get 'financial transactions' do
tags 'Financial Transaction'
produces 'application/json'
pagination_param
response '200', 'success' do
schema type: :object, properties: {
meta: { '$ref' => '#/components/schemas/Meta' },
financial_transaction: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransaction'
}
}
}
run_test!
end
it_handles_invalid_token_and_scope
end
end
path '/financial_transactions/{id}' do
get 'Retrieves a financial transaction ' do
tags 'Financial Transaction'
produces 'application/json'
id_url_param
response '200', 'financial transaction found' do
schema type: :object, properties: {
financial_transaction: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransaction'
}
}
}
let(:id) { FinancialTransaction.create(user: user).id }
run_test!
end
it_handles_invalid_token_with_id
it_handles_invalid_scope_with_id
it_cannot_find_object 'financial transaction not found'
end
end
end

View file

@ -0,0 +1,24 @@
require 'swagger_helper'
describe 'Navigation', type: :request do
include ApiHelper
path '/navigation' do
get 'navigation' do
tags 'General'
produces 'application/json'
response '200', 'success' do
schema type: :object, properties: {
navigation: {
'$ref' => '#/components/schemas/Navigation'
}
}
run_test!
end
it_handles_invalid_token
end
end
end

View file

@ -0,0 +1,115 @@
require 'swagger_helper'
describe 'Order Articles', type: :request do
include ApiHelper
path '/order_articles' do
get 'order articles' do
tags 'Order'
produces 'application/json'
pagination_param
q_ordered_url_param
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! quantity: 0, tolerance: 0, units_to_order: 0
order_articles[1].update! quantity: 1, tolerance: 0, units_to_order: 0
order_articles[2].update! quantity: 0, tolerance: 1, units_to_order: 0
order_articles[3].update! 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 'when ordered by 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 'when ordered by 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'
id_url_param
let(:api_scopes) { ['orders:read', 'orders:write'] }
response '200', 'success' do
schema type: :object, properties: {
order_article: {
'$ref': '#/components/schemas/OrderArticle'
}
}
let(:order) { create(:order, article_count: 1) }
let(:id) { order.order_articles.first.id }
run_test!
end
it_handles_invalid_token_and_scope
it_cannot_find_object 'order article not found'
end
end
end

View file

@ -0,0 +1,55 @@
require 'swagger_helper'
describe 'Orders', type: :request do
include ApiHelper
let(:api_scopes) { ['orders:read'] }
path '/orders' do
get 'orders' do
tags 'Order'
produces 'application/json'
pagination_param
let(:order) { create(:order) }
response '200', 'success' do
schema type: :object, properties: {
meta: { '$ref' => '#/components/schemas/Meta' },
ordes: {
type: :array,
items: {
'$ref': '#/components/schemas/Order'
}
}
}
run_test!
end
it_handles_invalid_token_and_scope
end
end
path '/orders/{id}' do
get 'Order' do
tags 'Order'
produces 'application/json'
id_url_param
let(:order) { create(:order) }
response '200', 'success' do
schema type: :object, properties: {
order: { '$ref' => '#/components/schemas/Order' }
}
let(:id) { order.id }
run_test! do |response|
expect(JSON.parse(response.body)['order']['id']).to eq order.id
end
end
it_handles_invalid_token_and_scope
it_cannot_find_object 'order not found'
end
end
end

View file

@ -0,0 +1,106 @@
require 'swagger_helper'
describe 'User', type: :request do
include ApiHelper
let(:api_scopes) { ['finance:user'] }
let(:user) { create :user, groups: [create(:ordergroup)] }
let(:other_user2) { create :user }
let(:ft) { create(:financial_transaction, user: user, ordergroup: user.ordergroup) }
before do
ft
end
path '/user/financial_transactions' do
post 'create new financial transaction (requires enabled self service)' do
tags 'Financial Transaction'
consumes 'application/json'
produces 'application/json'
parameter name: :financial_transaction, in: :body, schema: {
type: :object,
properties: {
amount: { type: :integer },
financial_transaction_type: { type: :integer },
note: { type: :string }
}
}
let(:financial_transaction) { { amount: 3, financial_transaction_type_id: create(:financial_transaction_type).id, note: 'lirum larum' } }
response '200', 'success' do
schema type: :object, properties: {
financial_transaction: { '$ref': '#/components/schemas/FinancialTransaction' }
}
run_test!
end
it_handles_invalid_token_with_id
it_handles_invalid_scope_with_id 'user has no ordergroup, is below minimum balance, self service is disabled, or missing scope'
response '404', 'financial transaction type not found' do
schema '$ref' => '#/components/schemas/Error404'
let(:financial_transaction) { { amount: 3, financial_transaction_type_id: 'invalid', note: 'lirum larum' } }
run_test!
end
response '422', 'invalid parameter value' do
xit 'TODO: fix controller to actually send a 422 for invalid params: https://github.com/foodcoops/foodsoft/issues/999'
# schema '$ref' => '#/components/schemas/Error422'
# let(:financial_transaction) { { amount: -3, financial_transaction_type_id: create(:financial_transaction_type).id, note: -2 } }
# run_test!
end
end
get "financial transactions of the member's ordergroup" do
tags 'User', 'Financial Transaction'
produces 'application/json'
pagination_param
response '200', 'success' do
schema type: :object, properties: {
meta: { '$ref': '#/components/schemas/Meta' },
financial_transaction: {
type: :array,
items: {
'$ref': '#/components/schemas/FinancialTransaction'
}
}
}
run_test! do |response|
data = JSON.parse(response.body)
expect(data['financial_transactions'].first['id']).to eq(ft.id)
end
end
it_handles_invalid_token_and_scope
end
end
path '/user/financial_transactions/{id}' do
get 'find financial transaction by id' do
tags 'User', 'Financial Transaction'
produces 'application/json'
id_url_param
response '200', 'success' do
schema type: :object, properties: {
financial_transaction: {
'$ref': '#/components/schemas/FinancialTransaction'
}
}
let(:id) { ft.id }
run_test! do |response|
data = JSON.parse(response.body)
expect(data['financial_transaction']['id']).to eq(ft.id)
end
end
it_handles_invalid_token_with_id
it_handles_invalid_scope_with_id 'user has no ordergroup or missing scope'
it_cannot_find_object 'financial transaction not found'
end
end
end

View file

@ -0,0 +1,192 @@
require 'swagger_helper'
describe 'User', type: :request do
include ApiHelper
let(:api_scopes) { ['group_orders:user'] }
let(:user) { create :user, groups: [create(:ordergroup)] }
let(:other_user2) { create :user }
let(:order) { create(:order, article_count: 4) }
let(:order_articles) { order.order_articles }
let(:group_order) { create :group_order, ordergroup: user.ordergroup, order_id: order.id }
let(:goa) { create :group_order_article, group_order: group_order, order_article: order_articles.first }
before do
goa
end
path '/user/group_order_articles' do
get 'group order articles' do
tags 'User', 'Order'
produces 'application/json'
pagination_param
q_ordered_url_param
response '200', 'success' do
schema type: :object, properties: {
meta: { '$ref': '#/components/schemas/Meta' },
group_order_article: {
type: :array,
items: {
'$ref': '#/components/schemas/GroupOrderArticle'
}
}
}
run_test! do |response|
data = JSON.parse(response.body)
expect(data['group_order_articles'].first['id']).to eq(goa.id)
end
end
it_handles_invalid_token
it_handles_invalid_scope 'user has no ordergroup or missing scope'
end
post 'create new group order article' do
tags 'User', 'Order'
consumes 'application/json'
produces 'application/json'
parameter name: :group_order_article, in: :body,
description: 'group order article to create',
required: true,
schema: { '$ref': '#/components/schemas/GroupOrderArticleForCreate' }
let(:group_order_article) { { order_article_id: order_articles.last.id, quantity: 1, tolerance: 2 } }
response '200', 'success' do
schema type: :object, properties: {
group_order_article: {
'$ref': '#/components/schemas/GroupOrderArticle'
},
order_article: {
'$ref': '#/components/schemas/OrderArticle'
}
}
run_test!
end
it_handles_invalid_token_with_id
it_handles_invalid_scope_with_id 'user has no ordergroup, order not open, is below minimum balance, has not enough apple points, or missing scope'
response '404', 'order article not found in open orders' do
let(:group_order_article) { { order_article_id: 'invalid', quantity: 1, tolerance: 2 } }
schema '$ref' => '#/components/schemas/Error404'
run_test!
end
response '422', 'invalid parameter value or group order article already exists' do
let(:group_order_article) { { order_article_id: goa.order_article_id, quantity: 1, tolerance: 2 } }
schema '$ref' => '#/components/schemas/Error422'
run_test!
end
end
end
path '/user/group_order_articles/{id}' do
get 'find group order article by id' do
tags 'User', 'Order'
produces 'application/json'
id_url_param
response '200', 'success' do
schema type: :object, properties: {
group_order_article: {
'$ref': '#/components/schemas/GroupOrderArticle'
},
order_article: {
'$ref': '#/components/schemas/OrderArticle'
}
}
let(:id) { goa.id }
run_test! do |response|
data = JSON.parse(response.body)
expect(data['group_order_article']['id']).to eq(goa.id)
end
end
it_handles_invalid_scope_with_id
it_handles_invalid_token_with_id
it_cannot_find_object 'group order article not found'
end
patch 'update a group order article (but delete if quantity and tolerance are zero)' do
tags 'User', 'Order'
consumes 'application/json'
produces 'application/json'
id_url_param
parameter name: :group_order_article, in: :body,
description: 'group order article update',
required: true,
schema: { '$ref': '#/components/schemas/GroupOrderArticleForUpdate' }
let(:id) { goa.id }
let(:group_order_article) { { order_article_id: goa.order_article_id, quantity: 2, tolerance: 2 } }
response '200', 'success' do
schema type: :object, properties: {
group_order_article: {
'$ref': '#/components/schemas/GroupOrderArticle'
}
}
run_test!
end
response 401, 'not logged-in' do
schema '$ref' => '#/components/schemas/Error401'
let(:Authorization) { 'abc' }
run_test!
end
response 403, 'user has no ordergroup, order not open, is below minimum balance, has not enough apple points, or missing scope' do
let(:api_scopes) { ['none'] }
schema '$ref' => '#/components/schemas/Error403'
run_test!
end
response '404', 'order article not found in open orders' do
schema type: :object, properties: {
group_order_article: {
'$ref': '#/components/schemas/GroupOrderArticle'
}
}
let(:id) { 'invalid' }
run_test!
end
response '422', 'invalid parameter value' do
let(:group_order_article) { { order_article_id: 'invalid', quantity: -5, tolerance: 'invalid' } }
schema '$ref' => '#/components/schemas/Error422'
run_test!
end
end
delete 'remove group order article' do
tags 'User', 'Order'
consumes 'application/json'
produces 'application/json'
id_url_param
let(:api_scopes) { ['group_orders:user'] }
response '200', 'success' do
schema type: :object, properties: {
group_order_article: {
'$ref': '#/components/schemas/GroupOrderArticle'
}
}
let(:id) { goa.id }
run_test!
end
it_handles_invalid_token_with_id
response 403, 'user has no ordergroup, order not open, is below minimum balance, has not enough apple points, or missing scope' do
let(:api_scopes) { ['none'] }
schema '$ref' => '#/components/schemas/Error403'
run_test!
end
it_cannot_find_object 'order article not found in open orders'
end
end
end

View file

@ -0,0 +1,103 @@
require 'swagger_helper'
describe 'User', type: :request do
include ApiHelper
path '/user' do
get 'info about the currently logged-in user' do
tags 'User'
produces 'application/json'
let(:api_scopes) { ['user:read'] }
let(:other_user1) { create :user }
let(:user) { create :user }
let(:other_user2) { create :user }
response '200', 'success' do
schema type: :object,
properties: {
user: {
type: :object,
properties: {
id: {
type: :integer
},
name: {
type: :string,
description: 'full name'
},
email: {
type: :string,
description: 'email address'
},
locale: {
type: :string,
description: 'language code'
}
},
required: %w[id name email]
}
}
run_test! do |response|
data = JSON.parse(response.body)
expect(data['user']['id']).to eq(user.id)
end
end
it_handles_invalid_token_and_scope
end
end
path '/user/financial_overview' do
get 'financial summary about the currently logged-in user' do
tags 'User', 'Financial Transaction'
produces 'application/json'
let(:user) { create :user, :ordergroup }
let(:api_scopes) { ['finance:user'] }
FinancialTransactionClass.create(name: 'TestTransaction')
response 200, 'success' do
schema type: :object,
properties: {
financial_overview: {
type: :object,
properties: {
account_balance: {
type: :number,
description: 'booked accout balance of ordergroup'
},
available_funds: {
type: :number,
description: 'fund available to order articles'
},
financial_transaction_class_sums: {
type: :array,
properties: {
id: {
type: :integer,
description: 'id of the financial transaction class'
},
name: {
type: :string,
description: 'name of the financial transaction class'
},
amount: {
type: :number,
description: 'sum of the amounts belonging to the financial transaction class'
}
},
required: %w[id name amount]
}
},
required: %w[account_balance available_funds financial_transaction_class_sums]
}
}
run_test!
end
it_handles_invalid_token_and_scope
end
end
end