reqcord 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/Gemfile +5 -0
- data/README.md +13 -0
- data/gemfiles/rails_7.1.gemfile +13 -0
- data/gemfiles/rails_7.2.gemfile +13 -0
- data/gemfiles/rails_8.0.gemfile +13 -0
- data/gemfiles/rails_8.1.gemfile +13 -0
- data/lib/reqcord/version.rb +1 -1
- data/reqcord.gemspec +18 -4
- metadata +65 -217
- data/.gitignore +0 -8
- data/Gemfile.lock +0 -171
- data/examples/complex-spec-app/.rspec +0 -1
- data/examples/complex-spec-app/README.md +0 -21
- data/examples/complex-spec-app/app.rb +0 -363
- data/examples/complex-spec-app/docs/api/README.md +0 -104
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/create.md +0 -117
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/destroy.md +0 -51
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/index.md +0 -11
- data/examples/complex-spec-app/docs/api/api/v1/admin/products/list.md +0 -106
- data/examples/complex-spec-app/docs/api/api/v1/auth/index.md +0 -9
- data/examples/complex-spec-app/docs/api/api/v1/auth/login.md +0 -76
- data/examples/complex-spec-app/docs/api/api/v1/cart-items/create.md +0 -91
- data/examples/complex-spec-app/docs/api/api/v1/cart-items/destroy.md +0 -51
- data/examples/complex-spec-app/docs/api/api/v1/cart-items/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/carts/checkout.md +0 -102
- data/examples/complex-spec-app/docs/api/api/v1/carts/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/carts/show.md +0 -73
- data/examples/complex-spec-app/docs/api/api/v1/home/index.md +0 -9
- data/examples/complex-spec-app/docs/api/api/v1/home/list.md +0 -47
- data/examples/complex-spec-app/docs/api/api/v1/notes/create.md +0 -94
- data/examples/complex-spec-app/docs/api/api/v1/notes/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/notes/list.md +0 -61
- data/examples/complex-spec-app/docs/api/api/v1/orders/cancel.md +0 -69
- data/examples/complex-spec-app/docs/api/api/v1/orders/create.md +0 -150
- data/examples/complex-spec-app/docs/api/api/v1/orders/destroy.md +0 -37
- data/examples/complex-spec-app/docs/api/api/v1/orders/index.md +0 -13
- data/examples/complex-spec-app/docs/api/api/v1/orders/list.md +0 -78
- data/examples/complex-spec-app/docs/api/api/v1/orders/show.md +0 -83
- data/examples/complex-spec-app/docs/api/api/v1/products/index.md +0 -11
- data/examples/complex-spec-app/docs/api/api/v1/products/list.md +0 -83
- data/examples/complex-spec-app/docs/api/api/v1/products/search.md +0 -88
- data/examples/complex-spec-app/docs/api/api/v1/products/show.md +0 -71
- data/examples/complex-spec-app/docs/api/api/v1/profiles/index.md +0 -10
- data/examples/complex-spec-app/docs/api/api/v1/profiles/show.md +0 -61
- data/examples/complex-spec-app/docs/api/api/v1/profiles/update.md +0 -91
- data/examples/complex-spec-app/docs/api/api/v2/products/index.md +0 -9
- data/examples/complex-spec-app/docs/api/api/v2/products/list.md +0 -77
- data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/create.sh +0 -18
- data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/destroy.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/admin/products/list.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/auth/login.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/cart-items/create.sh +0 -16
- data/examples/complex-spec-app/docs/api/curl/api/v1/cart-items/destroy.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/carts/checkout.sh +0 -13
- data/examples/complex-spec-app/docs/api/curl/api/v1/carts/show.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/home/list.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/notes/create.sh +0 -15
- data/examples/complex-spec-app/docs/api/curl/api/v1/notes/list.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/cancel.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/create.sh +0 -29
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/destroy.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/list.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/orders/show.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/products/list.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/products/search.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/products/show.sh +0 -8
- data/examples/complex-spec-app/docs/api/curl/api/v1/profiles/show.sh +0 -9
- data/examples/complex-spec-app/docs/api/curl/api/v1/profiles/update.sh +0 -16
- data/examples/complex-spec-app/docs/api/curl/api/v2/products/list.sh +0 -8
- data/examples/complex-spec-app/docs/api/dataset.json +0 -5116
- data/examples/complex-spec-app/docs/api/postman/collection.json +0 -2519
- data/examples/complex-spec-app/generate.rb +0 -14
- data/examples/complex-spec-app/reqcord.yml +0 -28
- data/examples/complex-spec-app/spec/requests/admin_spec.rb +0 -67
- data/examples/complex-spec-app/spec/requests/cart_spec.rb +0 -61
- data/examples/complex-spec-app/spec/requests/home_and_auth_spec.rb +0 -49
- data/examples/complex-spec-app/spec/requests/orders_spec.rb +0 -124
- data/examples/complex-spec-app/spec/requests/products_spec.rb +0 -65
- data/examples/complex-spec-app/spec/spec_helper.rb +0 -17
- data/examples/complex-test-app/README.md +0 -40
- data/examples/complex-test-app/app.rb +0 -384
- data/examples/complex-test-app/docs/api/README.md +0 -104
- data/examples/complex-test-app/docs/api/api/v1/admin/products/create.md +0 -117
- data/examples/complex-test-app/docs/api/api/v1/admin/products/destroy.md +0 -51
- data/examples/complex-test-app/docs/api/api/v1/admin/products/index.md +0 -11
- data/examples/complex-test-app/docs/api/api/v1/admin/products/list.md +0 -106
- data/examples/complex-test-app/docs/api/api/v1/auth/index.md +0 -9
- data/examples/complex-test-app/docs/api/api/v1/auth/login.md +0 -76
- data/examples/complex-test-app/docs/api/api/v1/cart-items/create.md +0 -91
- data/examples/complex-test-app/docs/api/api/v1/cart-items/destroy.md +0 -51
- data/examples/complex-test-app/docs/api/api/v1/cart-items/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/carts/checkout.md +0 -102
- data/examples/complex-test-app/docs/api/api/v1/carts/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/carts/show.md +0 -73
- data/examples/complex-test-app/docs/api/api/v1/home/index.md +0 -9
- data/examples/complex-test-app/docs/api/api/v1/home/list.md +0 -47
- data/examples/complex-test-app/docs/api/api/v1/notes/create.md +0 -94
- data/examples/complex-test-app/docs/api/api/v1/notes/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/notes/list.md +0 -61
- data/examples/complex-test-app/docs/api/api/v1/orders/cancel.md +0 -69
- data/examples/complex-test-app/docs/api/api/v1/orders/create.md +0 -150
- data/examples/complex-test-app/docs/api/api/v1/orders/destroy.md +0 -37
- data/examples/complex-test-app/docs/api/api/v1/orders/index.md +0 -13
- data/examples/complex-test-app/docs/api/api/v1/orders/list.md +0 -71
- data/examples/complex-test-app/docs/api/api/v1/orders/show.md +0 -83
- data/examples/complex-test-app/docs/api/api/v1/products/index.md +0 -11
- data/examples/complex-test-app/docs/api/api/v1/products/list.md +0 -83
- data/examples/complex-test-app/docs/api/api/v1/products/search.md +0 -88
- data/examples/complex-test-app/docs/api/api/v1/products/show.md +0 -71
- data/examples/complex-test-app/docs/api/api/v1/profiles/index.md +0 -10
- data/examples/complex-test-app/docs/api/api/v1/profiles/show.md +0 -61
- data/examples/complex-test-app/docs/api/api/v1/profiles/update.md +0 -91
- data/examples/complex-test-app/docs/api/api/v2/products/index.md +0 -9
- data/examples/complex-test-app/docs/api/api/v2/products/list.md +0 -77
- data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/create.sh +0 -18
- data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/destroy.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/admin/products/list.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/auth/login.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/cart-items/create.sh +0 -16
- data/examples/complex-test-app/docs/api/curl/api/v1/cart-items/destroy.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/carts/checkout.sh +0 -13
- data/examples/complex-test-app/docs/api/curl/api/v1/carts/show.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/home/list.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/notes/create.sh +0 -15
- data/examples/complex-test-app/docs/api/curl/api/v1/notes/list.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/cancel.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/create.sh +0 -29
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/destroy.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/list.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/orders/show.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/products/list.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/products/search.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/products/show.sh +0 -8
- data/examples/complex-test-app/docs/api/curl/api/v1/profiles/show.sh +0 -9
- data/examples/complex-test-app/docs/api/curl/api/v1/profiles/update.sh +0 -16
- data/examples/complex-test-app/docs/api/curl/api/v2/products/list.sh +0 -8
- data/examples/complex-test-app/docs/api/dataset.json +0 -5109
- data/examples/complex-test-app/docs/api/postman/collection.json +0 -2568
- data/examples/complex-test-app/generate.rb +0 -14
- data/examples/complex-test-app/reqcord.yml +0 -28
- data/examples/complex-test-app/test/integration/admin_test.rb +0 -70
- data/examples/complex-test-app/test/integration/cart_test.rb +0 -64
- data/examples/complex-test-app/test/integration/home_and_auth_test.rb +0 -53
- data/examples/complex-test-app/test/integration/orders_test.rb +0 -127
- data/examples/complex-test-app/test/integration/products_test.rb +0 -66
- data/examples/spec-app/.rspec +0 -1
- data/examples/spec-app/README.md +0 -36
- data/examples/spec-app/app.rb +0 -209
- data/examples/spec-app/docs/api/README.md +0 -45
- data/examples/spec-app/docs/api/api/v1/customers/create.md +0 -95
- data/examples/spec-app/docs/api/api/v1/customers/index.md +0 -11
- data/examples/spec-app/docs/api/api/v1/customers/list.md +0 -67
- data/examples/spec-app/docs/api/api/v1/customers/show.md +0 -65
- data/examples/spec-app/docs/api/api/v1/tasks/complete.md +0 -51
- data/examples/spec-app/docs/api/api/v1/tasks/create.md +0 -90
- data/examples/spec-app/docs/api/api/v1/tasks/destroy.md +0 -35
- data/examples/spec-app/docs/api/api/v1/tasks/index.md +0 -14
- data/examples/spec-app/docs/api/api/v1/tasks/list.md +0 -65
- data/examples/spec-app/docs/api/api/v1/tasks/show.md +0 -65
- data/examples/spec-app/docs/api/api/v1/tasks/update.md +0 -74
- data/examples/spec-app/docs/api/api/v1/users/create.md +0 -95
- data/examples/spec-app/docs/api/api/v1/users/index.md +0 -11
- data/examples/spec-app/docs/api/api/v1/users/list.md +0 -67
- data/examples/spec-app/docs/api/api/v1/users/show.md +0 -65
- data/examples/spec-app/docs/api/curl/api/v1/customers/create.sh +0 -17
- data/examples/spec-app/docs/api/curl/api/v1/customers/list.sh +0 -9
- data/examples/spec-app/docs/api/curl/api/v1/customers/show.sh +0 -9
- data/examples/spec-app/docs/api/curl/api/v1/tasks/complete.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/create.sh +0 -15
- data/examples/spec-app/docs/api/curl/api/v1/tasks/destroy.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/list.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/show.sh +0 -8
- data/examples/spec-app/docs/api/curl/api/v1/tasks/update.sh +0 -14
- data/examples/spec-app/docs/api/curl/api/v1/users/create.sh +0 -17
- data/examples/spec-app/docs/api/curl/api/v1/users/list.sh +0 -9
- data/examples/spec-app/docs/api/curl/api/v1/users/show.sh +0 -9
- data/examples/spec-app/docs/api/dataset.json +0 -2402
- data/examples/spec-app/docs/api/postman/collection.json +0 -1290
- data/examples/spec-app/generate.rb +0 -14
- data/examples/spec-app/reqcord.yml +0 -27
- data/examples/spec-app/spec/requests/customers_spec.rb +0 -71
- data/examples/spec-app/spec/requests/tasks_spec.rb +0 -78
- data/examples/spec-app/spec/requests/users_spec.rb +0 -68
- data/examples/spec-app/spec/spec_helper.rb +0 -17
- data/examples/test-app/README.md +0 -57
- data/examples/test-app/app.rb +0 -212
- data/examples/test-app/docs/api/README.md +0 -45
- data/examples/test-app/docs/api/api/v1/customers/create.md +0 -95
- data/examples/test-app/docs/api/api/v1/customers/index.md +0 -11
- data/examples/test-app/docs/api/api/v1/customers/list.md +0 -67
- data/examples/test-app/docs/api/api/v1/customers/show.md +0 -65
- data/examples/test-app/docs/api/api/v1/tasks/complete.md +0 -51
- data/examples/test-app/docs/api/api/v1/tasks/create.md +0 -90
- data/examples/test-app/docs/api/api/v1/tasks/destroy.md +0 -35
- data/examples/test-app/docs/api/api/v1/tasks/index.md +0 -14
- data/examples/test-app/docs/api/api/v1/tasks/list.md +0 -65
- data/examples/test-app/docs/api/api/v1/tasks/show.md +0 -65
- data/examples/test-app/docs/api/api/v1/tasks/update.md +0 -74
- data/examples/test-app/docs/api/api/v1/users/create.md +0 -95
- data/examples/test-app/docs/api/api/v1/users/index.md +0 -11
- data/examples/test-app/docs/api/api/v1/users/list.md +0 -67
- data/examples/test-app/docs/api/api/v1/users/show.md +0 -65
- data/examples/test-app/docs/api/curl/api/v1/customers/create.sh +0 -17
- data/examples/test-app/docs/api/curl/api/v1/customers/list.sh +0 -9
- data/examples/test-app/docs/api/curl/api/v1/customers/show.sh +0 -9
- data/examples/test-app/docs/api/curl/api/v1/tasks/complete.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/create.sh +0 -15
- data/examples/test-app/docs/api/curl/api/v1/tasks/destroy.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/list.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/show.sh +0 -8
- data/examples/test-app/docs/api/curl/api/v1/tasks/update.sh +0 -14
- data/examples/test-app/docs/api/curl/api/v1/users/create.sh +0 -17
- data/examples/test-app/docs/api/curl/api/v1/users/list.sh +0 -9
- data/examples/test-app/docs/api/curl/api/v1/users/show.sh +0 -9
- data/examples/test-app/docs/api/dataset.json +0 -2402
- data/examples/test-app/docs/api/postman/collection.json +0 -1290
- data/examples/test-app/generate.rb +0 -14
- data/examples/test-app/reqcord.yml +0 -28
- data/examples/test-app/test/integration/customers_test.rb +0 -72
- data/examples/test-app/test/integration/tasks_test.rb +0 -80
- data/examples/test-app/test/integration/users_test.rb +0 -72
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# Stands in for `bin/rails reqcord:generate`, which this single file example
|
|
4
|
-
# has no `bin/rails` to run.
|
|
5
|
-
require_relative "app"
|
|
6
|
-
|
|
7
|
-
dataset = Reqcord::Generator.call(
|
|
8
|
-
resources: ENV.fetch("RESOURCE", "").split(",").map(&:strip).reject(&:empty?),
|
|
9
|
-
version: ENV["VERSION"]
|
|
10
|
-
)
|
|
11
|
-
|
|
12
|
-
puts
|
|
13
|
-
puts "Endpoints: #{dataset.endpoints.size} (#{dataset.documented_endpoints.size} covered by tests)"
|
|
14
|
-
puts "Output: #{Reqcord.configuration.output_directory}"
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
version: 1
|
|
2
|
-
|
|
3
|
-
test:
|
|
4
|
-
framework: rspec
|
|
5
|
-
paths:
|
|
6
|
-
- spec/requests
|
|
7
|
-
|
|
8
|
-
routes:
|
|
9
|
-
prefix: /api
|
|
10
|
-
|
|
11
|
-
output:
|
|
12
|
-
directory: docs/api
|
|
13
|
-
|
|
14
|
-
exporters:
|
|
15
|
-
- curl
|
|
16
|
-
- markdown
|
|
17
|
-
- postman
|
|
18
|
-
|
|
19
|
-
variables:
|
|
20
|
-
base_url: http://localhost:3000
|
|
21
|
-
|
|
22
|
-
sanitize:
|
|
23
|
-
headers:
|
|
24
|
-
Authorization: "Bearer {{token}}"
|
|
25
|
-
X-Api-Key: "{{api_key}}"
|
|
26
|
-
body:
|
|
27
|
-
password: "{{password}}"
|
|
28
|
-
token: "{{token}}"
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "Admin and v2", type: :request do
|
|
6
|
-
let(:api_key) { { "X-Api-Key" => "sk_live_super-secret-key" } }
|
|
7
|
-
|
|
8
|
-
it "admin lists products with costs" do
|
|
9
|
-
get "/api/v1/admin/products", headers: api_key, as: :json
|
|
10
|
-
|
|
11
|
-
expect(response.status).to eq(200)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "admin requires an api key" do
|
|
15
|
-
get "/api/v1/admin/products", as: :json
|
|
16
|
-
|
|
17
|
-
expect(response.status).to eq(401)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "admin creates a product" do
|
|
21
|
-
post "/api/v1/admin/products",
|
|
22
|
-
params: { product: { sku: "TEA-003", name: "Jasmine", category: "tea", price_cents: 1400 } },
|
|
23
|
-
headers: api_key,
|
|
24
|
-
as: :json
|
|
25
|
-
|
|
26
|
-
expect(response.status).to eq(201)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
it "admin rejects a product without a sku" do
|
|
30
|
-
post "/api/v1/admin/products", params: { product: { sku: "", name: "Nameless" } }, headers: api_key, as: :json
|
|
31
|
-
|
|
32
|
-
expect(response.status).to eq(422)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
it "admin rejects a duplicate sku" do
|
|
36
|
-
post "/api/v1/admin/products",
|
|
37
|
-
params: { product: { sku: "TEA-001", name: "Earl Grey again", category: "tea", price_cents: 1200 } },
|
|
38
|
-
headers: api_key,
|
|
39
|
-
as: :json
|
|
40
|
-
|
|
41
|
-
expect(response.status).to eq(409)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "admin deletes a product" do
|
|
45
|
-
delete "/api/v1/admin/products/4", headers: api_key, as: :json
|
|
46
|
-
|
|
47
|
-
expect(response.status).to eq(204)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "admin cannot delete an unknown product" do
|
|
51
|
-
delete "/api/v1/admin/products/999", headers: api_key, as: :json
|
|
52
|
-
|
|
53
|
-
expect(response.status).to eq(404)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "v2 lists products" do
|
|
57
|
-
get "/api/v2/products", as: :json
|
|
58
|
-
|
|
59
|
-
expect(response.status).to eq(200)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "v2 follows a cursor" do
|
|
63
|
-
get "/api/v2/products", params: { cursor: "eyJpZCI6Mn0" }, as: :json
|
|
64
|
-
|
|
65
|
-
expect(response.status).to eq(200)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "Cart", type: :request do
|
|
6
|
-
let(:auth) { { "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" } }
|
|
7
|
-
|
|
8
|
-
it "shows the cart" do
|
|
9
|
-
get "/api/v1/cart", headers: auth, as: :json
|
|
10
|
-
|
|
11
|
-
expect(response.status).to eq(200)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "adds an item to the cart" do
|
|
15
|
-
post "/api/v1/cart/items", params: { item: { sku: "TEA-002", quantity: 3 } }, headers: auth, as: :json
|
|
16
|
-
|
|
17
|
-
expect(response.status).to eq(201)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "rejects an unknown sku" do
|
|
21
|
-
post "/api/v1/cart/items", params: { item: { sku: "TEA-999", quantity: 1 } }, headers: auth, as: :json
|
|
22
|
-
|
|
23
|
-
expect(response.status).to eq(422)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "removes an item from the cart" do
|
|
27
|
-
delete "/api/v1/cart/items/TEA-001", headers: auth, as: :json
|
|
28
|
-
|
|
29
|
-
expect(response.status).to eq(204)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "cannot remove an item that is not in the cart" do
|
|
33
|
-
delete "/api/v1/cart/items/MUG-002", headers: auth, as: :json
|
|
34
|
-
|
|
35
|
-
expect(response.status).to eq(404)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "checks out with a card" do
|
|
39
|
-
post "/api/v1/cart/checkout", params: { payment_method: "card" }, headers: auth, as: :json
|
|
40
|
-
|
|
41
|
-
expect(response.status).to eq(201)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "checks out with a bank transfer" do
|
|
45
|
-
post "/api/v1/cart/checkout", params: { payment_method: "bank_transfer" }, headers: auth, as: :json
|
|
46
|
-
|
|
47
|
-
expect(response.status).to eq(201)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "rejects an unknown payment method" do
|
|
51
|
-
post "/api/v1/cart/checkout", params: { payment_method: "cash" }, headers: auth, as: :json
|
|
52
|
-
|
|
53
|
-
expect(response.status).to eq(422)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "cart requires authentication" do
|
|
57
|
-
get "/api/v1/cart", as: :json
|
|
58
|
-
|
|
59
|
-
expect(response.status).to eq(401)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "Home and auth", type: :request do
|
|
6
|
-
let(:auth) { { "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" } }
|
|
7
|
-
|
|
8
|
-
it "root describes the api" do
|
|
9
|
-
get "/api/v1", as: :json
|
|
10
|
-
|
|
11
|
-
expect(response.status).to eq(200)
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
it "logs in with a form" do
|
|
15
|
-
post "/api/v1/auth/login", params: { email: "ada@example.com", password: "correct-horse-battery" }
|
|
16
|
-
|
|
17
|
-
expect(response.status).to eq(200)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "rejects a wrong password" do
|
|
21
|
-
post "/api/v1/auth/login", params: { email: "ada@example.com", password: "wrong" }
|
|
22
|
-
|
|
23
|
-
expect(response.status).to eq(401)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "shows the profile" do
|
|
27
|
-
get "/api/v1/profile", headers: auth, as: :json
|
|
28
|
-
|
|
29
|
-
expect(response.status).to eq(200)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "updates the profile" do
|
|
33
|
-
patch "/api/v1/profile", params: { profile: { name: "Ada L.", locale: "tr" } }, headers: auth, as: :json
|
|
34
|
-
|
|
35
|
-
expect(response.status).to eq(200)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "rejects an unknown locale" do
|
|
39
|
-
patch "/api/v1/profile", params: { profile: { locale: "xx" } }, headers: auth, as: :json
|
|
40
|
-
|
|
41
|
-
expect(response.status).to eq(422)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "profile requires authentication" do
|
|
45
|
-
get "/api/v1/profile", as: :json
|
|
46
|
-
|
|
47
|
-
expect(response.status).to eq(401)
|
|
48
|
-
end
|
|
49
|
-
end
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "Orders", type: :request do
|
|
6
|
-
let(:auth) { { "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" } }
|
|
7
|
-
|
|
8
|
-
let(:order_payload) do
|
|
9
|
-
{
|
|
10
|
-
order: {
|
|
11
|
-
line_items: [
|
|
12
|
-
{ sku: "TEA-001", quantity: 2 },
|
|
13
|
-
{ sku: "MUG-001", quantity: 1 }
|
|
14
|
-
],
|
|
15
|
-
shipping_address: { line1: "1 Analytical Engine Way", city: "London", country: "GB" }
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it "lists orders" do
|
|
21
|
-
get "/api/v1/orders", headers: auth, as: :json
|
|
22
|
-
|
|
23
|
-
expect(response.status).to eq(200)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "lists pending orders" do
|
|
27
|
-
get "/api/v1/orders", params: { status: "pending" }, headers: auth, as: :json
|
|
28
|
-
|
|
29
|
-
expect(response.status).to eq(200)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
it "lists shipped orders" do
|
|
33
|
-
get "/api/v1/orders", params: { status: "shipped" }, headers: auth, as: :json
|
|
34
|
-
|
|
35
|
-
expect(response.status).to eq(200)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
it "shows an order" do
|
|
39
|
-
get "/api/v1/orders/1", headers: auth, as: :json
|
|
40
|
-
|
|
41
|
-
expect(response.status).to eq(200)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
it "hides another customer's order" do
|
|
45
|
-
get "/api/v1/orders/3", headers: auth, as: :json
|
|
46
|
-
|
|
47
|
-
expect(response.status).to eq(403)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "returns not found for an unknown order" do
|
|
51
|
-
get "/api/v1/orders/999", headers: auth, as: :json
|
|
52
|
-
|
|
53
|
-
expect(response.status).to eq(404)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
it "creates an order" do
|
|
57
|
-
post "/api/v1/orders", params: order_payload, headers: auth, as: :json
|
|
58
|
-
|
|
59
|
-
expect(response.status).to eq(201)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it "creates a single item order" do
|
|
63
|
-
post "/api/v1/orders",
|
|
64
|
-
params: { order: { line_items: [{ sku: "MUG-002", quantity: 1 }], shipping_address: { line1: "Piazza", city: "Rome", country: "IT" } } },
|
|
65
|
-
headers: auth,
|
|
66
|
-
as: :json
|
|
67
|
-
|
|
68
|
-
expect(response.status).to eq(201)
|
|
69
|
-
end
|
|
70
|
-
|
|
71
|
-
it "rejects an order without line items" do
|
|
72
|
-
post "/api/v1/orders", params: { order: { line_items: [] } }, headers: auth, as: :json
|
|
73
|
-
|
|
74
|
-
expect(response.status).to eq(422)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it "rejects an unknown sku" do
|
|
78
|
-
post "/api/v1/orders", params: { order: { line_items: [{ sku: "TEA-999", quantity: 1 }] } }, headers: auth, as: :json
|
|
79
|
-
|
|
80
|
-
expect(response.status).to eq(422)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it "cancels a pending order" do
|
|
84
|
-
post "/api/v1/orders/1/cancel", headers: auth, as: :json
|
|
85
|
-
|
|
86
|
-
expect(response.status).to eq(200)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "cannot cancel a shipped order" do
|
|
90
|
-
post "/api/v1/orders/2/cancel", headers: auth, as: :json
|
|
91
|
-
|
|
92
|
-
expect(response.status).to eq(409)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
it "deletes an order" do
|
|
96
|
-
delete "/api/v1/orders/1", headers: auth, as: :json
|
|
97
|
-
|
|
98
|
-
expect(response.status).to eq(204)
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
it "orders require authentication" do
|
|
102
|
-
get "/api/v1/orders", as: :json
|
|
103
|
-
|
|
104
|
-
expect(response.status).to eq(401)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it "lists the notes of an order" do
|
|
108
|
-
get "/api/v1/orders/1/notes", headers: auth, as: :json
|
|
109
|
-
|
|
110
|
-
expect(response.status).to eq(200)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
it "adds a note to an order" do
|
|
114
|
-
post "/api/v1/orders/1/notes", params: { note: { body: "Ring the bell twice" } }, headers: auth, as: :json
|
|
115
|
-
|
|
116
|
-
expect(response.status).to eq(201)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
it "rejects an empty note" do
|
|
120
|
-
post "/api/v1/orders/1/notes", params: { note: { body: "" } }, headers: auth, as: :json
|
|
121
|
-
|
|
122
|
-
expect(response.status).to eq(422)
|
|
123
|
-
end
|
|
124
|
-
end
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "spec_helper"
|
|
4
|
-
|
|
5
|
-
RSpec.describe "Products", type: :request do
|
|
6
|
-
it "lists products" do
|
|
7
|
-
get "/api/v1/products", as: :json
|
|
8
|
-
|
|
9
|
-
expect(response.status).to eq(200)
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
it "filters products by category" do
|
|
13
|
-
get "/api/v1/products", params: { filter: { category: "tea" } }, as: :json
|
|
14
|
-
|
|
15
|
-
expect(response.status).to eq(200)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it "filters mugs" do
|
|
19
|
-
get "/api/v1/products", params: { filter: { category: "mugs" } }, as: :json
|
|
20
|
-
|
|
21
|
-
expect(response.status).to eq(200)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
it "sorts by price ascending" do
|
|
25
|
-
get "/api/v1/products", params: { sort: "price_asc" }, as: :json
|
|
26
|
-
|
|
27
|
-
expect(response.status).to eq(200)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
it "sorts by price descending" do
|
|
31
|
-
get "/api/v1/products", params: { sort: "price_desc" }, as: :json
|
|
32
|
-
|
|
33
|
-
expect(response.status).to eq(200)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
it "paginates" do
|
|
37
|
-
get "/api/v1/products", params: { page: 2, per_page: 2 }, as: :json
|
|
38
|
-
|
|
39
|
-
expect(response.status).to eq(200)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "shows a product" do
|
|
43
|
-
get "/api/v1/products/3", as: :json
|
|
44
|
-
|
|
45
|
-
expect(response.status).to eq(200)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it "returns not found for an unknown product" do
|
|
49
|
-
get "/api/v1/products/999", as: :json
|
|
50
|
-
|
|
51
|
-
expect(response.status).to eq(404)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
it "searches products" do
|
|
55
|
-
get "/api/v1/products/search", params: { q: "mug" }, as: :json
|
|
56
|
-
|
|
57
|
-
expect(response.status).to eq(200)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
it "search needs a query" do
|
|
61
|
-
get "/api/v1/products/search", as: :json
|
|
62
|
-
|
|
63
|
-
expect(response.status).to eq(400)
|
|
64
|
-
end
|
|
65
|
-
end
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../app"
|
|
4
|
-
|
|
5
|
-
require "rspec/core"
|
|
6
|
-
require "action_dispatch/testing/integration"
|
|
7
|
-
|
|
8
|
-
RSpec.configure do |config|
|
|
9
|
-
# What rspec-rails would give you as `type: :request`; spelled out here so
|
|
10
|
-
# the example runs with plain rspec-core.
|
|
11
|
-
config.include ActionDispatch::Integration::Runner, type: :request
|
|
12
|
-
config.include ActionDispatch::IntegrationTest::Behavior, type: :request
|
|
13
|
-
|
|
14
|
-
config.before(:each, type: :request) { integration_session }
|
|
15
|
-
|
|
16
|
-
config.expect_with(:rspec) { |expectations| expectations.syntax = :expect }
|
|
17
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# complex-test-app (Minitest)
|
|
2
|
-
|
|
3
|
-
A store API in one file, with ordinary Minitest integration tests, chosen to
|
|
4
|
-
show the harder things Reqcord documents. Start with [test-app](../test-app)
|
|
5
|
-
if you want the gentle version.
|
|
6
|
-
|
|
7
|
-
| Endpoint | What it shows in the output |
|
|
8
|
-
| --- | --- |
|
|
9
|
-
| `GET /api/v1` | `root` inside a namespace, titled "Home" |
|
|
10
|
-
| `POST /api/v1/auth/login` | a **form** post (`urlencoded` in Postman, `--data 'email=…'` in cURL); the `token` in the response is sanitized to `{{token}}` |
|
|
11
|
-
| `GET` / `PATCH /api/v1/profile` | singular `resource`; `PATCH` and `PUT` folded into one page |
|
|
12
|
-
| `GET /api/v1/products` | nested query `filter[category]`, an optional `sort` with a closed set (`"price_asc" \| "price_desc"`), `page` / `per_page` |
|
|
13
|
-
| `GET /api/v1/products/search` | collection action, `400` without `q` |
|
|
14
|
-
| `POST /api/v1/orders` | an array body: `order.line_items[].sku`, `order.shipping_address.city` |
|
|
15
|
-
| `GET /api/v1/orders/:id` | `403` for another customer's order, `404` |
|
|
16
|
-
| `POST /api/v1/orders/:id/cancel` | member action, `409` once shipped |
|
|
17
|
-
| `GET /api/v1/orders/:order_id/notes` | nested resource, `order_id` as a path parameter |
|
|
18
|
-
| `GET /api/v1/cart` | singular `resource :cart` — one record, no id |
|
|
19
|
-
| `POST` / `DELETE /api/v1/cart/items/:sku` | items nested under the cart, addressed by `sku` (`param: :sku`) |
|
|
20
|
-
| `POST /api/v1/cart/checkout` | custom action on a singular resource ("Checkout Cart"), `payment_method` as `"bank_transfer" \| "card"` |
|
|
21
|
-
| `/api/v1/admin/products` | a second credential (`X-Api-Key` → `{{api_key}}`), its own `admin` folder, `409` on a duplicate sku |
|
|
22
|
-
| `GET /api/v2/products` | a second API version next to the first: `VERSION=v2 ruby generate.rb` |
|
|
23
|
-
|
|
24
|
-
Every route is covered by a test, so the report ends in
|
|
25
|
-
`routes: 22 = 22 documented + 0 uncovered + 0 skipped`.
|
|
26
|
-
|
|
27
|
-
```text
|
|
28
|
-
app.rb the application
|
|
29
|
-
test/integration/*_test.rb ordinary integration tests
|
|
30
|
-
reqcord.yml paths, prefix, two sanitized headers and two body keys
|
|
31
|
-
docs/api/ generated Markdown, cURL scripts, Postman collection
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Regenerate
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
ruby generate.rb
|
|
38
|
-
RESOURCE=orders,notes ruby generate.rb
|
|
39
|
-
VERSION=v2 ruby generate.rb
|
|
40
|
-
```
|