add Mayhem for API as a github workflow

This commit is contained in:
J. David Lowe
2022-04-26 11:47:08 -07:00
parent c001463f8a
commit da2e7b404f
5 changed files with 221 additions and 171 deletions

45
.github/workflows/mapi.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
name: 'Mayhem for API'
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: true
steps:
- uses: actions/checkout@v2
- run: docker/build
- run: docker-compose up --detach
- run: until curl -f -s http://localhost:3000; do echo "waiting for api server"; sleep 1; done
- run: docker-compose exec -T db psql postgresql://ofn:f00d@localhost:5432/open_food_network_dev --command="update spree_users set spree_api_key='testing' where login='ofn@example.com'"
# equivalent to Flipper.enable(:api_v1)
- run: docker-compose exec -T db psql postgresql://ofn:f00d@localhost:5432/open_food_network_dev --command="insert into flipper_features (key, created_at, updated_at) values ('api_v1', localtimestamp, localtimestamp)"
- run: docker-compose exec -T db psql postgresql://ofn:f00d@localhost:5432/open_food_network_dev --command="insert into flipper_gates (feature_key, key, value, created_at, updated_at) values ('api_v1', 'boolean', 'true', localtimestamp, localtimestamp)"
# Run Mayhem for API
- name: Run Mayhem for API
uses: ForAllSecure/mapi-action@v1
continue-on-error: true
with:
mapi-token: ${{ secrets.MAPI_TOKEN }}
api-url: http://localhost:3000
api-spec: swagger/v1/swagger.yaml
target: mayhemheroes/openfoodnetwork
duration: 1min
sarif-report: mapi.sarif
html-report: mapi.html
run-args: |
--header-auth
X-Api-Token: testing
# Archive HTML report
- name: Archive Mayhem for API report
uses: actions/upload-artifact@v2
with:
name: mapi-report
path: mapi.html
# Upload SARIF file (only available on public repos or github enterprise)
- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: mapi.sarif

View File

@@ -14,7 +14,7 @@ class CustomerSchema < JsonApiSchema
code: { type: :string, nullable: true, example: "BUYER1" },
email: { type: :string, example: "alice@example.com" },
allow_charges: { type: :boolean, example: false },
tags: { type: :array, example: ["staff", "discount"] },
tags: { type: :array, items: { type: :string }, example: ["staff", "discount"] },
terms_and_conditions_accepted_at: {
type: :string, format: "date-time", nullable: true,
example: "2022-03-12T15:55:00.000+11:00",

View File

@@ -30,7 +30,7 @@ describe "Customers", type: :request do
response "200", "Customers list" do
param(:enterprise_id) { enterprise1.id }
schema "$ref": "#/components/schemas/resources/customers_collection"
schema "$ref": "#/components/schemas/customers_collection"
run_test!
end
@@ -123,7 +123,7 @@ describe "Customers", type: :request do
enterprise_id: enterprise1.id.to_s
}
end
schema "$ref": "#/components/schemas/resources/customer"
schema "$ref": "#/components/schemas/customer"
run_test! do
expect(json_response[:data][:attributes]).to include(
@@ -141,7 +141,7 @@ describe "Customers", type: :request do
enterprise_id: enterprise1.id,
)
end
schema "$ref": "#/components/schemas/resources/customer"
schema "$ref": "#/components/schemas/customer"
run_test! do
expect(json_response[:data][:attributes]).to include(
@@ -191,7 +191,7 @@ describe "Customers", type: :request do
response "200", "Customer" do
param(:id) { customer1.id }
schema "$ref": "#/components/schemas/resources/customer"
schema "$ref": "#/components/schemas/customer"
run_test! do
date_time_string =
@@ -292,7 +292,7 @@ describe "Customers", type: :request do
enterprise_id: enterprise1.id.to_s
}
end
schema "$ref": "#/components/schemas/resources/customer"
schema "$ref": "#/components/schemas/customer"
run_test! do
# Tags should not be overridden when the param is missing:
@@ -318,7 +318,7 @@ describe "Customers", type: :request do
response "200", "Customer deleted" do
param(:id) { customer1.id }
schema "$ref": "#/components/schemas/resources/customer"
schema "$ref": "#/components/schemas/customer"
run_test!
end
@@ -333,7 +333,7 @@ describe "Customers", type: :request do
response "200", "Customers list" do
param(:enterprise_id) { enterprise1.id }
schema "$ref": "#/components/schemas/resources/customers_collection"
schema "$ref": "#/components/schemas/customers_collection"
run_test!
end

View File

@@ -27,12 +27,10 @@ RSpec.configure do |config|
components: {
schemas: {
error_response: ErrorsSchema.schema,
resources: {
customer: CustomerSchema.schema(require_all: true),
customers_collection: CustomerSchema.collection(require_all: true)
}
customer: CustomerSchema.schema(require_all: true),
customers_collection: CustomerSchema.collection(require_all: true)
},
securitySchemas: {
securitySchemes: {
api_key_header: {
type: :apiKey,
name: 'X-Api-Token',
@@ -46,7 +44,7 @@ RSpec.configure do |config|
description: "Authenticates via API key passed in specified query param"
},
session: {
type: :http,
type: :apiKey,
name: '_ofn_session',
in: :cookie,
description: "Authenticates using the current user's session if logged in"

View File

@@ -23,11 +23,119 @@ components:
- detail
required:
- errors
resources:
customer:
type: object
properties:
data:
customer:
type: object
properties:
data:
type: object
properties:
id:
type: string
example: '1'
type:
type: string
example: customer
attributes:
type: object
properties:
id:
type: integer
example: 1
enterprise_id:
type: integer
example: 2
first_name:
type: string
nullable: true
example: Alice
last_name:
type: string
nullable: true
example: Springs
code:
type: string
nullable: true
example: BUYER1
email:
type: string
example: alice@example.com
allow_charges:
type: boolean
example: false
tags:
type: array
items:
type: string
example:
- staff
- discount
terms_and_conditions_accepted_at:
type: string
format: date-time
nullable: true
example: '2022-03-12T15:55:00.000+11:00'
billing_address:
type: object
nullable: true
example:
shipping_address:
type: object
nullable: true
example:
phone: 0404 333 222 111
latitude: -37.8173751
longitude: 144.964803195704
first_name: Alice
last_name: Springs
street_address_1: 1 Flinders Street
street_address_2: ''
postal_code: '1234'
locality: Melbourne
region: Victoria
country: Australia
required:
- id
- enterprise_id
- first_name
- last_name
- code
- email
- allow_charges
- tags
- terms_and_conditions_accepted_at
- billing_address
- shipping_address
relationships:
type: object
properties:
enterprise:
type: object
properties:
data:
type: object
properties:
id:
type: string
type:
type: string
example: enterprise
links:
type: object
properties:
related:
type: string
meta:
type: object
links:
type: object
required:
- data
customers_collection:
type: object
properties:
data:
type: array
items:
type: object
properties:
id:
@@ -65,6 +173,8 @@ components:
example: false
tags:
type: array
items:
type: string
example:
- staff
- discount
@@ -123,153 +233,46 @@ components:
properties:
related:
type: string
meta:
type: object
links:
type: object
required:
- data
customers_collection:
type: object
properties:
data:
type: array
items:
meta:
type: object
properties:
pagination:
type: object
properties:
id:
type: string
example: '1'
type:
type: string
example: customer
attributes:
type: object
properties:
id:
type: integer
example: 1
enterprise_id:
type: integer
example: 2
first_name:
type: string
nullable: true
example: Alice
last_name:
type: string
nullable: true
example: Springs
code:
type: string
nullable: true
example: BUYER1
email:
type: string
example: alice@example.com
allow_charges:
type: boolean
example: false
tags:
type: array
example:
- staff
- discount
terms_and_conditions_accepted_at:
type: string
format: date-time
nullable: true
example: '2022-03-12T15:55:00.000+11:00'
billing_address:
type: object
nullable: true
example:
shipping_address:
type: object
nullable: true
example:
phone: 0404 333 222 111
latitude: -37.8173751
longitude: 144.964803195704
first_name: Alice
last_name: Springs
street_address_1: 1 Flinders Street
street_address_2: ''
postal_code: '1234'
locality: Melbourne
region: Victoria
country: Australia
required:
- id
- enterprise_id
- first_name
- last_name
- code
- email
- allow_charges
- tags
- terms_and_conditions_accepted_at
- billing_address
- shipping_address
relationships:
type: object
properties:
enterprise:
type: object
properties:
data:
type: object
properties:
id:
type: string
type:
type: string
example: enterprise
links:
type: object
properties:
related:
type: string
meta:
type: object
properties:
pagination:
type: object
properties:
results:
type: integer
example: 250
pages:
type: integer
example: 5
page:
type: integer
example: 2
per_page:
type: integer
example: 50
required:
- pagination
links:
type: object
properties:
self:
type: string
first:
type: string
prev:
type: string
nullable: true
next:
type: string
nullable: true
last:
type: string
required:
- data
- meta
- links
securitySchemas:
results:
type: integer
example: 250
pages:
type: integer
example: 5
page:
type: integer
example: 2
per_page:
type: integer
example: 50
required:
- pagination
links:
type: object
properties:
self:
type: string
first:
type: string
prev:
type: string
nullable: true
next:
type: string
nullable: true
last:
type: string
required:
- data
- meta
- links
securitySchemes:
api_key_header:
type: apiKey
name: X-Api-Token
@@ -281,7 +284,7 @@ components:
in: query
description: Authenticates via API key passed in specified query param
session:
type: http
type: apiKey
name: _ofn_session
in: cookie
description: Authenticates using the current user's session if logged in
@@ -302,7 +305,7 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/resources/customers_collection"
"$ref": "#/components/schemas/customers_collection"
post:
summary: Create customer
tags:
@@ -314,7 +317,7 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/resources/customer"
"$ref": "#/components/schemas/customer"
'422':
description: Unprocessable entity
content:
@@ -347,6 +350,8 @@ paths:
example: alice@example.com
tags:
type: array
items:
type: string
example:
- staff
- discount
@@ -389,7 +394,7 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/resources/customer"
"$ref": "#/components/schemas/customer"
'404':
description: Not found
content:
@@ -418,7 +423,7 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/resources/customer"
"$ref": "#/components/schemas/customer"
'422':
description: Unprocessable entity
content:
@@ -451,6 +456,8 @@ paths:
example: alice@example.com
tags:
type: array
items:
type: string
example:
- staff
- discount
@@ -492,7 +499,7 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/resources/customer"
"$ref": "#/components/schemas/customer"
"/api/v1/enterprises/{enterprise_id}/customers":
get:
summary: List customers of an enterprise
@@ -511,6 +518,6 @@ paths:
content:
application/json:
schema:
"$ref": "#/components/schemas/resources/customers_collection"
"$ref": "#/components/schemas/customers_collection"
servers:
- url: "/"