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.
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