Skip to content

Commit

Permalink
Advance now has a invalid_event terminus instead of not_authorized.
Browse files Browse the repository at this point in the history
  • Loading branch information
apotonick committed Apr 3, 2024
1 parent 01a555d commit 61017ae
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 26 deletions.
36 changes: 14 additions & 22 deletions lib/trailblazer/workflow/advance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ module Workflow
# TODO:
# * wire the event_valid? step to {invalid_state} terminus and handle that differently in the endpoint.
class Advance < Trailblazer::Activity::Railway
step task: :compute_catch_event_tuple
terminus :invalid_event

step task: :compute_catch_event_tuple, Output(:failure) => Track(:invalid_event)
step task: :find_position_options
step task: :event_valid?, Output(:failure) => End(:not_authorized)
step task: :advance

def compute_catch_event_tuple((ctx, flow_options), **)
Expand All @@ -19,16 +20,25 @@ def compute_catch_event_tuple((ctx, flow_options), **)
# it's probably cleaner to have a dedicated state_table.
# it should compute activity/start_task (catch event ID) from the event label.
planned_iteration = iteration_set.to_a.find { |iteration| iteration.event_label == event_label }
return Activity::Left, [ctx, flow_options] unless planned_iteration

# TODO: those positions could also be passed in manually, without using an Iteration::Set.
position_options_FIXME = position_options_from_iteration(planned_iteration) # :start_task_position and :start_positions
catch_event_tuple = Introspect::Iteration::Set::Serialize.id_tuple_for(*position_options_FIXME[:start_task_position].to_a, lanes_cfg: flow_options[:lanes]) # TODO: this should be done via state_table.

flow_options[:catch_event_tuple] = catch_event_tuple
flow_options[:catch_event_tuple] = catch_event_tuple

return Activity::Right, [ctx, flow_options]
end

# Computes {:start_task_position} and {:start_positions}.
def position_options_from_iteration(iteration)
{
start_task_position: iteration.start_task_position, # which event to trigger
lane_positions: iteration.start_positions # current position/"state"
}
end

# TODO: Position object with "tuple", resolved activity/task, comment, lane label, etc. Instead of recomputing it continuously.


Expand All @@ -38,6 +48,7 @@ def find_position_options((ctx, flow_options), **)

_, state_options = state_resolver.(*flow_options[:catch_event_tuple], [ctx], **ctx.to_hash)

# raise unless state_options # FIXME.

lanes_cfg = flow_options[:lanes]
fixme_tuples = state_options[:suspend_tuples].collect { |tuple| {"tuple" => tuple} }
Expand All @@ -53,17 +64,6 @@ def find_position_options((ctx, flow_options), **)
return Activity::Right, [ctx, flow_options]
end

def event_valid?((ctx, flow_options), **)
# position_options = flow_options[:position_options]
# state_guards = flow_options[:state_guards]

# result = state_guards.(ctx, start_task_position: position_options[:start_task_position])

result = flow_options[:position_options][:lane_positions].is_a? Trailblazer::Workflow::Collaboration::Positions # FIXME

return result ? Activity::Right : Activity::Left, [ctx, flow_options]
end

# Needs Iteration::Set and an {event_label}.
def advance((ctx, flow_options), **circuit_options)
message_flow, position_options, iteration_set = flow_options[:message_flow], flow_options[:position_options], flow_options[:iteration_set]
Expand All @@ -85,14 +85,6 @@ def advance((ctx, flow_options), **circuit_options)
return signal, [ctx, flow_options]#, configuration
end

# Computes {:start_task_position} and {:start_positions}.
def position_options_from_iteration(iteration)
{
start_task_position: iteration.start_task_position, # which event to trigger
lane_positions: iteration.start_positions # current position/"state"
}
end

def return_signal_for(configuration, iteration_set, start_task_position:, **)
collaboration_signal = configuration.signal

Expand Down
41 changes: 38 additions & 3 deletions test/advance_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
require "test_helper"

# high-level unit test that shows the user's interface.
# low-level private test
class AdvanceTest < Minitest::Spec
it "legal, modelless advance" do
iteration_set, lanes_cfg, schema = fixtures()

ctx = {seq: []}
event_label = "☝ ⏵︎Create form" # TODO: "☝ ⏵︎Notify approver"

ctx_for_advance = Trailblazer::Context(ctx, {})
flow_options = {
event_label: event_label,
throw: [],
iteration_set: iteration_set,
**schema.to_h,

lanes: lanes_cfg, # FIXME: why is this not part of schema.to_h?
state_guards: state_guards(), # TODO: rename to {state_resolver}?
}

signal, (ctx, flow_options) = Trailblazer::Workflow::Advance.([ctx_for_advance, flow_options])

configuration = flow_options[:configuration]

assert_equal signal.inspect, %(#<Trailblazer::Activity::End semantic=:success>)


#@ unknown event label
flow_options = flow_options.merge!(event_label: "XXX unknown ~~~")

signal, (ctx, flow_options) = Trailblazer::Workflow::Advance.([ctx_for_advance, flow_options])

assert_equal signal.inspect, %(#<Trailblazer::Activity::End semantic=:invalid_event>)
end
end

# high-level unit test that shows the user's interface.
class AdvanceEndpointTest < Minitest::Spec
include BuildSchema
include DiscoveredStates

Expand Down Expand Up @@ -67,11 +102,11 @@ def policy(*)


advance_protocol = Trailblazer::Endpoint.build_protocol(protocol_template, domain_activity: Trailblazer::Workflow::Advance,
protocol_block: ->(*) { {Trailblazer::Activity::Railway.Output(:not_authorized) => Trailblazer::Activity::Railway.Track(:not_authorized)} }
protocol_block: ->(*) { {Trailblazer::Activity::Railway.Output(:invalid_event) => Trailblazer::Activity::Railway.Track(:not_authorized)} }
)

advance_protocol_with_model = Trailblazer::Endpoint.build_protocol(protocol_template_with_model, domain_activity: Trailblazer::Workflow::Advance,
protocol_block: ->(*) { {Trailblazer::Activity::Railway.Output(:not_authorized) => Trailblazer::Activity::Railway.Track(:not_authorized)} }
protocol_block: ->(*) { {Trailblazer::Activity::Railway.Output(:invalid_event) => Trailblazer::Activity::Railway.Track(:not_authorized)} }
)

# action_protocol = Trailblazer::Endpoint.build_protocol(Protocol, domain_activity: Create, protocol_block: ->(*) { {Output(:not_found) => Track(:not_found)} })
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,6 @@ def fixtures
states, lanes_sorted, lanes_cfg, schema, message_flow = states()
iteration_set = Trailblazer::Workflow::Introspect::Iteration::Set.from_discovered_states(states, lanes_cfg: lanes_cfg)

@fixtures = [iteration_set, lanes_cfg]
@fixtures = [iteration_set, lanes_cfg, schema]
end
end

0 comments on commit 61017ae

Please sign in to comment.