trailblazer-endpoint 0.0.5 → 0.0.9

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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +21 -0
  3. data/README.md +40 -5
  4. data/lib/trailblazer/endpoint/controller.rb +55 -22
  5. data/lib/trailblazer/endpoint/dsl.rb +2 -0
  6. data/lib/trailblazer/endpoint/options.rb +0 -23
  7. data/lib/trailblazer/endpoint/protocol/cipher.rb +27 -0
  8. data/lib/trailblazer/endpoint/protocol/controller.rb +102 -0
  9. data/lib/trailblazer/endpoint/protocol/find_process_model.rb +15 -0
  10. data/lib/trailblazer/endpoint/protocol.rb +2 -3
  11. data/lib/trailblazer/endpoint/version.rb +1 -1
  12. data/lib/trailblazer/endpoint.rb +45 -25
  13. data/test/docs/controller_test.rb +61 -1
  14. data/test/rails-app/Gemfile +17 -1
  15. data/test/rails-app/Gemfile.lock +134 -83
  16. data/test/rails-app/app/concepts/song/cell/create.rb +4 -0
  17. data/test/rails-app/app/concepts/song/cell/new.rb +4 -0
  18. data/test/rails-app/app/concepts/song/operation/create.rb +5 -1
  19. data/test/rails-app/app/concepts/song/view/create.erb +1 -0
  20. data/test/rails-app/app/concepts/song/view/new.erb +1 -0
  21. data/test/rails-app/app/controllers/api/v1/songs_controller.rb +13 -7
  22. data/test/rails-app/app/controllers/application_controller/api.rb +3 -1
  23. data/test/rails-app/app/controllers/application_controller/web.rb +35 -19
  24. data/test/rails-app/app/controllers/application_controller.rb +3 -1
  25. data/test/rails-app/app/controllers/auth_controller.rb +44 -0
  26. data/test/rails-app/app/controllers/home_controller.rb +5 -0
  27. data/test/rails-app/app/controllers/songs_controller.rb +255 -12
  28. data/test/rails-app/app/models/song.rb +4 -1
  29. data/test/rails-app/app/models/user.rb +3 -1
  30. data/test/rails-app/config/application.rb +1 -1
  31. data/test/rails-app/config/environments/test.rb +2 -0
  32. data/test/rails-app/config/routes.rb +21 -3
  33. data/test/rails-app/test/controllers/api_songs_controller_test.rb +6 -2
  34. data/test/rails-app/test/controllers/songs_controller_test.rb +125 -10
  35. data/trailblazer-endpoint.gemspec +2 -2
  36. metadata +23 -9
@@ -1,24 +1,267 @@
1
+ #:endpoint
2
+ #:or
3
+ #:create
1
4
  class SongsController < ApplicationController::Web
2
- endpoint("Create", domain_activity: Song::Operation::Create) do {} end # FIXME: we still need to provide an empty hash here if we want to override the not_found behavior.
5
+ endpoint Song::Operation::Create
3
6
 
4
- # directive :options_for_domain_ctx, ->(ctx, **) { {seq: []} }
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 "Create"
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
- def create_with_options
11
- endpoint "Create", process_model: "yay!" do |ctx, model:, endpoint_ctx:, **|
12
- # TODO test process_model
13
- render json: [model, endpoint_ctx[:process_model]]
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
- def create_with_or
18
- endpoint "Create" do |ctx, model:, **|
19
- render json: {or: model}
20
- end.Or do |ctx, model:, endpoint_ctx:, **|
21
- render json: model, status: 422
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,3 +1,6 @@
1
1
  class Song < Struct.new(:id)
2
-
2
+ def self.find_by(id: false)
3
+ return unless id
4
+ return Song.new(id)
5
+ end
3
6
  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 = true
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
- resources :songs
4
- post "/songs/create_with_options", to: "songs#create_with_options"
5
- post "/songs/create_with_or", to: "songs#create_with_or"
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
- post_json "/v1/songs", {authenticate: false}
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 "create 200" do
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 "[\"1\",\"yay!\"]", response.body
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 "{\"or\":\"1\"}", response.body
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
- # default {failure} block doesn't do anything
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 "null", response.body
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/gems/operation/endpoint.html"
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.3.0", "< 0.4.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.5
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: 2020-09-09 00:00:00.000000000 Z
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.3.0
19
+ version: 0.4.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 0.4.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.3.0
29
+ version: 0.4.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.4.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/gems/operation/endpoint.html
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
- rubyforge_project:
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