Merge pull request #5578 from mbudm/issue/3770-manual-update

Update orders swagger spec and fix api_key access to orders endpoint
This commit is contained in:
Luis Ramos
2020-07-06 20:32:25 +01:00
committed by GitHub
8 changed files with 409 additions and 2 deletions

View File

@@ -144,6 +144,7 @@ group :test, :development do
gem 'letter_opener', '>= 1.4.1'
gem 'rspec-rails', ">= 3.5.2"
gem 'rspec-retry'
gem 'rswag'
gem 'selenium-webdriver'
gem 'shoulda-matchers'
gem 'timecop'

View File

@@ -433,6 +433,8 @@ GEM
jquery-ui-rails (4.2.1)
railties (>= 3.2.16)
json (1.8.6)
json-schema (2.8.1)
addressable (>= 2.4)
json_spec (1.1.5)
multi_json (~> 1.0)
rspec (>= 2.0, < 4.0)
@@ -586,6 +588,19 @@ GEM
rspec-retry (0.6.2)
rspec-core (> 3.3)
rspec-support (3.9.2)
rswag (2.2.0)
rswag-api (= 2.2.0)
rswag-specs (= 2.2.0)
rswag-ui (= 2.2.0)
rswag-api (2.2.0)
railties (>= 3.1, < 6.1)
rswag-specs (2.2.0)
activesupport (>= 3.1, < 6.1)
json-schema (~> 2.2)
railties (>= 3.1, < 6.1)
rswag-ui (2.2.0)
actionpack (>= 3.1, < 6.1)
railties (>= 3.1, < 6.1)
rubocop (0.81.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
@@ -775,6 +790,7 @@ DEPENDENCIES
roo (~> 2.8.3)
rspec-rails (>= 3.5.2)
rspec-retry
rswag
rubocop
rubocop-rails
sass

View File

@@ -8,7 +8,7 @@ module Api
def index
authorize! :admin, Spree::Order
search_results = SearchOrders.new(params, spree_current_user)
search_results = SearchOrders.new(params, current_api_user)
render json: {
orders: serialized_orders(search_results.orders),

View File

@@ -1,4 +1,5 @@
Openfoodnetwork::Application.routes.draw do
root :to => 'home#index'
# Redirects from old URLs avoid server errors and helps search engines

View File

@@ -0,0 +1,137 @@
# frozen_string_literal: true
require 'swagger_helper'
describe 'api/orders', type: :request do
path '/api/orders' do
get('list orders') do
tags 'Orders'
# type should be replaced with swagger 3.01 valid schema: {type: string} when rswag #317 is resolved:
# https://github.com/rswag/rswag/pull/319
parameter name: 'X-Spree-Token', in: :header, type: :string
parameter name: 'q[distributor_id_eq]', in: :query, type: :string, required: false, description: "Query orders for a specific distributor id."
parameter name: 'q[completed_at_gt]', in: :query, type: :string, required: false, description: "Query orders completed after a date."
parameter name: 'q[completed_at_lt]', in: :query, type: :string, required: false, description: "Query orders completed before a date."
parameter name: 'q[state_eq]', in: :query, type: :string, required: false, description: "Query orders by order state, eg 'cart', 'complete'."
parameter name: 'q[payment_state_eq]', in: :query, type: :string, required: false, description: "Query orders by order payment_state, eg 'balance_due', 'paid', 'failed'."
parameter name: 'q[email_cont]', in: :query, type: :string, required: false, description: "Query orders where the order email contains a string."
parameter name: 'q[order_cycle_id_eq]', in: :query, type: :string, required: false, description: "Query orders for a specific order_cycle id."
response(200, 'get orders') do
# Adds model metadata for Swagger UI. Ideally we'd be able to just add:
# schema '$ref' => '#/components/schemas/Order_Concise'
# Which would also validate the response in the test, this is an open
# issue with rswag: https://github.com/rswag/rswag/issues/268
metadata[:response][:content] = {
"application/json": {
schema: {'$ref' => '#/components/schemas/Order_Concise'}
}
}
context "when there are four orders with different properties set" do
let!(:order_dist_1) { create(:order_with_distributor, email: "specific_name@example.com") }
let!(:order_dist_2) { create(:order_with_totals_and_distribution) }
let!(:order_dist_1_complete) { create(:order, distributor: order_dist_1.distributor, state: 'complete', completed_at: Time.zone.today - 7.days) }
let!(:order_dist_1_credit_owed) { create(:order, distributor: order_dist_1.distributor, payment_state: 'credit_owed', completed_at: Time.zone.today) }
let(:user) { order_dist_1.distributor.owner }
let(:'X-Spree-Token') do
user.generate_spree_api_key!
user.spree_api_key
end
context "and there are no query parameters" do
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 4
end
end
context "and queried by distributor id" do
let(:'q[distributor_id_eq]') { order_dist_2.distributor.id }
before { order_dist_2.distributor.update_attributes owner: user }
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 1
expect(orders.first["id"]).to eq order_dist_2.id
end
end
context "and queried within a date range" do
let(:'q[completed_at_gt]') { Time.zone.today - 7.days - 1.second }
let(:'q[completed_at_lt]') { Time.zone.today - 6.days }
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 1
expect(orders.first["id"]).to eq order_dist_1_complete.id
end
end
context "and queried by complete state" do
let(:'q[state_eq]') { "complete" }
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 1
expect(orders.first["id"]).to eq order_dist_1_complete.id
end
end
context "and queried by credit_owed payment_state" do
let(:'q[payment_state_eq]') { "credit_owed" }
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 1
expect(orders.first["id"]).to eq order_dist_1_credit_owed.id
end
end
context "and queried by buyer email contains a specific string" do
let(:'q[email_cont]') { order_dist_1.email.split("@").first }
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 1
expect(orders.first["id"]).to eq order_dist_1.id
end
end
context "and queried by a specific order_cycle" do
let(:'q[order_cycle_id_eq]') {
order_dist_2.order_cycle.id
}
before { order_dist_2.distributor.update_attributes owner: user }
run_test! do |response|
expect(response).to have_http_status(200)
data = JSON.parse(response.body)
orders = data["orders"]
expect(orders.size).to eq 1
expect(orders.first["id"]).to eq order_dist_2.id
end
end
end
end
end
end
end

74
spec/swagger_helper.rb Normal file
View File

@@ -0,0 +1,74 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.configure do |config|
config.swagger_root = Rails.root.join('swagger').to_s
config.swagger_docs = {
'v1/swagger.yaml' => {
openapi: '3.0.1',
info: {
title: 'The Open Food Network',
description: 'This spec is auto generated using the rswag gem. It is incomplete and not yet valid for openapi 3.0.1. Do not publish this. \
Some endpoints are public and require no authorization; others require authorization. Talk to us to get your credentials set up. \
Check out our repo! https://github.com/openfoodfoundation/openfoodnetwork',
version: '0.1',
},
components: {
securitySchemes: {
api_key: {
type: :apiKey,
name: 'X-Spree-Token',
in: :header
}
},
schemas: {
Order_Concise: {
type: 'object',
properties: {
id: { type: 'integer' },
number: { type: 'string' },
full_name: { type: 'string' },
email: { type: 'string' },
phone: { type: 'string' },
completed_at: { type: 'string' },
display_total: { type: 'string' },
show_path: { type: 'string' },
edit_path: { type: 'string' },
state: { type: 'string' },
payment_state: { type: 'string' },
shipment_state: { type: 'string' },
payments_path: { type: 'string' },
shipments_path: { type: 'string' },
ship_path: { type: 'string' },
ready_to_ship: { type: 'string' },
created_at: { type: 'string' },
distributor_name: { type: 'string' },
special_instructions: { type: 'string' },
payment_capture_path: { type: 'string' },
distributor: {
type: 'object',
properties: {
id: { type: 'integer' }
}
},
order_cycle: {
type: 'object',
properties: {
id: { type: 'integer' }
}
}
}
}
}
},
paths: {},
servers: [
{
url: 'https://staging.katuma.org/api'
}
]
}
}
config.swagger_format = :yaml
end

View File

@@ -342,9 +342,63 @@ paths:
/orders:
get:
description: Gets all Orders.
description: >
Gets all Orders. Use combinations of parameters to filter your query.
For example /api/orders?q[completed_at_gt]=2020_02_02&q[completed_at_lt]=2020_02_10 returns orders between 2nd and 10th February 2020.
Query parameters are generated for the '#/components/schemas/Order_Concise' model with [Ransack](https://github.com/activerecord-hackery/ransack#search-matchers) search matchers
tags:
- orders
parameters:
- in: query
name: q[distributor_id_eq]
schema:
type: string
style: deepObject
description: Query orders for a specific distributor id.
required: false
- in: query
name: q[completed_at_gt]
schema:
type: string
style: deepObject
description: Query orders completed after a date.
required: false
- in: query
name: q[completed_at_lt]
schema:
type: string
style: deepObject
description: Query orders completed before a date.
required: false
- in: query
name: q[state_eq]
schema:
type: string
style: deepObject
description: Query orders by order state, eg 'cart', 'complete'.
required: false
- in: query
name: q[payment_state_eq]
schema:
type: string
style: deepObject
description: Query orders by order payment_state, eg 'balance_due', 'paid', 'failed'.
required: false
- in: query
name: q[email_cont]
schema:
type: string
style: deepObject
description: Query orders where the order email contains a string.
required: false
- in: query
name: q[order_cycle_id_eq]
schema:
type: string
style: deepObject
description: Query orders for a specific order_cycle id.
required: false
responses:
'200':
description: successful operation

124
swagger/v1/swagger.yaml Normal file
View File

@@ -0,0 +1,124 @@
---
openapi: 3.0.1
info:
title: The Open Food Network
description: |-
This spec is auto generated using the rswag gem. It is incomplete and not yet valid for openapi 3.0.1. Do not publish this. \
Some endpoints are public and require no authorization; others require authorization. Talk to us to get your credentials set up. \
Check out our repo! https://github.com/openfoodfoundation/openfoodnetwork
version: '0.1'
components:
securitySchemes:
api_key:
type: apiKey
name: X-Spree-Token
in: header
schemas:
Order_Concise:
type: object
properties:
id:
type: integer
number:
type: string
full_name:
type: string
email:
type: string
phone:
type: string
completed_at:
type: string
display_total:
type: string
show_path:
type: string
edit_path:
type: string
state:
type: string
payment_state:
type: string
shipment_state:
type: string
payments_path:
type: string
shipments_path:
type: string
ship_path:
type: string
ready_to_ship:
type: string
created_at:
type: string
distributor_name:
type: string
special_instructions:
type: string
payment_capture_path:
type: string
distributor:
type: object
properties:
id:
type: integer
order_cycle:
type: object
properties:
id:
type: integer
paths:
"/api/orders":
get:
summary: list orders
tags:
- Orders
parameters:
- name: X-Spree-Token
in: header
type: string
- name: q[distributor_id_eq]
in: query
type: string
required: false
description: Query orders for a specific distributor id.
- name: q[completed_at_gt]
in: query
type: string
required: false
description: Query orders completed after a date.
- name: q[completed_at_lt]
in: query
type: string
required: false
description: Query orders completed before a date.
- name: q[state_eq]
in: query
type: string
required: false
description: Query orders by order state, eg 'cart', 'complete'.
- name: q[payment_state_eq]
in: query
type: string
required: false
description: Query orders by order payment_state, eg 'balance_due', 'paid',
'failed'.
- name: q[email_cont]
in: query
type: string
required: false
description: Query orders where the order email contains a string.
- name: q[order_cycle_id_eq]
in: query
type: string
required: false
description: Query orders for a specific order_cycle id.
responses:
'200':
description: get orders
content:
application/json:
schema:
"$ref": "#/components/schemas/Order_Concise"
servers:
- url: https://staging.katuma.org/api