trailblazer-endpoint 0.0.5 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +21 -0
- data/README.md +40 -5
- data/lib/trailblazer/endpoint/controller.rb +55 -22
- data/lib/trailblazer/endpoint/dsl.rb +2 -0
- data/lib/trailblazer/endpoint/options.rb +0 -23
- data/lib/trailblazer/endpoint/protocol/cipher.rb +27 -0
- data/lib/trailblazer/endpoint/protocol/controller.rb +102 -0
- data/lib/trailblazer/endpoint/protocol/find_process_model.rb +15 -0
- data/lib/trailblazer/endpoint/protocol.rb +2 -3
- data/lib/trailblazer/endpoint/version.rb +1 -1
- data/lib/trailblazer/endpoint.rb +45 -25
- data/test/docs/controller_test.rb +61 -1
- data/test/rails-app/Gemfile +17 -1
- data/test/rails-app/Gemfile.lock +134 -83
- data/test/rails-app/app/concepts/song/cell/create.rb +4 -0
- data/test/rails-app/app/concepts/song/cell/new.rb +4 -0
- data/test/rails-app/app/concepts/song/operation/create.rb +5 -1
- data/test/rails-app/app/concepts/song/view/create.erb +1 -0
- data/test/rails-app/app/concepts/song/view/new.erb +1 -0
- data/test/rails-app/app/controllers/api/v1/songs_controller.rb +13 -7
- data/test/rails-app/app/controllers/application_controller/api.rb +3 -1
- data/test/rails-app/app/controllers/application_controller/web.rb +35 -19
- data/test/rails-app/app/controllers/application_controller.rb +3 -1
- data/test/rails-app/app/controllers/auth_controller.rb +44 -0
- data/test/rails-app/app/controllers/home_controller.rb +5 -0
- data/test/rails-app/app/controllers/songs_controller.rb +255 -12
- data/test/rails-app/app/models/song.rb +4 -1
- data/test/rails-app/app/models/user.rb +3 -1
- data/test/rails-app/config/application.rb +1 -1
- data/test/rails-app/config/environments/test.rb +2 -0
- data/test/rails-app/config/routes.rb +21 -3
- data/test/rails-app/test/controllers/api_songs_controller_test.rb +6 -2
- data/test/rails-app/test/controllers/songs_controller_test.rb +125 -10
- data/trailblazer-endpoint.gemspec +2 -2
- metadata +23 -9
@@ -1,24 +1,267 @@
|
|
1
|
+
#:endpoint
|
2
|
+
#:or
|
3
|
+
#:create
|
1
4
|
class SongsController < ApplicationController::Web
|
2
|
-
endpoint
|
5
|
+
endpoint Song::Operation::Create
|
3
6
|
|
4
|
-
|
7
|
+
#:endpoint end
|
8
|
+
def create
|
9
|
+
endpoint Song::Operation::Create do |ctx, current_user:, model:, **|
|
10
|
+
render html: cell(Song::Cell::Create, model, current_user: current_user)
|
11
|
+
end.Or do |ctx, contract:, **| # validation failure
|
12
|
+
render html: cell(Song::Cell::New, contract)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
#:create end
|
16
|
+
|
17
|
+
#~oskip
|
18
|
+
class CreateOrController < SongsController
|
19
|
+
#~oskip end
|
20
|
+
def create
|
21
|
+
endpoint Song::Operation::Create do |ctx, current_user:, model:, **|
|
22
|
+
render html: cell(Song::Cell::Create, model, current_user: current_user)
|
23
|
+
end.Or do |ctx, contract:, **| # validation failure
|
24
|
+
render json: contract.errors, status: 422
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
#:or end
|
29
|
+
|
30
|
+
def create_without_block
|
31
|
+
endpoint Song::Operation::Create
|
32
|
+
end
|
33
|
+
|
34
|
+
class CreateWithOptionsController < SongsController
|
35
|
+
#:create-options
|
36
|
+
def create
|
37
|
+
endpoint Song::Operation::Create, session: {user_id: 2} do |ctx, current_user:, model:, **|
|
38
|
+
render html: cell(Song::Cell::Create, model, current_user: current_user)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
#:create-options end
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
class CreateWithOptionsForDomainCtxController < SongsController
|
46
|
+
#:domain_ctx
|
47
|
+
def create
|
48
|
+
endpoint Song::Operation::Create, options_for_domain_ctx: {params: {id: 999}} do |ctx, model:, **|
|
49
|
+
render html: cell(Song::Cell::Create, model)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
#:domain_ctx end
|
53
|
+
end
|
54
|
+
|
55
|
+
class CreateEndpointCtxController < SongsController
|
56
|
+
#:endpoint_ctx
|
57
|
+
def create
|
58
|
+
endpoint Song::Operation::Create do |ctx, endpoint_ctx:, **|
|
59
|
+
render html: "Created", status: endpoint_ctx[:status]
|
60
|
+
end.Or do |ctx, **| # validation failure
|
61
|
+
#~empty
|
62
|
+
#~empty end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
#:endpoint_ctx end
|
66
|
+
end
|
67
|
+
|
68
|
+
# end.Or do |ctx, endpoint_ctx:, **| # validation failure
|
69
|
+
# render json: endpoint_ctx.keys, status: 422
|
70
|
+
# end
|
71
|
+
|
72
|
+
|
73
|
+
class CreateWithProtocolFailureController < SongsController
|
74
|
+
#:protocol_failure
|
75
|
+
def create_with_protocol_failure
|
76
|
+
endpoint Song::Operation::Create do |ctx, **|
|
77
|
+
redirect_to dashboard_path
|
78
|
+
end.protocol_failure do |ctx, **|
|
79
|
+
render html: "wrong login, app crashed", status: 500
|
80
|
+
end
|
81
|
+
end
|
82
|
+
#:protocol_failure end
|
83
|
+
end
|
5
84
|
|
85
|
+
# {:process_model} is copied from {domain_ctx[:model]} via {#insert_copy_from_domain_ctx!}.
|
86
|
+
class Create1Controller < SongsController
|
6
87
|
def create
|
7
|
-
endpoint
|
88
|
+
endpoint Song::Operation::Create do |ctx, endpoint_ctx:, **|
|
89
|
+
render html: endpoint_ctx[:process_model].inspect.html_safe
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# endpoint_ctx
|
96
|
+
# :resume_data
|
97
|
+
# domain_ctx
|
98
|
+
# :resume_data (copy)
|
99
|
+
|
100
|
+
|
101
|
+
# authenticate
|
102
|
+
|
103
|
+
# deserialize ==> {resume_data: {id: 1}}
|
104
|
+
# deserialize_process_model_id_from_resume_data
|
105
|
+
|
106
|
+
# find_process_model
|
107
|
+
# policy
|
108
|
+
# domain_activity
|
109
|
+
|
110
|
+
# serialize suspend_data and deserialize resume_data
|
111
|
+
class SerializeController < SongsController
|
112
|
+
endpoint Song::Operation::Create,
|
113
|
+
protocol: ApplicationController::Web::Protocol
|
114
|
+
# serialize: true
|
115
|
+
|
116
|
+
def self.options_for_block_options(ctx, **)
|
117
|
+
{
|
118
|
+
invoke: Trailblazer::Developer.method(:wtf?) # FIXME
|
119
|
+
}
|
120
|
+
end
|
121
|
+
|
122
|
+
|
123
|
+
def self.options_for_endpoint(ctx, controller:, **)
|
124
|
+
{
|
125
|
+
cipher_key: Rails.application.config.cipher_key,
|
126
|
+
|
127
|
+
encrypted_resume_data: controller.params[:encrypted_resume_data],
|
128
|
+
}
|
129
|
+
end
|
130
|
+
|
131
|
+
directive :options_for_block_options, method(:options_for_block_options)
|
132
|
+
directive :options_for_endpoint, method(:options_for_endpoint)
|
133
|
+
|
134
|
+
def create
|
135
|
+
encrypted_value = Trailblazer::Workflow::Cipher.encrypt_value({}, cipher_key: cipher_key, value: JSON.dump({id: "findings received", class: Object}))
|
136
|
+
|
137
|
+
endpoint Song::Operation::Create, encrypted_resume_data: encrypted_value, process_model_from_resume_data: false do |ctx, current_user:, endpoint_ctx:, **|
|
138
|
+
render html: cell(Song::Cell::Create, model, current_user: current_user)
|
139
|
+
end.Or do |ctx, contract:, **| # validation failure
|
140
|
+
render html: cell(Song::Cell::New, contract)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# TODO: not really a doc test.
|
146
|
+
# the entire deserialize cycle is skipped since we only use {:serialize}
|
147
|
+
class Serialize1Controller < SerializeController
|
148
|
+
class Create < Trailblazer::Operation
|
149
|
+
pass ->(ctx, **) { ctx[:model] = ctx.key?(:model) ? ctx[:model] : false }
|
150
|
+
end
|
151
|
+
|
152
|
+
endpoint "Create",
|
153
|
+
domain_activity: Create,
|
154
|
+
serialize: true,
|
155
|
+
deserialize: true
|
156
|
+
|
157
|
+
def create
|
158
|
+
# {:model} and {:memory} are from the domain_ctx.
|
159
|
+
# {:encrypted_suspend_data} from endpoint.
|
160
|
+
endpoint "Create" do |ctx, model:, endpoint_ctx:, **|
|
161
|
+
render html: "#{model.inspect}/#{ctx[:memory].inspect}/#{endpoint_ctx[:encrypted_suspend_data]}".html_safe
|
162
|
+
end.Or do |ctx, **| # validation failure
|
163
|
+
render html: "xxx", status: 500
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# TODO: not really a doc test.
|
169
|
+
# ---------deserialize cycle is skipped.
|
170
|
+
# we serialize {:remember}.
|
171
|
+
class Serialize2Controller < Serialize1Controller # "render confirm page"
|
172
|
+
class Create < Trailblazer::Operation
|
173
|
+
pass ->(ctx, **) { ctx[:model] = ctx.key?(:model) ? ctx[:model] : false }
|
174
|
+
step ->(ctx, **) { ctx[:suspend_data] = {remember: OpenStruct.new(id: 1), id: 9} } # write to domain_ctx[:suspend_data]
|
175
|
+
end
|
176
|
+
|
177
|
+
endpoint "Create",
|
178
|
+
domain_activity: Create,
|
179
|
+
serialize: true
|
180
|
+
end
|
181
|
+
|
182
|
+
# we can read from {:resume_data}
|
183
|
+
class Serialize3Controller < Serialize1Controller # "process submitted confirm page"
|
184
|
+
class Create < Trailblazer::Operation
|
185
|
+
pass ->(ctx, **) { ctx[:model] = ctx.key?(:model) ? ctx[:model] : false }
|
186
|
+
pass ->(ctx, **) { ctx[:memory] = ctx[:resume_data] } # read/process the suspended data
|
187
|
+
end
|
188
|
+
|
189
|
+
endpoint "Create",
|
190
|
+
domain_activity: Create,
|
191
|
+
deserialize: true
|
192
|
+
end
|
193
|
+
|
194
|
+
# find process_model via id in suspend/resume data (used to be called {process_model_from_resume_data})
|
195
|
+
class Serialize4Controller < Serialize1Controller
|
196
|
+
class Create < Trailblazer::Operation
|
197
|
+
pass ->(ctx, **) { ctx[:model] = ctx.key?(:model) ? ctx[:model] : false }
|
198
|
+
pass ->(ctx, **) { ctx[:memory] = ctx[:resume_data] } # read/process the suspended data
|
199
|
+
end
|
200
|
+
|
201
|
+
endpoint "Create",
|
202
|
+
domain_activity: Create,
|
203
|
+
deserialize: true,
|
204
|
+
find_process_model: true,
|
205
|
+
deserialize_process_model_id_from_resume_data: true
|
206
|
+
|
207
|
+
def create
|
208
|
+
endpoint "Create", process_model_class: Song do |ctx, endpoint_ctx:, **|
|
209
|
+
render html: "#{endpoint_ctx[:process_model_id].inspect}/#{ctx[:memory].inspect}/#{endpoint_ctx[:encrypted_suspend_data]}".html_safe
|
210
|
+
end
|
211
|
+
end
|
8
212
|
end
|
9
213
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
214
|
+
# find process_model from resume
|
215
|
+
# FIXME: what is the diff to Controller4?
|
216
|
+
class Serialize5Controller < Serialize1Controller
|
217
|
+
endpoint "Create",
|
218
|
+
domain_activity: Serialize4Controller::Create,
|
219
|
+
deserialize: true,
|
220
|
+
find_process_model: true,
|
221
|
+
deserialize_process_model_id_from_resume_data: true
|
222
|
+
|
223
|
+
def create
|
224
|
+
endpoint "Create", find_process_model: true, process_model_class: Song, process_model_id: params[:id] do |ctx, model:, endpoint_ctx:, **|
|
225
|
+
render html: "#{model.inspect}/#{ctx[:memory].inspect}/#{endpoint_ctx[:encrypted_suspend_data]}".html_safe
|
226
|
+
end
|
14
227
|
end
|
15
228
|
end
|
16
229
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
230
|
+
# find process_model from action_options
|
231
|
+
class Serialize6Controller < Serialize1Controller
|
232
|
+
endpoint "Create",
|
233
|
+
domain_activity: Serialize4Controller::Create,
|
234
|
+
protocol: ApplicationController::Web::Protocol,
|
235
|
+
find_process_model: true
|
236
|
+
|
237
|
+
def create
|
238
|
+
endpoint "Create", find_process_model: true, process_model_class: Song, process_model_id: params[:id] do |ctx, model:, endpoint_ctx:, **|
|
239
|
+
render html: "#{model.inspect}/#{endpoint_ctx[:process_model].inspect}/#{endpoint_ctx[:encrypted_suspend_data]}".html_safe
|
240
|
+
end
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
# Configure only {:find_process_model} and {:protocol}.
|
245
|
+
class Serialize7Controller < Serialize1Controller
|
246
|
+
endpoint find_process_model: true # generic setting for all endpoints in this controller.
|
247
|
+
|
248
|
+
endpoint "Create", # no need to specify {:find_process_model}
|
249
|
+
domain_activity: Serialize4Controller::Create
|
250
|
+
|
251
|
+
endpoint "New",
|
252
|
+
find_process_model: false,
|
253
|
+
domain_activity: Serialize4Controller::Create
|
254
|
+
|
255
|
+
def create
|
256
|
+
endpoint "Create", process_model_class: Song, process_model_id: params[:id] do |ctx, model:, endpoint_ctx:, **|
|
257
|
+
render html: "#{model.inspect}/#{endpoint_ctx[:process_model].inspect}/#{endpoint_ctx[:encrypted_suspend_data]}".html_safe
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def new
|
262
|
+
endpoint "New", process_model_class: Song, process_model_id: params[:id] do |ctx, model:, endpoint_ctx:, **|
|
263
|
+
render html: "#{model.inspect}/#{endpoint_ctx[:process_model].inspect}/#{endpoint_ctx[:encrypted_suspend_data]}".html_safe
|
264
|
+
end
|
22
265
|
end
|
23
266
|
end
|
24
267
|
end
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class User < Struct.new(:id, :email)
|
2
|
-
def self.find_by(id:)
|
2
|
+
def self.find_by(id: false, email: false)
|
3
|
+
return User.new(1, "yogi@trb.to") if email == "yogi@trb.to"
|
3
4
|
return User.new(id, "yogi@trb.to") if id.to_s == "1"
|
5
|
+
return User.new(id, "seuros@trb.to") if id.to_s == "2"
|
4
6
|
end
|
5
7
|
end
|
@@ -33,6 +33,6 @@ module RailsApp
|
|
33
33
|
# Only loads a smaller set of middleware suitable for API only apps.
|
34
34
|
# Middleware like session, flash, cookies can be added back manually.
|
35
35
|
# Skip views, helpers and assets when generating a new resource.
|
36
|
-
config.api_only =
|
36
|
+
config.api_only = false
|
37
37
|
end
|
38
38
|
end
|
@@ -35,4 +35,6 @@ Rails.application.configure do
|
|
35
35
|
|
36
36
|
# Raises error for missing translations.
|
37
37
|
# config.action_view.raise_on_missing_translations = true
|
38
|
+
|
39
|
+
config.cipher_key = "e1e1cc87asdfasdfasdfasfdasdfasdfasvhnfvbdb" # FIXME: this usually happens via the new key mechanism in Rails 6
|
38
40
|
end
|
@@ -1,11 +1,29 @@
|
|
1
1
|
Rails.application.routes.draw do
|
2
2
|
# For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
|
3
|
-
|
4
|
-
post "/songs/
|
5
|
-
post "/songs/
|
3
|
+
post "/songs/create_with_options", to: "songs_controller/create_with_options#create"
|
4
|
+
post "/songs/create_or", to: "songs_controller/create_or#create"
|
5
|
+
post "/songs/endpoint_ctx", to: "songs_controller/create_endpoint_ctx#create"
|
6
|
+
post "/songs/create_with_or", to: "songs#create"
|
7
|
+
post "/songs", to: "songs#create_without_block"
|
8
|
+
post "/songs/create_with_protocol_failure", to: "songs_controller/create_with_protocol_failure#create_with_protocol_failure"
|
9
|
+
post "/songs/create_with_options_for_domain_ctx", to: "songs_controller/create_with_options_for_domain_ctx#create"
|
10
|
+
post "/auth/sign_in", to: "auth#sign_in"
|
6
11
|
|
7
12
|
post "/v1/songs", to: "api/v1/songs#create"
|
8
13
|
get "/v1/songs/:id", to: "api/v1/songs#show"
|
9
14
|
|
10
15
|
get "/v1/songs_with_options/:id", to: "api/v1/songs_controller/with_options#show"
|
16
|
+
|
17
|
+
get "/", to: "home#dashboard"
|
18
|
+
|
19
|
+
post "/songs/serialize", to: "songs_controller/serialize#create"
|
20
|
+
post "/songs/copy_from_domain_ctx", to: "songs_controller/create1#create"
|
21
|
+
post "/songs/serialize1", to: "songs_controller/serialize1#create"
|
22
|
+
post "/songs/serialize2", to: "songs_controller/serialize2#create"
|
23
|
+
post "/songs/serialize3", to: "songs_controller/serialize3#create"
|
24
|
+
post "/songs/serialize4", to: "songs_controller/serialize4#create"
|
25
|
+
post "/songs/serialize5", to: "songs_controller/serialize5#create"
|
26
|
+
post "/songs/serialize6", to: "songs_controller/serialize6#create"
|
27
|
+
post "/songs/serialize7", to: "songs_controller/serialize7#create"
|
28
|
+
post "/songs/serialize72", to: "songs_controller/serialize7#new"
|
11
29
|
end
|
@@ -32,11 +32,13 @@ class ApiSongsControllerTest < ActionDispatch::IntegrationTest
|
|
32
32
|
test "API interface" do
|
33
33
|
yogi_jwt = jwt(1)
|
34
34
|
|
35
|
+
# default {success}
|
36
|
+
#:success
|
35
37
|
post_json "/v1/songs", {id: 1}, yogi_jwt
|
36
38
|
|
37
|
-
# default {success}
|
38
39
|
assert_response 200
|
39
40
|
assert_equal "{\"id\":1}", response.body
|
41
|
+
#:success end
|
40
42
|
|
41
43
|
# no proper input/params
|
42
44
|
post_json "/v1/songs", {}, yogi_jwt
|
@@ -45,9 +47,11 @@ class ApiSongsControllerTest < ActionDispatch::IntegrationTest
|
|
45
47
|
assert_equal "{\"errors\":{\"message\":\"The submitted data is invalid.\"}}", response.body
|
46
48
|
|
47
49
|
# 401
|
48
|
-
|
50
|
+
#:not_authenticated
|
51
|
+
post_json "/v1/songs", {} # no token
|
49
52
|
assert_response 401
|
50
53
|
assert_equal "{\"errors\":{\"message\":\"Authentication credentials were not provided or are invalid.\"}}", response.body
|
54
|
+
#:not_authenticated end
|
51
55
|
|
52
56
|
# 403
|
53
57
|
post_json "/v1/songs", {id: 1, policy: false}, yogi_jwt
|
@@ -1,7 +1,18 @@
|
|
1
1
|
require "test_helper"
|
2
2
|
|
3
3
|
class SongsControllerTest < ActionDispatch::IntegrationTest
|
4
|
-
test "
|
4
|
+
test "all possible outcomes with {Create}" do
|
5
|
+
# 401
|
6
|
+
post "/songs", params: {}
|
7
|
+
assert_response 401
|
8
|
+
assert_equal "", response.body
|
9
|
+
|
10
|
+
# sign in
|
11
|
+
post "/auth/sign_in", params: {username: "yogi@trb.to", password: "secret"}
|
12
|
+
assert_equal 1, session[:user_id]
|
13
|
+
# follow_redirect!
|
14
|
+
assert_equal 1, session[:user_id]
|
15
|
+
|
5
16
|
post "/songs", params: {id: 1}
|
6
17
|
# default {success} block doesn't do anything
|
7
18
|
assert_response 200
|
@@ -12,11 +23,6 @@ class SongsControllerTest < ActionDispatch::IntegrationTest
|
|
12
23
|
assert_response 422
|
13
24
|
assert_equal "", response.body
|
14
25
|
|
15
|
-
# 401
|
16
|
-
post "/songs", params: {authenticate: false}
|
17
|
-
assert_response 401
|
18
|
-
assert_equal "", response.body
|
19
|
-
|
20
26
|
# 403
|
21
27
|
post "/songs", params: {policy: false}
|
22
28
|
assert_response 403
|
@@ -25,7 +31,7 @@ class SongsControllerTest < ActionDispatch::IntegrationTest
|
|
25
31
|
post "/songs/create_with_options", params: {id: 1}
|
26
32
|
# {success} block renders model
|
27
33
|
assert_response 200
|
28
|
-
assert_equal "
|
34
|
+
assert_equal "<div>#<struct Song id=\"1\">#<struct User id=2, email=\"seuros@trb.to\"></div>\n", response.body
|
29
35
|
|
30
36
|
post "/songs/create_with_options", params: {}
|
31
37
|
# default {failure} block doesn't do anything
|
@@ -35,13 +41,122 @@ class SongsControllerTest < ActionDispatch::IntegrationTest
|
|
35
41
|
post "/songs/create_with_or", params: {id: 1}
|
36
42
|
# {success} block renders model
|
37
43
|
assert_response 200
|
38
|
-
assert_equal "
|
44
|
+
assert_equal "<div>#<struct Song id=\"1\">#<struct User id=1, email=\"yogi@trb.to\"></div>\n", response.body
|
39
45
|
|
40
46
|
post "/songs/create_with_or", params: {}
|
41
|
-
|
47
|
+
assert_response 200
|
48
|
+
assert_equal %{<div>#<struct errors=nil></div>\n}, response.body
|
49
|
+
|
50
|
+
# Or { render status: 422 }
|
51
|
+
post "/songs/create_or", params: {}
|
42
52
|
assert_response 422
|
43
|
-
assert_equal
|
53
|
+
assert_equal %{null}, response.body
|
54
|
+
|
55
|
+
# {:endpoint_ctx} is available in blocks
|
56
|
+
post "/songs/endpoint_ctx", params: {id: 1}
|
57
|
+
assert_response 200
|
58
|
+
assert_equal "Created", response.body
|
59
|
+
# assert_equal "[\"domain_ctx\",\"session\",\"controller\",\"config_source\",\"current_user\",\"domain_activity_return_signal\"]", response.body
|
60
|
+
|
61
|
+
# {:options_for_domain_ctx} overrides domain_ctx
|
62
|
+
post "/songs/create_with_options_for_domain_ctx", params: {id: 1} # params get overridden
|
63
|
+
assert_response 200
|
64
|
+
assert_equal "<div>#<struct Song id=999></div>\n", response.body
|
65
|
+
end
|
66
|
+
|
67
|
+
test "override protocol_failure" do
|
68
|
+
post "/songs/create_with_protocol_failure", params: {}
|
69
|
+
assert_response 500
|
70
|
+
assert_equal "wrong login, app crashed", response.body
|
71
|
+
end
|
72
|
+
|
73
|
+
test "serializing/deserializing/find_process_model_from_resume_data" do
|
74
|
+
# # 401
|
75
|
+
# post "/songs/serialize/"
|
76
|
+
# assert_response 401
|
77
|
+
|
78
|
+
# sign in
|
79
|
+
post "/auth/sign_in", params: {username: "yogi@trb.to", password: "secret"}
|
80
|
+
assert_equal 1, session[:user_id]
|
81
|
+
|
82
|
+
|
83
|
+
# When {:encrypted_resume_data} is {nil} the entire deserialize cycle is skipped.
|
84
|
+
# Nothing gets serialized.
|
85
|
+
# This is considered an error since we're expecting resume data.
|
86
|
+
post "/songs/serialize1/", params: {} # encrypted_resume_data: nil
|
87
|
+
assert_response 500
|
88
|
+
assert_equal "xxx", response.body # DISCUSS: is this an application or a protocol error?
|
89
|
+
|
90
|
+
# Nothing deserialized, but {:remember} serialized
|
91
|
+
# "confirm_delete form"
|
92
|
+
post "/songs/serialize2/", params: {} # {:remember} serialized
|
93
|
+
assert_response 200
|
94
|
+
encrypted_string = "0109C4E535EDA2CCE8CD69E50C179F5950CC4A2A898504F951C995B6BCEAFE1DFAB02894854B96B9D11C23E25DB5FB03"
|
95
|
+
assert_equal "false/nil/#{encrypted_string}", response.body
|
96
|
+
|
97
|
+
# {:remember} deserialized
|
98
|
+
# "submit confirm_delete"
|
99
|
+
# We're expecting serialized data and don't serialize anything.
|
100
|
+
post "/songs/serialize3/", params: {encrypted_resume_data: encrypted_string} # {:remember} serialized
|
101
|
+
assert_response 200
|
102
|
+
assert_equal "false/{\"remember\"=>\"#<OpenStruct id=1>\", \"id\"=>9}/", response.body
|
103
|
+
|
104
|
+
# retrieve process_model via id in {:resume_data}
|
105
|
+
# we can see {endpoint_ctx[:process_model_id]}
|
106
|
+
# We're expecting serialized data and don't serialize anything.
|
107
|
+
post "/songs/serialize4/", params: {encrypted_resume_data: encrypted_string}
|
108
|
+
assert_response 200
|
109
|
+
assert_equal "9/{\"remember\"=>\"#<OpenStruct id=1>\", \"id\"=>9}/", response.body
|
110
|
+
|
111
|
+
# retrieve process_model via {:resume_data}'s serialized id.
|
112
|
+
# We're expecting serialized data and don't serialize anything.
|
113
|
+
post "/songs/serialize5/", params: {encrypted_resume_data: encrypted_string}
|
114
|
+
assert_response 200
|
115
|
+
assert_equal "#<struct Song id=9>/{\"remember\"=>\"#<OpenStruct id=1>\", \"id\"=>9}/", response.body
|
116
|
+
# model not found
|
117
|
+
post "/songs/serialize5/", params: {encrypted_resume_data: "36C61CCE30E6CFDE637DF0DA9257CC49"}
|
118
|
+
assert_response 404
|
119
|
+
assert_equal "", response.body
|
120
|
+
|
121
|
+
# find model without serialize from params, no serialized stuff passed
|
122
|
+
# DISCUSS: this could be a different test
|
123
|
+
post "/songs/serialize6/", params: {id: 1}
|
124
|
+
assert_response 200
|
125
|
+
assert_equal "#<struct Song id=\"1\">/#<struct Song id=\"1\">/", response.body
|
126
|
+
# model not found
|
127
|
+
post "/songs/serialize6/", params: {id: nil}
|
128
|
+
assert_response 404
|
129
|
+
assert_equal "", response.body
|
130
|
+
|
131
|
+
# {find_process_model: true} set on controller level, for all endpoints.
|
132
|
+
post "/songs/serialize7/", params: {id: 1}
|
133
|
+
assert_response 200
|
134
|
+
assert_equal "#<struct Song id=\"1\">/#<struct Song id=\"1\">/", response.body
|
135
|
+
# {find_process_model: false} overrides controller setting
|
136
|
+
post "/songs/serialize72/", params: {id: 1}
|
137
|
+
assert_response 200
|
138
|
+
assert_equal "false/false/", response.body
|
139
|
+
|
140
|
+
|
141
|
+
# {#insert_copy_from_domain_ctx!} provides {:process_model}
|
142
|
+
post "/songs/copy_from_domain_ctx", params: {id: 1}
|
143
|
+
assert_response 200
|
144
|
+
assert_equal %{#<struct Song id="1">}, response.body
|
145
|
+
end
|
146
|
+
|
147
|
+
test "sign_in" do
|
148
|
+
# wrong credentials
|
149
|
+
post "/auth/sign_in", params: {}
|
150
|
+
assert_response 401
|
151
|
+
assert_equal "", response.body
|
152
|
+
assert_nil session[:user_id]
|
44
153
|
|
154
|
+
# valid signin
|
155
|
+
post "/auth/sign_in", params: {username: "yogi@trb.to", password: "secret"}
|
156
|
+
assert_response 302
|
157
|
+
# assert_equal "", response.body
|
158
|
+
assert_equal 1, session[:user_id]
|
159
|
+
assert_redirected_to "/"
|
45
160
|
end
|
46
161
|
end
|
47
162
|
|
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.email = ["apotonick@gmail.com"]
|
10
10
|
spec.description = %q{Endpoints handle authentication, policies, run your domain operation and set up the rendering.}
|
11
11
|
spec.summary = %q{Endpoints handle authentication, policies, run your domain operation and set up the rendering.}
|
12
|
-
spec.homepage = "http://trailblazer.to/
|
12
|
+
spec.homepage = "http://trailblazer.to/"
|
13
13
|
spec.license = "LGPL-3.0"
|
14
14
|
|
15
15
|
spec.files = `git ls-files`.split($/)
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |spec|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
18
|
spec.require_paths = ["lib"]
|
19
19
|
|
20
|
-
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.
|
20
|
+
spec.add_dependency "trailblazer-activity-dsl-linear", ">= 0.4.0", "< 0.5.0"
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler"
|
23
23
|
spec.add_development_dependency "rake"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: trailblazer-endpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nick Sutterer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trailblazer-activity-dsl-linear
|
@@ -16,20 +16,20 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.4.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.5.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - ">="
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: 0.
|
29
|
+
version: 0.4.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 0.5.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: bundler
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,6 +109,9 @@ files:
|
|
109
109
|
- lib/trailblazer/endpoint/dsl.rb
|
110
110
|
- lib/trailblazer/endpoint/options.rb
|
111
111
|
- lib/trailblazer/endpoint/protocol.rb
|
112
|
+
- lib/trailblazer/endpoint/protocol/cipher.rb
|
113
|
+
- lib/trailblazer/endpoint/protocol/controller.rb
|
114
|
+
- lib/trailblazer/endpoint/protocol/find_process_model.rb
|
112
115
|
- lib/trailblazer/endpoint/rails.rb
|
113
116
|
- lib/trailblazer/endpoint/version.rb
|
114
117
|
- test/adapter/api_test.rb
|
@@ -129,13 +132,19 @@ files:
|
|
129
132
|
- test/rails-app/app/concepts/auth/jwt.rb
|
130
133
|
- test/rails-app/app/concepts/auth/operation/authenticate.rb
|
131
134
|
- test/rails-app/app/concepts/auth/operation/policy.rb
|
135
|
+
- test/rails-app/app/concepts/song/cell/create.rb
|
136
|
+
- test/rails-app/app/concepts/song/cell/new.rb
|
132
137
|
- test/rails-app/app/concepts/song/operation/create.rb
|
133
138
|
- test/rails-app/app/concepts/song/operation/show.rb
|
134
139
|
- test/rails-app/app/concepts/song/representer.rb
|
140
|
+
- test/rails-app/app/concepts/song/view/create.erb
|
141
|
+
- test/rails-app/app/concepts/song/view/new.erb
|
135
142
|
- test/rails-app/app/controllers/api/v1/songs_controller.rb
|
136
143
|
- test/rails-app/app/controllers/application_controller.rb
|
137
144
|
- test/rails-app/app/controllers/application_controller/api.rb
|
138
145
|
- test/rails-app/app/controllers/application_controller/web.rb
|
146
|
+
- test/rails-app/app/controllers/auth_controller.rb
|
147
|
+
- test/rails-app/app/controllers/home_controller.rb
|
139
148
|
- test/rails-app/app/controllers/songs_controller.rb
|
140
149
|
- test/rails-app/app/models/application_record.rb
|
141
150
|
- test/rails-app/app/models/concerns/.keep
|
@@ -178,7 +187,7 @@ files:
|
|
178
187
|
- test/rails-app/tmp/.keep
|
179
188
|
- test/test_helper.rb
|
180
189
|
- trailblazer-endpoint.gemspec
|
181
|
-
homepage: http://trailblazer.to/
|
190
|
+
homepage: http://trailblazer.to/
|
182
191
|
licenses:
|
183
192
|
- LGPL-3.0
|
184
193
|
metadata: {}
|
@@ -197,8 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
206
|
- !ruby/object:Gem::Version
|
198
207
|
version: '0'
|
199
208
|
requirements: []
|
200
|
-
|
201
|
-
rubygems_version: 2.7.3
|
209
|
+
rubygems_version: 3.2.3
|
202
210
|
signing_key:
|
203
211
|
specification_version: 4
|
204
212
|
summary: Endpoints handle authentication, policies, run your domain operation and
|
@@ -222,13 +230,19 @@ test_files:
|
|
222
230
|
- test/rails-app/app/concepts/auth/jwt.rb
|
223
231
|
- test/rails-app/app/concepts/auth/operation/authenticate.rb
|
224
232
|
- test/rails-app/app/concepts/auth/operation/policy.rb
|
233
|
+
- test/rails-app/app/concepts/song/cell/create.rb
|
234
|
+
- test/rails-app/app/concepts/song/cell/new.rb
|
225
235
|
- test/rails-app/app/concepts/song/operation/create.rb
|
226
236
|
- test/rails-app/app/concepts/song/operation/show.rb
|
227
237
|
- test/rails-app/app/concepts/song/representer.rb
|
238
|
+
- test/rails-app/app/concepts/song/view/create.erb
|
239
|
+
- test/rails-app/app/concepts/song/view/new.erb
|
228
240
|
- test/rails-app/app/controllers/api/v1/songs_controller.rb
|
229
241
|
- test/rails-app/app/controllers/application_controller.rb
|
230
242
|
- test/rails-app/app/controllers/application_controller/api.rb
|
231
243
|
- test/rails-app/app/controllers/application_controller/web.rb
|
244
|
+
- test/rails-app/app/controllers/auth_controller.rb
|
245
|
+
- test/rails-app/app/controllers/home_controller.rb
|
232
246
|
- test/rails-app/app/controllers/songs_controller.rb
|
233
247
|
- test/rails-app/app/models/application_record.rb
|
234
248
|
- test/rails-app/app/models/concerns/.keep
|