trailblazer-endpoint 0.0.6 → 0.0.10
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/CHANGES.md +19 -0
- data/lib/trailblazer/endpoint/controller.rb +27 -8
- data/lib/trailblazer/endpoint/dsl.rb +2 -0
- 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 +42 -24
- data/test/docs/controller_test.rb +2 -1
- data/test/rails-app/Gemfile +13 -1
- data/test/rails-app/Gemfile.lock +110 -84
- data/test/rails-app/app/controllers/application_controller/web.rb +4 -2
- data/test/rails-app/app/controllers/songs_controller.rb +183 -0
- data/test/rails-app/app/models/song.rb +4 -1
- data/test/rails-app/config/environments/test.rb +2 -0
- data/test/rails-app/config/routes.rb +11 -0
- data/test/rails-app/test/controllers/songs_controller_test.rb +74 -0
- data/trailblazer-endpoint.gemspec +2 -2
- metadata +11 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57e2396200f20eb000c87f7b740ea31dd41c9db79ea6d3ba02bdb2e85e0b8ba0
|
4
|
+
data.tar.gz: 68fc7c66e7fdebe16cf6a347c0d7104efb520fcf2fc8aabcafd79914df5492d9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93f8b8b7e0fad7959cec6ac2f8b11955867ccc6276ee511748beb072df2f66e00ccb648f082c30e7f776cf3736442688d0334e9c59ea95c06d96b6b26ea6f6ec
|
7
|
+
data.tar.gz: 200822214d8146292f64390c63fb3104386496b2326e6fd026d61bd477592fb6bc86d3a3acb48c8e9acd279ac5375f8164da816c6744e6ec5e901ec9d3edf718
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
# 0.0.10
|
2
|
+
|
3
|
+
* Require `dsl-linear` >= 0.5.0.
|
4
|
+
|
5
|
+
# 0.0.9
|
6
|
+
|
7
|
+
* Fix Ruby 3.0 code.
|
8
|
+
* Update dependencies.
|
9
|
+
|
10
|
+
# 0.0.8
|
11
|
+
|
12
|
+
* Add `Protocol.insert_copy_from_domain_ctx!` to copy from `domain_ctx` to the `endpoint_ctx`.
|
13
|
+
|
14
|
+
# 0.0.7
|
15
|
+
|
16
|
+
* BREAKING: Remove `:domain_ctx_filter` in favor of `Controller.insert_copy_to_domain_ctx!`.
|
17
|
+
* Add support for serializing `:suspend_data` and deserializing `:resume_data` so session data can get automatically encrypted and passed to the next action. This used to sit in `workflow`.
|
18
|
+
* Add `:find_process_model`. This introduces a new protocol step before `policy` to find the "process model" instead of letting the domain operation or even the policy (or both!) find the "current model".
|
19
|
+
|
1
20
|
# 0.0.6
|
2
21
|
|
3
22
|
* `Controller::endpoint` short form introduced.
|
@@ -92,18 +92,19 @@ module Trailblazer
|
|
92
92
|
extended.directive(:endpoints, ->(*) { {} })
|
93
93
|
end
|
94
94
|
|
95
|
-
|
95
|
+
# Builds and registers an endpoint in a controller class.
|
96
|
+
def endpoint(name=nil, **options, &block)
|
96
97
|
options = options.merge(protocol_block: block) if block_given?
|
97
98
|
|
98
|
-
return generic_endpoint_config(**
|
99
|
-
|
99
|
+
return generic_endpoint_config(**options) if name.nil?
|
100
|
+
|
101
|
+
build_endpoint(name, **options)
|
100
102
|
end
|
101
103
|
|
102
|
-
|
104
|
+
# Configures generic {:adapter}, {:protocol}, etc.
|
105
|
+
def generic_endpoint_config(**options)
|
103
106
|
self.singleton_class.define_method :generic_options do |ctx,**|
|
104
107
|
{
|
105
|
-
protocol: protocol,
|
106
|
-
adapter: adapter,
|
107
108
|
**options
|
108
109
|
}
|
109
110
|
end
|
@@ -111,10 +112,10 @@ module Trailblazer
|
|
111
112
|
directive :generic_options, method(:generic_options) # FIXME: do we need this?
|
112
113
|
end
|
113
114
|
|
114
|
-
def
|
115
|
+
def build_endpoint(name, domain_activity: name, **options)
|
115
116
|
build_options = options_for(:generic_options, {}).merge(domain_activity: domain_activity, **options) # DISCUSS: why don't we add this as another directive option/step?
|
116
117
|
|
117
|
-
endpoint = Trailblazer::Endpoint.build(build_options)
|
118
|
+
endpoint = Trailblazer::Endpoint.build(**build_options)
|
118
119
|
|
119
120
|
directive :endpoints, ->(*) { {name.to_s => endpoint} }
|
120
121
|
end
|
@@ -134,6 +135,24 @@ module Trailblazer
|
|
134
135
|
|
135
136
|
endpoint = endpoint_for(name)
|
136
137
|
|
138
|
+
# raise name.inspect unless block_given?
|
139
|
+
# TODO: check {dsl: false}
|
140
|
+
# unless block_given? # FIXME
|
141
|
+
# config_source = self.class # FIXME
|
142
|
+
# block_options = config_source.options_for(:options_for_block_options, **action_options)
|
143
|
+
# block_options = Trailblazer::Endpoint::Options.merge_with(action_options, block_options)
|
144
|
+
|
145
|
+
# signal, (ctx, _) = Trailblazer::Endpoint::Controller.advance_endpoint_for_controller(
|
146
|
+
# endpoint: endpoint,
|
147
|
+
# block_options: block_options,
|
148
|
+
# config_source: config_source,
|
149
|
+
# **action_options
|
150
|
+
# )
|
151
|
+
|
152
|
+
# return ctx
|
153
|
+
# end
|
154
|
+
|
155
|
+
|
137
156
|
invoke_endpoint_with_dsl(endpoint: endpoint, **action_options, &block)
|
138
157
|
end
|
139
158
|
|
@@ -19,9 +19,11 @@ module Trailblazer
|
|
19
19
|
# #call
|
20
20
|
def to_args(default_block_options)
|
21
21
|
return options,
|
22
|
+
default_block_options.merge( # this adds :invoke.
|
22
23
|
success_block: success_block || default_block_options[:success_block],
|
23
24
|
failure_block: failure_block || default_block_options[:failure_block],
|
24
25
|
protocol_failure_block: protocol_failure_block || default_block_options[:protocol_failure_block]
|
26
|
+
)
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "openssl"
|
2
|
+
|
3
|
+
module Trailblazer
|
4
|
+
class Endpoint::Protocol
|
5
|
+
module Controller
|
6
|
+
module Cipher # FIXME: copied from Tyrant!
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def encrypt_value(ctx, value:, cipher_key:, **)
|
10
|
+
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').encrypt
|
11
|
+
cipher.key = Digest::SHA1.hexdigest(cipher_key)[0..23] # ArgumentError: key must be 24 bytes
|
12
|
+
s = cipher.update(value) + cipher.final
|
13
|
+
|
14
|
+
ctx[:encrypted_value] = s.unpack('H*')[0].upcase
|
15
|
+
end
|
16
|
+
|
17
|
+
def decrypt_value(ctx, encrypted_value:, cipher_key:, **)
|
18
|
+
cipher = OpenSSL::Cipher.new('DES-EDE3-CBC').decrypt
|
19
|
+
cipher.key = Digest::SHA1.hexdigest(cipher_key)[0..23]
|
20
|
+
s = [encrypted_value].pack("H*").unpack("C*").pack("c*")
|
21
|
+
|
22
|
+
ctx[:decrypted_value] = cipher.update(s) + cipher.final
|
23
|
+
end
|
24
|
+
end # Cipher
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Trailblazer
|
2
|
+
class Endpoint::Protocol
|
3
|
+
# Deserialize incoming state.
|
4
|
+
# Serialize outgoing state.
|
5
|
+
# What else?
|
6
|
+
module Controller
|
7
|
+
module_function
|
8
|
+
|
9
|
+
def decrypt?(ctx, encrypted_resume_data:, **)
|
10
|
+
encrypted_resume_data
|
11
|
+
end
|
12
|
+
|
13
|
+
def deserialize_resume_data(ctx, decrypted_value:, **)
|
14
|
+
ctx[:resume_data] = JSON.parse(decrypted_value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def deserialize_process_model?(ctx, process_model_from_resume_data:, **)
|
18
|
+
process_model_from_resume_data
|
19
|
+
end
|
20
|
+
|
21
|
+
def deserialize_process_model_id(ctx, resume_data:, **)
|
22
|
+
ctx[:process_model_id] = resume_data["id"] # DISCUSS: overriding {:process_model_id}?
|
23
|
+
end
|
24
|
+
|
25
|
+
def encrypt?(ctx, domain_ctx:, **)
|
26
|
+
ctx[:suspend_data] = domain_ctx[:suspend_data]
|
27
|
+
end
|
28
|
+
|
29
|
+
def serialize_suspend_data(ctx, suspend_data:, **)
|
30
|
+
ctx[:serialized_suspend_data] = JSON.dump(suspend_data)
|
31
|
+
end
|
32
|
+
|
33
|
+
def copy_suspend_data_to_endpoint_ctx(ctx, domain_ctx:, **)
|
34
|
+
ctx[:suspend_data] = domain_ctx[:suspend_data] # FIXME: use {#insert_copy_from_domain_ctx!}
|
35
|
+
end
|
36
|
+
|
37
|
+
# FIXME: use Model() mechanics.
|
38
|
+
def deserialize_process_model_id_from_resume_data(ctx, resume_data:, **)
|
39
|
+
# DISCUSS: should we warn when overriding an existing {process_model_id}?
|
40
|
+
ctx[:process_model_id] = resume_data["id"] # DISCUSS: overriding {:process_model_id}? # FIXME: stolen from Advance___::Controller
|
41
|
+
end
|
42
|
+
|
43
|
+
def insert_deserialize_steps!(activity, deserialize_before: :policy)
|
44
|
+
activity.module_eval do
|
45
|
+
step Controller.method(:decrypt?), id: :decrypt?, before: deserialize_before # error out if no serialized_resume_data given.
|
46
|
+
step Controller::Cipher.method(:decrypt_value), id: :decrypt,
|
47
|
+
input: {cipher_key: :cipher_key, encrypted_resume_data: :encrypted_value} , before: deserialize_before,
|
48
|
+
# Output(:failure) => Track(:success),
|
49
|
+
Output(:success) => Path(connect_to: Track(:success), track_color: :deserialize, before: deserialize_before) do # usually, Path goes into {policy}
|
50
|
+
|
51
|
+
step Controller.method(:deserialize_resume_data), id: :deserialize_resume_data
|
52
|
+
# DISCUSS: unmarshall?
|
53
|
+
# step Controller.method(:deserialize_process_model_id?), id: :deserialize_process_model_id?, activity.Output(Trailblazer::Activity::Left, :failure) => activity.Id(around_activity_id)
|
54
|
+
# step Controller.method(:deserialize_process_model_id), id: :deserialize_process_model_id
|
55
|
+
|
56
|
+
step ->(*) { true } # FIXME: otherwise we can't insert an element AFTER :deserialize_resume_data
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def insert_serialize_steps!(activity, serialize_after: :domain_activity)
|
62
|
+
activity.module_eval do
|
63
|
+
# FIXME: reverse order for insertion
|
64
|
+
step Controller::Cipher.method(:encrypt_value), id: :encrypt , after: serialize_after,
|
65
|
+
input: {cipher_key: :cipher_key, serialized_suspend_data: :value}, output: {encrypted_value: :encrypted_suspend_data}
|
66
|
+
step Controller.method(:serialize_suspend_data), id: :serialize_suspend_data , after: serialize_after
|
67
|
+
pass Controller.method(:copy_suspend_data_to_endpoint_ctx), id: :copy_suspend_data_to_endpoint_ctx , after: serialize_after
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
# Insert the "experimental" {find_process_model} steps
|
72
|
+
def insert_find_process_model!(protocol, **options)
|
73
|
+
protocol.module_eval do
|
74
|
+
step Subprocess(FindProcessModel), Output(:failure) => End(:not_found),
|
75
|
+
id: :find_process_model,
|
76
|
+
**options
|
77
|
+
# after: :authenticate
|
78
|
+
end
|
79
|
+
|
80
|
+
insert_copy_to_domain_ctx!(protocol, {:process_model => :model})
|
81
|
+
end
|
82
|
+
|
83
|
+
def insert_copy_to_domain_ctx!(protocol, variables, before: :domain_activity) # FIXME: `:before` untested!
|
84
|
+
variables.each do |original_name, domain_name|
|
85
|
+
protocol.module_eval do
|
86
|
+
pass ->(ctx, domain_ctx:, **) { domain_ctx[domain_name] = ctx[original_name] if ctx.key?(original_name) },
|
87
|
+
id: :"copy_[#{original_name.inspect}]_to_domain_ctx[#{domain_name.inspect}]", before: before
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def insert_copy_from_domain_ctx!(protocol, variables, after: :domain_activity) # FIXME: `:after` untested!
|
93
|
+
variables.each do |domain_name, endpoint_name|
|
94
|
+
protocol.module_eval do
|
95
|
+
pass ->(ctx, domain_ctx:, **) { ctx[endpoint_name] = domain_ctx[domain_name] if domain_ctx.key?(domain_name) },
|
96
|
+
id: :"copy_[#{endpoint_name.inspect}]_from_domain_ctx[#{domain_name.inspect}]", after: after
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class Trailblazer::Endpoint::Protocol
|
2
|
+
class FindProcessModel < Trailblazer::Activity::Railway
|
3
|
+
# step :find_process_model?, Output(:failure) => Id("End.success")
|
4
|
+
step :find_process_model#, Output(:failure) => End(:not_found) # DISCUSS: currently, {End.failure} implies {not_found}.
|
5
|
+
|
6
|
+
# DISCUSS: should the implementation remain in {Activity}?
|
7
|
+
# def find_process_model?(ctx, find_process_model:, **)
|
8
|
+
# find_process_model
|
9
|
+
# end
|
10
|
+
|
11
|
+
def find_process_model(ctx, process_model_class:, process_model_id:, **)
|
12
|
+
ctx[:process_model] = process_model_class.find_by(id: process_model_id)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -24,7 +24,7 @@ module Trailblazer
|
|
24
24
|
|
25
25
|
step :authenticate, Output(:failure) => _Path(semantic: :not_authenticated) do
|
26
26
|
# step :handle_not_authenticated
|
27
|
-
|
27
|
+
end
|
28
28
|
|
29
29
|
step :policy, Output(:failure) => _Path(semantic: :not_authorized) do # user from cookie, etc
|
30
30
|
# step :handle_not_authorized
|
@@ -113,7 +113,6 @@ module Trailblazer
|
|
113
113
|
[[Trailblazer::Activity::TaskWrap::Pipeline.method(:insert_after), "task_wrap.call_task", ["endpoint.end_signal", method(:terminus_handler)]]]
|
114
114
|
end
|
115
115
|
end
|
116
|
-
|
117
|
-
end
|
116
|
+
end # Protocol
|
118
117
|
end
|
119
118
|
end
|
data/lib/trailblazer/endpoint.rb
CHANGED
@@ -2,7 +2,12 @@ module Trailblazer
|
|
2
2
|
class Endpoint
|
3
3
|
# Create an {Endpoint} class with the provided adapter and protocol.
|
4
4
|
# This builder also sets up taskWrap filters around the {domain_activity} execution.
|
5
|
-
def self.build(protocol:, adapter:, domain_activity:, scope_domain_ctx: true,
|
5
|
+
def self.build(protocol:, adapter:, domain_activity:, scope_domain_ctx: true, protocol_block: ->(*) { Hash.new },
|
6
|
+
serialize: false, # TODO: plug-in, not hardcoded!
|
7
|
+
deserialize: false,# TODO: plug-in, not hardcoded!
|
8
|
+
find_process_model: false, # TODO: plug-in, not hardcoded!
|
9
|
+
deserialize_process_model_id_from_resume_data: false # TODO: plug-in, not hardcoded!
|
10
|
+
)
|
6
11
|
# special considerations around the {domain_activity} and its taskWrap:
|
7
12
|
#
|
8
13
|
# 1. domain_ctx_filter (e.g. to filter {current_user})
|
@@ -19,14 +24,41 @@ module Trailblazer
|
|
19
24
|
# scoping: {:domain_ctx} becomes ctx
|
20
25
|
extensions_options.merge!(Endpoint.options_for_scope_domain_ctx) if scope_domain_ctx # TODO: test flag
|
21
26
|
|
27
|
+
app_protocol = build_protocol(protocol, domain_activity: domain_activity, extensions_options: extensions_options, protocol_block: protocol_block, serialize: serialize, deserialize: deserialize,
|
28
|
+
find_process_model: find_process_model, deserialize_process_model_id_from_resume_data: deserialize_process_model_id_from_resume_data
|
29
|
+
)
|
30
|
+
|
31
|
+
# puts Trailblazer::Developer.render(app_protocol)
|
32
|
+
|
33
|
+
Class.new(adapter) do
|
34
|
+
step(Subprocess(app_protocol), {inherit: true, id: :protocol, replace: :protocol})
|
35
|
+
end # app_adapter
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# @private
|
40
|
+
def self.build_protocol(protocol, domain_activity:, extensions_options:, protocol_block:, serialize:, deserialize:, find_process_model:, deserialize_process_model_id_from_resume_data:)
|
41
|
+
Class.new(protocol) do
|
42
|
+
if serialize
|
43
|
+
Protocol::Controller.insert_serialize_steps!(self)
|
44
|
+
end
|
45
|
+
|
46
|
+
if deserialize
|
47
|
+
Protocol::Controller.insert_deserialize_steps!(self)
|
48
|
+
end
|
49
|
+
|
50
|
+
if serialize || deserialize
|
51
|
+
Protocol::Controller.insert_copy_to_domain_ctx!(self, {:resume_data => :resume_data})
|
52
|
+
end
|
22
53
|
|
23
|
-
|
24
|
-
|
54
|
+
if find_process_model
|
55
|
+
Protocol::Controller.insert_find_process_model!(self, before: :policy) # TODO: test before: :policy
|
56
|
+
end
|
25
57
|
|
26
|
-
|
27
|
-
|
58
|
+
if deserialize_process_model_id_from_resume_data
|
59
|
+
pass Protocol::Controller.method(:deserialize_process_model_id_from_resume_data), after: :deserialize_resume_data, magnetic_to: :deserialize, Output(:success) => Track(:deserialize)
|
60
|
+
end
|
28
61
|
|
29
|
-
app_protocol = Class.new(protocol) do
|
30
62
|
step(Subprocess(domain_activity), {inherit: true, id: :domain_activity, replace: :domain_activity,
|
31
63
|
|
32
64
|
# FIXME: where does this go?
|
@@ -35,13 +67,6 @@ module Trailblazer
|
|
35
67
|
merge(instance_exec(&protocol_block)) # the block is evaluated in the {Protocol} context.
|
36
68
|
)
|
37
69
|
end
|
38
|
-
|
39
|
-
# puts Trailblazer::Developer.render(app_protocol)
|
40
|
-
|
41
|
-
Class.new(adapter) do
|
42
|
-
step(Subprocess(app_protocol), {inherit: true, id: :protocol, replace: :protocol})
|
43
|
-
end # app_adapter
|
44
|
-
|
45
70
|
end
|
46
71
|
|
47
72
|
def self.options_for_scope_domain_ctx()
|
@@ -51,16 +76,6 @@ module Trailblazer
|
|
51
76
|
}
|
52
77
|
end
|
53
78
|
|
54
|
-
def self.domain_ctx_filter(variables)
|
55
|
-
->(_ctx, ((ctx, a), b)) do # taskWrap interface
|
56
|
-
variables.each do |variable|
|
57
|
-
ctx[:domain_ctx][variable] = ctx[variable]
|
58
|
-
end
|
59
|
-
|
60
|
-
[_ctx, [[ctx, a], b]]
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
79
|
# Runtime
|
65
80
|
# Invokes the endpoint for you and runs one of the three outcome blocks.
|
66
81
|
def self.with_or_etc(activity, args, failure_block:, success_block:, protocol_failure_block:, invoke: Trailblazer::Activity::TaskWrap.method(:invoke))
|
@@ -116,7 +131,7 @@ module Trailblazer
|
|
116
131
|
end
|
117
132
|
|
118
133
|
# FIXME: name will change! this is for controllers, only!
|
119
|
-
def self.advance_from_controller(endpoint, success_block:, failure_block:, protocol_failure_block
|
134
|
+
def self.advance_from_controller(endpoint, success_block:, failure_block:, protocol_failure_block:, **argument_options)
|
120
135
|
args = Trailblazer::Endpoint.arguments_for(argument_options)
|
121
136
|
|
122
137
|
signal, (ctx, _ ) = Trailblazer::Endpoint.with_or_etc(
|
@@ -146,3 +161,6 @@ require "trailblazer/endpoint/adapter"
|
|
146
161
|
require "trailblazer/endpoint/dsl"
|
147
162
|
require "trailblazer/endpoint/controller"
|
148
163
|
require "trailblazer/endpoint/options"
|
164
|
+
require "trailblazer/endpoint/protocol/controller"
|
165
|
+
require "trailblazer/endpoint/protocol/find_process_model"
|
166
|
+
require "trailblazer/endpoint/protocol/cipher"
|
@@ -58,7 +58,8 @@ class DocsControllerTest < Minitest::Spec
|
|
58
58
|
include T.def_steps(:authenticate, :policy)
|
59
59
|
end
|
60
60
|
|
61
|
-
endpoint protocol: Protocol, adapter: Trailblazer::Endpoint::Adapter::Web,
|
61
|
+
endpoint protocol: Protocol, adapter: Trailblazer::Endpoint::Adapter::Web,
|
62
|
+
scope_domain_ctx: true
|
62
63
|
end
|
63
64
|
|
64
65
|
class HtmlController < ApplicationController
|
data/test/rails-app/Gemfile
CHANGED
@@ -13,7 +13,13 @@ gem 'sqlite3', '~> 1.4'
|
|
13
13
|
# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible
|
14
14
|
# gem 'rack-cors'
|
15
15
|
|
16
|
-
gem "trailblazer-operation"
|
16
|
+
# gem "trailblazer-operation"
|
17
|
+
gem "trailblazer-operation", path: "../../../trailblazer-operation"
|
18
|
+
gem "trailblazer-context", path: "../../../trailblazer-context"
|
19
|
+
gem "trailblazer-activity-dsl-linear", path: "../../../trailblazer-activity-dsl-linear"
|
20
|
+
gem "trailblazer-activity", path: "../../../trailblazer-activity"
|
21
|
+
|
22
|
+
|
17
23
|
gem "trailblazer-endpoint", path: "../../."
|
18
24
|
gem "jwt"
|
19
25
|
gem "multi_json"
|
@@ -21,3 +27,9 @@ gem "minitest-line"
|
|
21
27
|
gem "trailblazer-cells"
|
22
28
|
gem "cells-erb"
|
23
29
|
gem "cells-rails"
|
30
|
+
|
31
|
+
|
32
|
+
# FIXME
|
33
|
+
# gem "trailblazer-workflow", path: "../../../trailblazer-workflow"
|
34
|
+
# gem "trailblazer-activity-dsl-linear", path: "../../../trailblazer-activity-dsl-linear"
|
35
|
+
# gem "trailblazer-activity-dsl-linear", ">= 0.3.4"
|
data/test/rails-app/Gemfile.lock
CHANGED
@@ -1,62 +1,89 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../../trailblazer-activity-dsl-linear
|
3
|
+
specs:
|
4
|
+
trailblazer-activity-dsl-linear (0.5.0)
|
5
|
+
trailblazer-activity (>= 0.13.0, < 1.0.0)
|
6
|
+
|
7
|
+
PATH
|
8
|
+
remote: ../../../trailblazer-activity
|
9
|
+
specs:
|
10
|
+
trailblazer-activity (0.13.0)
|
11
|
+
trailblazer-context (~> 0.5.0)
|
12
|
+
trailblazer-option (~> 0.1.0)
|
13
|
+
|
14
|
+
PATH
|
15
|
+
remote: ../../../trailblazer-context
|
16
|
+
specs:
|
17
|
+
trailblazer-context (0.5.0)
|
18
|
+
hashie (>= 3.0.0)
|
19
|
+
|
20
|
+
PATH
|
21
|
+
remote: ../../../trailblazer-operation
|
22
|
+
specs:
|
23
|
+
trailblazer-operation (0.7.5)
|
24
|
+
trailblazer-activity (>= 0.12.2, < 1.0.0)
|
25
|
+
trailblazer-activity-dsl-linear (>= 0.4.1, < 1.0.0)
|
26
|
+
trailblazer-developer (>= 0.0.21, < 1.0.0)
|
27
|
+
|
1
28
|
PATH
|
2
29
|
remote: ../..
|
3
30
|
specs:
|
4
|
-
trailblazer-endpoint (0.0.
|
5
|
-
trailblazer-activity-dsl-linear (>= 0.
|
31
|
+
trailblazer-endpoint (0.0.9)
|
32
|
+
trailblazer-activity-dsl-linear (>= 0.5.0, < 0.6.0)
|
6
33
|
|
7
34
|
GEM
|
8
35
|
remote: https://rubygems.org/
|
9
36
|
specs:
|
10
|
-
actioncable (6.0.3.
|
11
|
-
actionpack (= 6.0.3.
|
37
|
+
actioncable (6.0.3.4)
|
38
|
+
actionpack (= 6.0.3.4)
|
12
39
|
nio4r (~> 2.0)
|
13
40
|
websocket-driver (>= 0.6.1)
|
14
|
-
actionmailbox (6.0.3.
|
15
|
-
actionpack (= 6.0.3.
|
16
|
-
activejob (= 6.0.3.
|
17
|
-
activerecord (= 6.0.3.
|
18
|
-
activestorage (= 6.0.3.
|
19
|
-
activesupport (= 6.0.3.
|
41
|
+
actionmailbox (6.0.3.4)
|
42
|
+
actionpack (= 6.0.3.4)
|
43
|
+
activejob (= 6.0.3.4)
|
44
|
+
activerecord (= 6.0.3.4)
|
45
|
+
activestorage (= 6.0.3.4)
|
46
|
+
activesupport (= 6.0.3.4)
|
20
47
|
mail (>= 2.7.1)
|
21
|
-
actionmailer (6.0.3.
|
22
|
-
actionpack (= 6.0.3.
|
23
|
-
actionview (= 6.0.3.
|
24
|
-
activejob (= 6.0.3.
|
48
|
+
actionmailer (6.0.3.4)
|
49
|
+
actionpack (= 6.0.3.4)
|
50
|
+
actionview (= 6.0.3.4)
|
51
|
+
activejob (= 6.0.3.4)
|
25
52
|
mail (~> 2.5, >= 2.5.4)
|
26
53
|
rails-dom-testing (~> 2.0)
|
27
|
-
actionpack (6.0.3.
|
28
|
-
actionview (= 6.0.3.
|
29
|
-
activesupport (= 6.0.3.
|
54
|
+
actionpack (6.0.3.4)
|
55
|
+
actionview (= 6.0.3.4)
|
56
|
+
activesupport (= 6.0.3.4)
|
30
57
|
rack (~> 2.0, >= 2.0.8)
|
31
58
|
rack-test (>= 0.6.3)
|
32
59
|
rails-dom-testing (~> 2.0)
|
33
60
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
34
|
-
actiontext (6.0.3.
|
35
|
-
actionpack (= 6.0.3.
|
36
|
-
activerecord (= 6.0.3.
|
37
|
-
activestorage (= 6.0.3.
|
38
|
-
activesupport (= 6.0.3.
|
61
|
+
actiontext (6.0.3.4)
|
62
|
+
actionpack (= 6.0.3.4)
|
63
|
+
activerecord (= 6.0.3.4)
|
64
|
+
activestorage (= 6.0.3.4)
|
65
|
+
activesupport (= 6.0.3.4)
|
39
66
|
nokogiri (>= 1.8.5)
|
40
|
-
actionview (6.0.3.
|
41
|
-
activesupport (= 6.0.3.
|
67
|
+
actionview (6.0.3.4)
|
68
|
+
activesupport (= 6.0.3.4)
|
42
69
|
builder (~> 3.1)
|
43
70
|
erubi (~> 1.4)
|
44
71
|
rails-dom-testing (~> 2.0)
|
45
72
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
46
|
-
activejob (6.0.3.
|
47
|
-
activesupport (= 6.0.3.
|
73
|
+
activejob (6.0.3.4)
|
74
|
+
activesupport (= 6.0.3.4)
|
48
75
|
globalid (>= 0.3.6)
|
49
|
-
activemodel (6.0.3.
|
50
|
-
activesupport (= 6.0.3.
|
51
|
-
activerecord (6.0.3.
|
52
|
-
activemodel (= 6.0.3.
|
53
|
-
activesupport (= 6.0.3.
|
54
|
-
activestorage (6.0.3.
|
55
|
-
actionpack (= 6.0.3.
|
56
|
-
activejob (= 6.0.3.
|
57
|
-
activerecord (= 6.0.3.
|
76
|
+
activemodel (6.0.3.4)
|
77
|
+
activesupport (= 6.0.3.4)
|
78
|
+
activerecord (6.0.3.4)
|
79
|
+
activemodel (= 6.0.3.4)
|
80
|
+
activesupport (= 6.0.3.4)
|
81
|
+
activestorage (6.0.3.4)
|
82
|
+
actionpack (= 6.0.3.4)
|
83
|
+
activejob (= 6.0.3.4)
|
84
|
+
activerecord (= 6.0.3.4)
|
58
85
|
marcel (~> 0.3.1)
|
59
|
-
activesupport (6.0.3.
|
86
|
+
activesupport (6.0.3.4)
|
60
87
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
61
88
|
i18n (>= 0.7, < 2)
|
62
89
|
minitest (~> 5.1)
|
@@ -71,7 +98,7 @@ GEM
|
|
71
98
|
cells-erb (0.1.0)
|
72
99
|
cells (~> 4.0)
|
73
100
|
erbse (>= 0.1.1)
|
74
|
-
cells-rails (0.1.
|
101
|
+
cells-rails (0.1.3)
|
75
102
|
actionpack (>= 5.0)
|
76
103
|
cells (>= 4.1.6, < 5.0.0)
|
77
104
|
concurrent-ruby (1.1.7)
|
@@ -82,15 +109,15 @@ GEM
|
|
82
109
|
declarative-option (0.1.0)
|
83
110
|
erbse (0.1.4)
|
84
111
|
temple
|
85
|
-
erubi (1.
|
112
|
+
erubi (1.10.0)
|
86
113
|
globalid (0.4.2)
|
87
114
|
activesupport (>= 4.2.0)
|
88
|
-
hashie (
|
115
|
+
hashie (5.0.0)
|
89
116
|
hirb (0.7.3)
|
90
|
-
i18n (1.8.
|
117
|
+
i18n (1.8.7)
|
91
118
|
concurrent-ruby (~> 1.0)
|
92
119
|
jwt (2.2.2)
|
93
|
-
loofah (2.
|
120
|
+
loofah (2.8.0)
|
94
121
|
crass (~> 1.0.2)
|
95
122
|
nokogiri (>= 1.5.9)
|
96
123
|
mail (2.7.1)
|
@@ -100,52 +127,56 @@ GEM
|
|
100
127
|
method_source (1.0.0)
|
101
128
|
mimemagic (0.3.5)
|
102
129
|
mini_mime (1.0.2)
|
103
|
-
mini_portile2 (2.
|
104
|
-
minitest (5.14.
|
130
|
+
mini_portile2 (2.5.0)
|
131
|
+
minitest (5.14.3)
|
105
132
|
minitest-line (0.6.5)
|
106
133
|
minitest (~> 5.0)
|
107
134
|
multi_json (1.15.0)
|
108
|
-
nio4r (2.5.
|
109
|
-
nokogiri (1.
|
110
|
-
mini_portile2 (~> 2.
|
135
|
+
nio4r (2.5.4)
|
136
|
+
nokogiri (1.11.1)
|
137
|
+
mini_portile2 (~> 2.5.0)
|
138
|
+
racc (~> 1.4)
|
139
|
+
nokogiri (1.11.1-x86_64-linux)
|
140
|
+
racc (~> 1.4)
|
141
|
+
racc (1.5.2)
|
111
142
|
rack (2.2.3)
|
112
143
|
rack-test (1.1.0)
|
113
144
|
rack (>= 1.0, < 3)
|
114
|
-
rails (6.0.3.
|
115
|
-
actioncable (= 6.0.3.
|
116
|
-
actionmailbox (= 6.0.3.
|
117
|
-
actionmailer (= 6.0.3.
|
118
|
-
actionpack (= 6.0.3.
|
119
|
-
actiontext (= 6.0.3.
|
120
|
-
actionview (= 6.0.3.
|
121
|
-
activejob (= 6.0.3.
|
122
|
-
activemodel (= 6.0.3.
|
123
|
-
activerecord (= 6.0.3.
|
124
|
-
activestorage (= 6.0.3.
|
125
|
-
activesupport (= 6.0.3.
|
145
|
+
rails (6.0.3.4)
|
146
|
+
actioncable (= 6.0.3.4)
|
147
|
+
actionmailbox (= 6.0.3.4)
|
148
|
+
actionmailer (= 6.0.3.4)
|
149
|
+
actionpack (= 6.0.3.4)
|
150
|
+
actiontext (= 6.0.3.4)
|
151
|
+
actionview (= 6.0.3.4)
|
152
|
+
activejob (= 6.0.3.4)
|
153
|
+
activemodel (= 6.0.3.4)
|
154
|
+
activerecord (= 6.0.3.4)
|
155
|
+
activestorage (= 6.0.3.4)
|
156
|
+
activesupport (= 6.0.3.4)
|
126
157
|
bundler (>= 1.3.0)
|
127
|
-
railties (= 6.0.3.
|
158
|
+
railties (= 6.0.3.4)
|
128
159
|
sprockets-rails (>= 2.0.0)
|
129
160
|
rails-dom-testing (2.0.3)
|
130
161
|
activesupport (>= 4.2.0)
|
131
162
|
nokogiri (>= 1.6)
|
132
163
|
rails-html-sanitizer (1.3.0)
|
133
164
|
loofah (~> 2.3)
|
134
|
-
railties (6.0.3.
|
135
|
-
actionpack (= 6.0.3.
|
136
|
-
activesupport (= 6.0.3.
|
165
|
+
railties (6.0.3.4)
|
166
|
+
actionpack (= 6.0.3.4)
|
167
|
+
activesupport (= 6.0.3.4)
|
137
168
|
method_source
|
138
169
|
rake (>= 0.8.7)
|
139
170
|
thor (>= 0.20.3, < 2.0)
|
140
|
-
rake (13.0.
|
141
|
-
representable (3.
|
171
|
+
rake (13.0.3)
|
172
|
+
representable (3.1.1)
|
142
173
|
declarative (< 0.1.0)
|
143
|
-
|
174
|
+
trailblazer-option (>= 0.1.1, < 0.2.0)
|
144
175
|
uber (< 0.2.0)
|
145
176
|
sprockets (4.0.2)
|
146
177
|
concurrent-ruby (~> 1.0)
|
147
178
|
rack (> 1, < 3)
|
148
|
-
sprockets-rails (3.2.
|
179
|
+
sprockets-rails (3.2.2)
|
149
180
|
actionpack (>= 4.0)
|
150
181
|
activesupport (>= 4.0)
|
151
182
|
sprockets (>= 3.0.0)
|
@@ -154,33 +185,25 @@ GEM
|
|
154
185
|
thor (1.0.1)
|
155
186
|
thread_safe (0.3.6)
|
156
187
|
tilt (2.0.10)
|
157
|
-
trailblazer-activity (0.11.3)
|
158
|
-
trailblazer-context (>= 0.3.1, < 0.4.0)
|
159
|
-
trailblazer-activity-dsl-linear (0.3.2)
|
160
|
-
trailblazer-activity (>= 0.11.2, < 1.0.0)
|
161
188
|
trailblazer-cells (0.0.3)
|
162
189
|
cells (>= 4.1.0.rc1, < 5.0.0)
|
163
|
-
trailblazer-
|
164
|
-
hashie (~> 4.1)
|
165
|
-
trailblazer-developer (0.0.16)
|
190
|
+
trailblazer-developer (0.0.22)
|
166
191
|
hirb
|
167
|
-
representable
|
168
|
-
trailblazer-activity (>= 0.
|
169
|
-
trailblazer-activity-dsl-linear
|
170
|
-
trailblazer-
|
171
|
-
|
172
|
-
trailblazer-activity-dsl-linear (>= 0.3.2, < 1.0.0)
|
173
|
-
trailblazer-developer (>= 0.0.8)
|
174
|
-
tzinfo (1.2.7)
|
192
|
+
representable (>= 3.1.1, < 4.0.0)
|
193
|
+
trailblazer-activity (>= 0.12.2, < 1.0.0)
|
194
|
+
trailblazer-activity-dsl-linear (>= 0.4.1, < 1.0.0)
|
195
|
+
trailblazer-option (0.1.2)
|
196
|
+
tzinfo (1.2.9)
|
175
197
|
thread_safe (~> 0.1)
|
176
198
|
uber (0.1.0)
|
177
199
|
websocket-driver (0.7.3)
|
178
200
|
websocket-extensions (>= 0.1.0)
|
179
201
|
websocket-extensions (0.1.5)
|
180
|
-
zeitwerk (2.4.
|
202
|
+
zeitwerk (2.4.2)
|
181
203
|
|
182
204
|
PLATFORMS
|
183
205
|
ruby
|
206
|
+
x86_64-linux
|
184
207
|
|
185
208
|
DEPENDENCIES
|
186
209
|
cells-erb
|
@@ -190,9 +213,12 @@ DEPENDENCIES
|
|
190
213
|
multi_json
|
191
214
|
rails (~> 6.0.3, >= 6.0.3.1)
|
192
215
|
sqlite3 (~> 1.4)
|
216
|
+
trailblazer-activity!
|
217
|
+
trailblazer-activity-dsl-linear!
|
193
218
|
trailblazer-cells
|
219
|
+
trailblazer-context!
|
194
220
|
trailblazer-endpoint!
|
195
|
-
trailblazer-operation
|
221
|
+
trailblazer-operation!
|
196
222
|
|
197
223
|
BUNDLED WITH
|
198
|
-
2.
|
224
|
+
2.2.11
|
@@ -30,12 +30,14 @@ class ApplicationController::Web < ApplicationController
|
|
30
30
|
def policy(ctx, domain_ctx:, **)
|
31
31
|
Policy.(domain_ctx)
|
32
32
|
end
|
33
|
+
|
34
|
+
Trailblazer::Endpoint::Protocol::Controller.insert_copy_to_domain_ctx!(self, {:current_user => :current_user})
|
35
|
+
Trailblazer::Endpoint::Protocol::Controller.insert_copy_from_domain_ctx!(self, {:model => :process_model})
|
33
36
|
end
|
34
37
|
#:protocol end
|
35
38
|
Policy = ->(domain_ctx) { domain_ctx[:params][:policy] == "false" ? false : true }
|
36
39
|
#~gskip end
|
37
|
-
endpoint protocol: Protocol, adapter: Trailblazer::Endpoint::Adapter::Web
|
38
|
-
domain_ctx_filter: ApplicationController.current_user_in_domain_ctx
|
40
|
+
endpoint protocol: Protocol, adapter: Trailblazer::Endpoint::Adapter::Web
|
39
41
|
end
|
40
42
|
#:generic end
|
41
43
|
|
@@ -81,4 +81,187 @@ end
|
|
81
81
|
end
|
82
82
|
#:protocol_failure end
|
83
83
|
end
|
84
|
+
|
85
|
+
# {:process_model} is copied from {domain_ctx[:model]} via {#insert_copy_from_domain_ctx!}.
|
86
|
+
class Create1Controller < SongsController
|
87
|
+
def 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
|
212
|
+
end
|
213
|
+
|
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
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
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
|
265
|
+
end
|
266
|
+
end
|
84
267
|
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
|
@@ -15,4 +15,15 @@ Rails.application.routes.draw do
|
|
15
15
|
get "/v1/songs_with_options/:id", to: "api/v1/songs_controller/with_options#show"
|
16
16
|
|
17
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"
|
18
29
|
end
|
@@ -70,6 +70,80 @@ class SongsControllerTest < ActionDispatch::IntegrationTest
|
|
70
70
|
assert_equal "wrong login, app crashed", response.body
|
71
71
|
end
|
72
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
|
+
|
73
147
|
test "sign_in" do
|
74
148
|
# wrong credentials
|
75
149
|
post "/auth/sign_in", params: {}
|
@@ -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.5.0", "< 0.6.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.10
|
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: 2022-02-04 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.5.0
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: 0.
|
22
|
+
version: 0.6.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.5.0
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: 0.
|
32
|
+
version: 0.6.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
|
@@ -184,7 +187,7 @@ files:
|
|
184
187
|
- test/rails-app/tmp/.keep
|
185
188
|
- test/test_helper.rb
|
186
189
|
- trailblazer-endpoint.gemspec
|
187
|
-
homepage: http://trailblazer.to/
|
190
|
+
homepage: http://trailblazer.to/
|
188
191
|
licenses:
|
189
192
|
- LGPL-3.0
|
190
193
|
metadata: {}
|
@@ -203,8 +206,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
203
206
|
- !ruby/object:Gem::Version
|
204
207
|
version: '0'
|
205
208
|
requirements: []
|
206
|
-
|
207
|
-
rubygems_version: 2.7.3
|
209
|
+
rubygems_version: 3.2.3
|
208
210
|
signing_key:
|
209
211
|
specification_version: 4
|
210
212
|
summary: Endpoints handle authentication, policies, run your domain operation and
|