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: minitest
|
|
5
|
-
paths:
|
|
6
|
-
- test/integration
|
|
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,70 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../app"
|
|
4
|
-
require "minitest/autorun"
|
|
5
|
-
|
|
6
|
-
class AdminTest < ActionDispatch::IntegrationTest
|
|
7
|
-
def api_key
|
|
8
|
-
{ "X-Api-Key" => "sk_live_super-secret-key" }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "admin lists products with costs" do
|
|
12
|
-
get "/api/v1/admin/products", headers: api_key, as: :json
|
|
13
|
-
|
|
14
|
-
assert_response :ok
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "admin requires an api key" do
|
|
18
|
-
get "/api/v1/admin/products", as: :json
|
|
19
|
-
|
|
20
|
-
assert_response :unauthorized
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
test "admin creates a product" do
|
|
24
|
-
post "/api/v1/admin/products",
|
|
25
|
-
params: { product: { sku: "TEA-003", name: "Jasmine", category: "tea", price_cents: 1400 } },
|
|
26
|
-
headers: api_key,
|
|
27
|
-
as: :json
|
|
28
|
-
|
|
29
|
-
assert_response :created
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
test "admin rejects a product without a sku" do
|
|
33
|
-
post "/api/v1/admin/products", params: { product: { sku: "", name: "Nameless" } }, headers: api_key, as: :json
|
|
34
|
-
|
|
35
|
-
assert_response :unprocessable_entity
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
test "admin rejects a duplicate sku" do
|
|
39
|
-
post "/api/v1/admin/products",
|
|
40
|
-
params: { product: { sku: "TEA-001", name: "Earl Grey again", category: "tea", price_cents: 1200 } },
|
|
41
|
-
headers: api_key,
|
|
42
|
-
as: :json
|
|
43
|
-
|
|
44
|
-
assert_response :conflict
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
test "admin deletes a product" do
|
|
48
|
-
delete "/api/v1/admin/products/4", headers: api_key, as: :json
|
|
49
|
-
|
|
50
|
-
assert_response :no_content
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
test "admin cannot delete an unknown product" do
|
|
54
|
-
delete "/api/v1/admin/products/999", headers: api_key, as: :json
|
|
55
|
-
|
|
56
|
-
assert_response :not_found
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
test "v2 lists products" do
|
|
60
|
-
get "/api/v2/products", as: :json
|
|
61
|
-
|
|
62
|
-
assert_response :ok
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
test "v2 follows a cursor" do
|
|
66
|
-
get "/api/v2/products", params: { cursor: "eyJpZCI6Mn0" }, as: :json
|
|
67
|
-
|
|
68
|
-
assert_response :ok
|
|
69
|
-
end
|
|
70
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../app"
|
|
4
|
-
require "minitest/autorun"
|
|
5
|
-
|
|
6
|
-
class CartTest < ActionDispatch::IntegrationTest
|
|
7
|
-
def auth
|
|
8
|
-
{ "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "shows the cart" do
|
|
12
|
-
get "/api/v1/cart", headers: auth, as: :json
|
|
13
|
-
|
|
14
|
-
assert_response :ok
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
test "adds an item to the cart" do
|
|
18
|
-
post "/api/v1/cart/items", params: { item: { sku: "TEA-002", quantity: 3 } }, headers: auth, as: :json
|
|
19
|
-
|
|
20
|
-
assert_response :created
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
test "rejects an unknown sku" do
|
|
24
|
-
post "/api/v1/cart/items", params: { item: { sku: "TEA-999", quantity: 1 } }, headers: auth, as: :json
|
|
25
|
-
|
|
26
|
-
assert_response :unprocessable_entity
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
test "removes an item from the cart" do
|
|
30
|
-
delete "/api/v1/cart/items/TEA-001", headers: auth, as: :json
|
|
31
|
-
|
|
32
|
-
assert_response :no_content
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
test "cannot remove an item that is not in the cart" do
|
|
36
|
-
delete "/api/v1/cart/items/MUG-002", headers: auth, as: :json
|
|
37
|
-
|
|
38
|
-
assert_response :not_found
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
test "checks out with a card" do
|
|
42
|
-
post "/api/v1/cart/checkout", params: { payment_method: "card" }, headers: auth, as: :json
|
|
43
|
-
|
|
44
|
-
assert_response :created
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
test "checks out with a bank transfer" do
|
|
48
|
-
post "/api/v1/cart/checkout", params: { payment_method: "bank_transfer" }, headers: auth, as: :json
|
|
49
|
-
|
|
50
|
-
assert_response :created
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
test "rejects an unknown payment method" do
|
|
54
|
-
post "/api/v1/cart/checkout", params: { payment_method: "cash" }, headers: auth, as: :json
|
|
55
|
-
|
|
56
|
-
assert_response :unprocessable_entity
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
test "cart requires authentication" do
|
|
60
|
-
get "/api/v1/cart", as: :json
|
|
61
|
-
|
|
62
|
-
assert_response :unauthorized
|
|
63
|
-
end
|
|
64
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../app"
|
|
4
|
-
require "minitest/autorun"
|
|
5
|
-
|
|
6
|
-
class HomeAndAuthTest < ActionDispatch::IntegrationTest
|
|
7
|
-
def auth
|
|
8
|
-
{ "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
test "root describes the api" do
|
|
12
|
-
get "/api/v1", as: :json
|
|
13
|
-
|
|
14
|
-
assert_response :ok
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
# A form post, not JSON: the documentation must keep it a form.
|
|
18
|
-
test "logs in with a form" do
|
|
19
|
-
post "/api/v1/auth/login", params: { email: "ada@example.com", password: "correct-horse-battery" }
|
|
20
|
-
|
|
21
|
-
assert_response :ok
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
test "rejects a wrong password" do
|
|
25
|
-
post "/api/v1/auth/login", params: { email: "ada@example.com", password: "wrong" }
|
|
26
|
-
|
|
27
|
-
assert_response :unauthorized
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
test "shows the profile" do
|
|
31
|
-
get "/api/v1/profile", headers: auth, as: :json
|
|
32
|
-
|
|
33
|
-
assert_response :ok
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
test "updates the profile" do
|
|
37
|
-
patch "/api/v1/profile", params: { profile: { name: "Ada L.", locale: "tr" } }, headers: auth, as: :json
|
|
38
|
-
|
|
39
|
-
assert_response :ok
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
test "rejects an unknown locale" do
|
|
43
|
-
patch "/api/v1/profile", params: { profile: { locale: "xx" } }, headers: auth, as: :json
|
|
44
|
-
|
|
45
|
-
assert_response :unprocessable_entity
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
test "profile requires authentication" do
|
|
49
|
-
get "/api/v1/profile", as: :json
|
|
50
|
-
|
|
51
|
-
assert_response :unauthorized
|
|
52
|
-
end
|
|
53
|
-
end
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../app"
|
|
4
|
-
require "minitest/autorun"
|
|
5
|
-
|
|
6
|
-
class OrdersTest < ActionDispatch::IntegrationTest
|
|
7
|
-
def auth
|
|
8
|
-
{ "Authorization" => "Bearer eyJhbGciOiJIUzI1NiJ9.super-secret" }
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def order_payload
|
|
12
|
-
{
|
|
13
|
-
order: {
|
|
14
|
-
line_items: [
|
|
15
|
-
{ sku: "TEA-001", quantity: 2 },
|
|
16
|
-
{ sku: "MUG-001", quantity: 1 }
|
|
17
|
-
],
|
|
18
|
-
shipping_address: { line1: "1 Analytical Engine Way", city: "London", country: "GB" }
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
test "lists orders" do
|
|
24
|
-
get "/api/v1/orders", headers: auth, as: :json
|
|
25
|
-
|
|
26
|
-
assert_response :ok
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
test "lists pending orders" do
|
|
30
|
-
get "/api/v1/orders", params: { status: "pending" }, headers: auth, as: :json
|
|
31
|
-
|
|
32
|
-
assert_response :ok
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
test "lists shipped orders" do
|
|
36
|
-
get "/api/v1/orders", params: { status: "shipped" }, headers: auth, as: :json
|
|
37
|
-
|
|
38
|
-
assert_response :ok
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
test "shows an order" do
|
|
42
|
-
get "/api/v1/orders/1", headers: auth, as: :json
|
|
43
|
-
|
|
44
|
-
assert_response :ok
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
test "hides another customer's order" do
|
|
48
|
-
get "/api/v1/orders/3", headers: auth, as: :json
|
|
49
|
-
|
|
50
|
-
assert_response :forbidden
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
test "returns not found for an unknown order" do
|
|
54
|
-
get "/api/v1/orders/999", headers: auth, as: :json
|
|
55
|
-
|
|
56
|
-
assert_response :not_found
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
test "creates an order" do
|
|
60
|
-
post "/api/v1/orders", params: order_payload, headers: auth, as: :json
|
|
61
|
-
|
|
62
|
-
assert_response :created
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
test "creates a single item order" do
|
|
66
|
-
post "/api/v1/orders",
|
|
67
|
-
params: { order: { line_items: [{ sku: "MUG-002", quantity: 1 }], shipping_address: { line1: "Piazza", city: "Rome", country: "IT" } } },
|
|
68
|
-
headers: auth,
|
|
69
|
-
as: :json
|
|
70
|
-
|
|
71
|
-
assert_response :created
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
test "rejects an order without line items" do
|
|
75
|
-
post "/api/v1/orders", params: { order: { line_items: [] } }, headers: auth, as: :json
|
|
76
|
-
|
|
77
|
-
assert_response :unprocessable_entity
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
test "rejects an unknown sku" do
|
|
81
|
-
post "/api/v1/orders", params: { order: { line_items: [{ sku: "TEA-999", quantity: 1 }] } }, headers: auth, as: :json
|
|
82
|
-
|
|
83
|
-
assert_response :unprocessable_entity
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
test "cancels a pending order" do
|
|
87
|
-
post "/api/v1/orders/1/cancel", headers: auth, as: :json
|
|
88
|
-
|
|
89
|
-
assert_response :ok
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
test "cannot cancel a shipped order" do
|
|
93
|
-
post "/api/v1/orders/2/cancel", headers: auth, as: :json
|
|
94
|
-
|
|
95
|
-
assert_response :conflict
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
test "deletes an order" do
|
|
99
|
-
delete "/api/v1/orders/1", headers: auth, as: :json
|
|
100
|
-
|
|
101
|
-
assert_response :no_content
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
test "orders require authentication" do
|
|
105
|
-
get "/api/v1/orders", as: :json
|
|
106
|
-
|
|
107
|
-
assert_response :unauthorized
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
test "lists the notes of an order" do
|
|
111
|
-
get "/api/v1/orders/1/notes", headers: auth, as: :json
|
|
112
|
-
|
|
113
|
-
assert_response :ok
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
test "adds a note to an order" do
|
|
117
|
-
post "/api/v1/orders/1/notes", params: { note: { body: "Ring the bell twice" } }, headers: auth, as: :json
|
|
118
|
-
|
|
119
|
-
assert_response :created
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
test "rejects an empty note" do
|
|
123
|
-
post "/api/v1/orders/1/notes", params: { note: { body: "" } }, headers: auth, as: :json
|
|
124
|
-
|
|
125
|
-
assert_response :unprocessable_entity
|
|
126
|
-
end
|
|
127
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require_relative "../../app"
|
|
4
|
-
require "minitest/autorun"
|
|
5
|
-
|
|
6
|
-
class ProductsTest < ActionDispatch::IntegrationTest
|
|
7
|
-
test "lists products" do
|
|
8
|
-
get "/api/v1/products", as: :json
|
|
9
|
-
|
|
10
|
-
assert_response :ok
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
test "filters products by category" do
|
|
14
|
-
get "/api/v1/products", params: { filter: { category: "tea" } }, as: :json
|
|
15
|
-
|
|
16
|
-
assert_response :ok
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
test "filters mugs" do
|
|
20
|
-
get "/api/v1/products", params: { filter: { category: "mugs" } }, as: :json
|
|
21
|
-
|
|
22
|
-
assert_response :ok
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
test "sorts by price ascending" do
|
|
26
|
-
get "/api/v1/products", params: { sort: "price_asc" }, as: :json
|
|
27
|
-
|
|
28
|
-
assert_response :ok
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
test "sorts by price descending" do
|
|
32
|
-
get "/api/v1/products", params: { sort: "price_desc" }, as: :json
|
|
33
|
-
|
|
34
|
-
assert_response :ok
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
test "paginates" do
|
|
38
|
-
get "/api/v1/products", params: { page: 2, per_page: 2 }, as: :json
|
|
39
|
-
|
|
40
|
-
assert_response :ok
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
test "shows a product" do
|
|
44
|
-
get "/api/v1/products/3", as: :json
|
|
45
|
-
|
|
46
|
-
assert_response :ok
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
test "returns not found for an unknown product" do
|
|
50
|
-
get "/api/v1/products/999", as: :json
|
|
51
|
-
|
|
52
|
-
assert_response :not_found
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
test "searches products" do
|
|
56
|
-
get "/api/v1/products/search", params: { q: "mug" }, as: :json
|
|
57
|
-
|
|
58
|
-
assert_response :ok
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
test "search needs a query" do
|
|
62
|
-
get "/api/v1/products/search", as: :json
|
|
63
|
-
|
|
64
|
-
assert_response :bad_request
|
|
65
|
-
end
|
|
66
|
-
end
|
data/examples/spec-app/.rspec
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
--require spec_helper
|
data/examples/spec-app/README.md
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
# spec-app (RSpec)
|
|
2
|
-
|
|
3
|
-
The same API as [test-app](../test-app), documented from RSpec request specs
|
|
4
|
-
instead of Minitest. The generated dataset is identical in shape: the test
|
|
5
|
-
framework only decides how examples are named.
|
|
6
|
-
|
|
7
|
-
```text
|
|
8
|
-
app.rb the application (customers, users, tasks)
|
|
9
|
-
spec/requests/*_spec.rb ordinary request specs
|
|
10
|
-
spec/spec_helper.rb request helpers (see the note below)
|
|
11
|
-
reqcord.yml `test.framework: rspec`
|
|
12
|
-
docs/api/ generated Markdown, cURL scripts and Postman
|
|
13
|
-
collection — the same files test-app gets
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Regenerate
|
|
17
|
-
|
|
18
|
-
```bash
|
|
19
|
-
ruby generate.rb
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Notes
|
|
23
|
-
|
|
24
|
-
This example runs on plain `rspec-core`, so `spec_helper.rb` includes the
|
|
25
|
-
ActionDispatch request helpers itself and the specs assert
|
|
26
|
-
`response.status`. An application using `rspec-rails` gets `type: :request`
|
|
27
|
-
and `have_http_status` for free and needs none of that.
|
|
28
|
-
|
|
29
|
-
The only Reqcord-facing difference from test-app is one line in `reqcord.yml`:
|
|
30
|
-
|
|
31
|
-
```yaml
|
|
32
|
-
test:
|
|
33
|
-
framework: rspec
|
|
34
|
-
paths:
|
|
35
|
-
- spec/requests
|
|
36
|
-
```
|
data/examples/spec-app/app.rb
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# A tiny Rails API, in one file, so the example stays readable. In a real
|
|
4
|
-
# application this is just your app; Reqcord does not care how it is built.
|
|
5
|
-
#
|
|
6
|
-
# The same three resources as test-app — customers, users, tasks — so the two
|
|
7
|
-
# examples can be compared endpoint for endpoint.
|
|
8
|
-
ENV["RAILS_ENV"] ||= "test"
|
|
9
|
-
|
|
10
|
-
# Only needed because this example lives inside the Reqcord repository.
|
|
11
|
-
# In your own application, `gem "reqcord"` in the Gemfile is enough.
|
|
12
|
-
$LOAD_PATH.unshift File.expand_path("../../lib", __dir__)
|
|
13
|
-
|
|
14
|
-
require "rails"
|
|
15
|
-
require "action_controller/railtie"
|
|
16
|
-
require "reqcord"
|
|
17
|
-
|
|
18
|
-
class ExampleApp < Rails::Application
|
|
19
|
-
config.root = __dir__
|
|
20
|
-
config.eager_load = false
|
|
21
|
-
config.logger = Logger.new(IO::NULL)
|
|
22
|
-
config.secret_key_base = "a" * 64
|
|
23
|
-
config.hosts.clear
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
Rails.application.initialize!
|
|
27
|
-
|
|
28
|
-
module Api
|
|
29
|
-
module V1
|
|
30
|
-
class CustomersController < ActionController::API
|
|
31
|
-
CUSTOMERS = [
|
|
32
|
-
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
33
|
-
{ id: 2, name: "Jane Roe", email: "jane@example.com" }
|
|
34
|
-
].freeze
|
|
35
|
-
|
|
36
|
-
before_action :authenticate!
|
|
37
|
-
|
|
38
|
-
def index
|
|
39
|
-
render json: CUSTOMERS.first(params.fetch(:per_page, 25).to_i)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def show
|
|
43
|
-
customer = CUSTOMERS.find { |record| record[:id] == params[:id].to_i }
|
|
44
|
-
|
|
45
|
-
return render(json: { error: "Not Found" }, status: :not_found) unless customer
|
|
46
|
-
|
|
47
|
-
render json: customer
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
STATUSES = %w[active passive].freeze
|
|
51
|
-
|
|
52
|
-
def create
|
|
53
|
-
if params.dig(:customer, :email).to_s.empty?
|
|
54
|
-
return render(
|
|
55
|
-
json: { errors: { email: ["can't be blank"] } },
|
|
56
|
-
status: :unprocessable_entity
|
|
57
|
-
)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
unless STATUSES.include?(params.dig(:customer, :status).to_s)
|
|
61
|
-
return render(
|
|
62
|
-
json: { errors: { status: ["is not included in the list"] } },
|
|
63
|
-
status: :unprocessable_entity
|
|
64
|
-
)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
render json: { id: 3, **customer_params }, status: :created
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
private
|
|
71
|
-
|
|
72
|
-
def authenticate!
|
|
73
|
-
return if request.headers["Authorization"].present?
|
|
74
|
-
|
|
75
|
-
render json: { error: "Unauthorized" }, status: :unauthorized
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def customer_params
|
|
79
|
-
params.require(:customer).permit(:name, :email, :status).to_h.symbolize_keys
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
class UsersController < ActionController::API
|
|
84
|
-
USERS = [
|
|
85
|
-
{ id: 1, name: "John Doe", email: "john@example.com" },
|
|
86
|
-
{ id: 2, name: "Jane Roe", email: "jane@example.com" }
|
|
87
|
-
].freeze
|
|
88
|
-
|
|
89
|
-
before_action :authenticate!
|
|
90
|
-
|
|
91
|
-
def index
|
|
92
|
-
render json: USERS.first(params.fetch(:per_page, 25).to_i)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def show
|
|
96
|
-
user = USERS.find { |record| record[:id] == params[:id].to_i }
|
|
97
|
-
|
|
98
|
-
return render(json: { error: "Not Found" }, status: :not_found) unless user
|
|
99
|
-
|
|
100
|
-
render json: user
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
STATUSES = %w[active inactive].freeze
|
|
104
|
-
|
|
105
|
-
def create
|
|
106
|
-
if params.dig(:user, :email).to_s.empty?
|
|
107
|
-
return render(
|
|
108
|
-
json: { errors: { email: ["can't be blank"] } },
|
|
109
|
-
status: :unprocessable_entity
|
|
110
|
-
)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
unless STATUSES.include?(params.dig(:user, :status).to_s)
|
|
114
|
-
return render(
|
|
115
|
-
json: { errors: { status: ["is not included in the list"] } },
|
|
116
|
-
status: :unprocessable_entity
|
|
117
|
-
)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
render json: { id: 3, **user_params }, status: :created
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
private
|
|
124
|
-
|
|
125
|
-
def authenticate!
|
|
126
|
-
return if request.headers["Authorization"].present?
|
|
127
|
-
|
|
128
|
-
render json: { error: "Unauthorized" }, status: :unauthorized
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def user_params
|
|
132
|
-
params.require(:user).permit(:name, :email, :status).to_h.symbolize_keys
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
class TasksController < ActionController::API
|
|
137
|
-
TASKS = [
|
|
138
|
-
{ id: 1, title: "Write the docs", status: "open", priority: "high" },
|
|
139
|
-
{ id: 2, title: "Ship 0.1.1", status: "done", priority: "high" },
|
|
140
|
-
{ id: 3, title: "Tidy the backlog", status: "open", priority: "low" }
|
|
141
|
-
].freeze
|
|
142
|
-
|
|
143
|
-
STATUSES = %w[open done].freeze
|
|
144
|
-
PRIORITIES = %w[low high].freeze
|
|
145
|
-
|
|
146
|
-
def index
|
|
147
|
-
tasks = TASKS
|
|
148
|
-
tasks = tasks.select { |task| task[:status] == params[:status] } if params[:status].present?
|
|
149
|
-
|
|
150
|
-
render json: tasks
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
before_action :find_task, only: %i[show update complete destroy]
|
|
154
|
-
|
|
155
|
-
def show
|
|
156
|
-
render json: @task
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def create
|
|
160
|
-
if params.dig(:task, :title).to_s.empty?
|
|
161
|
-
return render(json: { errors: { title: ["can't be blank"] } }, status: :unprocessable_entity)
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
unless PRIORITIES.include?(params.dig(:task, :priority).to_s)
|
|
165
|
-
return render(json: { errors: { priority: ["is not included in the list"] } }, status: :unprocessable_entity)
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
render json: { id: 4, status: "open", **task_params }, status: :created
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
def update
|
|
172
|
-
render json: @task.merge(task_params)
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
def complete
|
|
176
|
-
render json: @task.merge(status: "done")
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def destroy
|
|
180
|
-
head :no_content
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
private
|
|
184
|
-
|
|
185
|
-
# Rendering in a before_action halts the chain, so the action never runs.
|
|
186
|
-
def find_task
|
|
187
|
-
@task = TASKS.find { |task| task[:id] == params[:id].to_i }
|
|
188
|
-
|
|
189
|
-
render(json: { error: "Not Found" }, status: :not_found) unless @task
|
|
190
|
-
end
|
|
191
|
-
|
|
192
|
-
def task_params
|
|
193
|
-
params.require(:task).permit(:title, :priority, :status).to_h.symbolize_keys
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
Rails.application.routes.draw do
|
|
200
|
-
namespace :api do
|
|
201
|
-
namespace :v1 do
|
|
202
|
-
resources :customers, only: %i[index show create]
|
|
203
|
-
resources :users, only: %i[index show create]
|
|
204
|
-
resources :tasks, except: %i[new edit] do
|
|
205
|
-
post :complete, on: :member
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
end
|
|
209
|
-
end
|