require 'rails_helper' shared_examples_for AgentControllerConcern do describe "preconditions" do it "must be satisfied for these shared examples" do expect(agent.user).to eq(users(:bob)) expect(agent.control_action).to eq('run') end end describe "validation" do describe "of action" do it "should allow certain values" do ['run', 'enable', 'disable', '{{ action }}'].each { |action| agent.options['action'] = action expect(agent).to be_valid } end it "should disallow obviously bad values" do ['delete', nil, 1, true].each { |action| agent.options['action'] = action expect(agent).not_to be_valid } end it "should accept 'run' if all target agents are schedulable" do agent.control_targets = [agents(:bob_website_agent)] expect(agent).to be_valid end it "should reject 'run' if targets include an unschedulable agent" do agent.control_targets = [agents(:bob_rain_notifier_agent)] expect(agent).not_to be_valid end it "should not reject 'enable' or 'disable' no matter if targets include an unschedulable agent" do ['enable', 'disable'].each { |action| agent.options['action'] = action agent.control_targets = [agents(:bob_rain_notifier_agent)] expect(agent).to be_valid } end it "should ensure that 'configure_options' exists in options when the action is 'configure'" do agent.options['action'] = 'configure' expect(agent).not_to be_valid agent.options['configure_options'] = {} expect(agent).not_to be_valid agent.options['configure_options'] = { 'key' => 'value' } expect(agent).to be_valid end end end describe 'control_action' do it "returns options['action']" do expect(agent.control_action).to eq('run') ['run', 'enable', 'disable'].each { |action| agent.options['action'] = action expect(agent.control_action).to eq(action) } end it "returns the result of interpolation" do expect(agent.control_action).to eq('run') agent.options['action'] = '{{ "enable" }}' expect(agent.control_action).to eq('enable') end end describe "control!" do before do agent.control_targets = [agents(:bob_website_agent), agents(:bob_weather_agent)] agent.save! end it "should run targets" do control_target_ids = agent.control_targets.map(&:id) allow(Agent).to receive(:async_check).with(anything) { |id| control_target_ids.delete(id) } agent.control! expect(control_target_ids).to be_empty end it "should not run disabled targets" do control_target_ids = agent.control_targets.map(&:id) allow(Agent).to receive(:async_check).with(anything) { |id| control_target_ids.delete(id) } agent.control_targets.last.update!(disabled: true) agent.control! expect(control_target_ids).to eq [agent.control_targets.last.id] end it "should disable targets" do agent.options['action'] = 'disable' agent.save! agent.control_targets.first.update!(disabled: false) agent.control! expect(agent.control_targets.reload).to all(be_disabled) end it "should enable targets" do agent.options['action'] = 'enable' agent.save! agent.control_targets.first.update!(disabled: true) agent.control! expect(agent.control_targets.reload).to all(satisfy { |a| !a.disabled? }) end it "should enable targets and drop pending events" do agent.options['action'] = 'enable' agent.options['drop_pending_events'] = 'true' agent.save! agent.control_targets.first.update!(disabled: true) agent.control! # Find the maximum Event ID, which is what our control_targets should be set to when drop_pending_events is called. maximum_event_id = Event.maximum(:id) # Only test Agents which can_receive_events? because those are the only ones who will have had pending events dropped. agents_that_can_recieve_events = agent.control_targets.to_a.keep_if(&:can_receive_events?) expect(agents_that_can_recieve_events.collect(&:last_checked_event_id)).to all(eq(maximum_event_id)) # Ensure that the control_targets are not disabled. expect(agent.control_targets.reload).to all(satisfy { |a| !a.disabled? }) end it "should configure targets" do agent.options['action'] = 'configure' agent.options['configure_options'] = { 'url' => 'http://some-new-url.com/{{"something" | upcase}}' } agent.save! old_options = agents(:bob_website_agent).options agent.control! expect(agent.control_targets.reload).to all(satisfy { |a| a.options['url'] == 'http://some-new-url.com/SOMETHING' }) expect(agents(:bob_website_agent).reload.options).to eq(old_options.merge('url' => 'http://some-new-url.com/SOMETHING')) end it "should configure targets with nested objects" do agent.control_targets = [ agents(:bob_twitter_user_agent), # does not support a `template` option, but anyway agents(:bob_data_output_agent) ] agent.options['action'] = 'configure' agent.options['configure_options'] = { template: { item: { title: "changed" } } } agent.save! old_options = agents(:bob_data_output_agent).options agent.control! expect(agent.control_targets.reload).to all(satisfy { |a| a.options['template'] && a.options['template']['item'] && (a.options['template']['item']['title'] == 'changed') }) expect(agents(:bob_data_output_agent).reload.options).to eq(old_options.deep_merge(agent.options['configure_options'])) end end end