@@ -60,6 +60,7 @@ class ScenarioImport |
||
| 60 | 60 |
description = parsed_data['description'] |
| 61 | 61 |
name = parsed_data['name'] |
| 62 | 62 |
links = parsed_data['links'] |
| 63 |
+ control_links = parsed_data['control_links'] || [] |
|
| 63 | 64 |
tag_fg_color = parsed_data['tag_fg_color'] |
| 64 | 65 |
tag_bg_color = parsed_data['tag_bg_color'] |
| 65 | 66 |
source_url = parsed_data['source_url'].presence || nil |
@@ -87,12 +88,19 @@ class ScenarioImport |
||
| 87 | 88 |
end |
| 88 | 89 |
agent |
| 89 | 90 |
end |
| 91 |
+ |
|
| 90 | 92 |
if success |
| 91 | 93 |
links.each do |link| |
| 92 | 94 |
receiver = created_agents[link['receiver']] |
| 93 | 95 |
source = created_agents[link['source']] |
| 94 | 96 |
receiver.sources << source unless receiver.sources.include?(source) |
| 95 | 97 |
end |
| 98 |
+ |
|
| 99 |
+ control_links.each do |control_link| |
|
| 100 |
+ controller = created_agents[control_link['controller']] |
|
| 101 |
+ control_target = created_agents[control_link['control_target']] |
|
| 102 |
+ controller.control_targets << control_target unless controller.control_targets.include?(control_target) |
|
| 103 |
+ end |
|
| 96 | 104 |
end |
| 97 | 105 |
end |
| 98 | 106 |
|
@@ -20,7 +20,8 @@ class AgentsExporter |
||
| 20 | 20 |
:tag_bg_color => options[:tag_bg_color], |
| 21 | 21 |
:exported_at => Time.now.utc.iso8601, |
| 22 | 22 |
:agents => agents.map { |agent| agent_as_json(agent) },
|
| 23 |
- :links => links |
|
| 23 |
+ :links => links, |
|
| 24 |
+ :control_links => control_links |
|
| 24 | 25 |
} |
| 25 | 26 |
end |
| 26 | 27 |
|
@@ -32,14 +33,26 @@ class AgentsExporter |
||
| 32 | 33 |
agent_ids = agents.map(&:id) |
| 33 | 34 |
|
| 34 | 35 |
contained_links = agents.map.with_index do |agent, index| |
| 35 |
- agent.links_as_source.where(:receiver_id => agent_ids).map do |link| |
|
| 36 |
- { :source => index, :receiver => agent_ids.index(link.receiver_id) }
|
|
| 36 |
+ agent.links_as_source.where(receiver_id: agent_ids).map do |link| |
|
| 37 |
+ { source: index, receiver: agent_ids.index(link.receiver_id) }
|
|
| 37 | 38 |
end |
| 38 | 39 |
end |
| 39 | 40 |
|
| 40 | 41 |
contained_links.flatten.compact |
| 41 | 42 |
end |
| 42 | 43 |
|
| 44 |
+ def control_links |
|
| 45 |
+ agent_ids = agents.map(&:id) |
|
| 46 |
+ |
|
| 47 |
+ contained_controller_links = agents.map.with_index do |agent, index| |
|
| 48 |
+ agent.control_links_as_controller.where(control_target_id: agent_ids).map do |control_link| |
|
| 49 |
+ { controller: index, control_target: agent_ids.index(control_link.control_target_id) }
|
|
| 50 |
+ end |
|
| 51 |
+ end |
|
| 52 |
+ |
|
| 53 |
+ contained_controller_links.flatten.compact |
|
| 54 |
+ end |
|
| 55 |
+ |
|
| 43 | 56 |
def agent_as_json(agent) |
| 44 | 57 |
{
|
| 45 | 58 |
:type => agent.type, |
@@ -25,6 +25,7 @@ describe AgentsExporter do |
||
| 25 | 25 |
expect(data[:tag_bg_color]).to eq(tag_bg_color) |
| 26 | 26 |
expect(Time.parse(data[:exported_at])).to be_within(2).of(Time.now.utc) |
| 27 | 27 |
expect(data[:links]).to eq([{ :source => 0, :receiver => 1 }])
|
| 28 |
+ expect(data[:control_links]).to eq([]) |
|
| 28 | 29 |
expect(data[:agents]).to eq(agent_list.map { |agent| exporter.agent_as_json(agent) })
|
| 29 | 30 |
expect(data[:agents].all? { |agent_json| agent_json[:guid].present? && agent_json[:type].present? && agent_json[:name].present? }).to be_truthy
|
| 30 | 31 |
|
@@ -38,6 +39,13 @@ describe AgentsExporter do |
||
| 38 | 39 |
|
| 39 | 40 |
expect(exporter.as_json[:links]).to eq([{ :source => 0, :receiver => 1 }])
|
| 40 | 41 |
end |
| 42 |
+ |
|
| 43 |
+ it "outputs control links to agents within the incoming set, but not outside it" do |
|
| 44 |
+ agents(:jane_rain_notifier_agent).control_targets = [agents(:jane_weather_agent), agents(:jane_basecamp_agent)] |
|
| 45 |
+ agents(:jane_rain_notifier_agent).save! |
|
| 46 |
+ |
|
| 47 |
+ expect(exporter.as_json[:control_links]).to eq([{ :controller => 1, :control_target => 0 }])
|
|
| 48 |
+ end |
|
| 41 | 49 |
end |
| 42 | 50 |
|
| 43 | 51 |
describe "#filename" do |
@@ -74,7 +74,8 @@ describe ScenarioImport do |
||
| 74 | 74 |
], |
| 75 | 75 |
:links => [ |
| 76 | 76 |
{ :source => 0, :receiver => 1 }
|
| 77 |
- ] |
|
| 77 |
+ ], |
|
| 78 |
+ :control_links => [] |
|
| 78 | 79 |
} |
| 79 | 80 |
end |
| 80 | 81 |
let(:valid_data) { valid_parsed_data.to_json }
|
@@ -226,6 +227,38 @@ describe ScenarioImport do |
||
| 226 | 227 |
scenario_import.import |
| 227 | 228 |
}.to change { users(:bob).agents.count }.by(2)
|
| 228 | 229 |
end |
| 230 |
+ |
|
| 231 |
+ describe "with control links" do |
|
| 232 |
+ it 'creates the links' do |
|
| 233 |
+ valid_parsed_data[:control_links] = [ |
|
| 234 |
+ { :controller => 1, :control_target => 0 }
|
|
| 235 |
+ ] |
|
| 236 |
+ |
|
| 237 |
+ expect {
|
|
| 238 |
+ scenario_import.import |
|
| 239 |
+ }.to change { users(:bob).agents.count }.by(2)
|
|
| 240 |
+ |
|
| 241 |
+ weather_agent = scenario_import.scenario.agents.find_by(:guid => "a-weather-agent") |
|
| 242 |
+ trigger_agent = scenario_import.scenario.agents.find_by(:guid => "a-trigger-agent") |
|
| 243 |
+ |
|
| 244 |
+ expect(trigger_agent.sources).to eq([weather_agent]) |
|
| 245 |
+ expect(weather_agent.controllers.to_a).to eq([trigger_agent]) |
|
| 246 |
+ expect(trigger_agent.control_targets.to_a).to eq([weather_agent]) |
|
| 247 |
+ end |
|
| 248 |
+ |
|
| 249 |
+ it "doesn't crash without any control links" do |
|
| 250 |
+ valid_parsed_data.delete(:control_links) |
|
| 251 |
+ |
|
| 252 |
+ expect {
|
|
| 253 |
+ scenario_import.import |
|
| 254 |
+ }.to change { users(:bob).agents.count }.by(2)
|
|
| 255 |
+ |
|
| 256 |
+ weather_agent = scenario_import.scenario.agents.find_by(:guid => "a-weather-agent") |
|
| 257 |
+ trigger_agent = scenario_import.scenario.agents.find_by(:guid => "a-trigger-agent") |
|
| 258 |
+ |
|
| 259 |
+ expect(trigger_agent.sources).to eq([weather_agent]) |
|
| 260 |
+ end |
|
| 261 |
+ end |
|
| 229 | 262 |
end |
| 230 | 263 |
|
| 231 | 264 |
describe "#generate_diff" do |