@@ -0,0 +1,49 @@ |
||
| 1 |
+module Agents |
|
| 2 |
+ class JsonParseAgent < Agent |
|
| 3 |
+ include FormConfigurable |
|
| 4 |
+ |
|
| 5 |
+ cannot_be_scheduled! |
|
| 6 |
+ |
|
| 7 |
+ description <<-MD |
|
| 8 |
+ The JSON Parse Agent parses a JSON string and emits the data in a new event |
|
| 9 |
+ |
|
| 10 |
+ `data` is the JSON to parse. Use [Liquid](https://github.com/cantino/huginn/wiki/Formatting-Events-using-Liquid) templating to specify the JSON string. |
|
| 11 |
+ |
|
| 12 |
+ `data_key` sets the key which contains the parsed JSON data in emitted events |
|
| 13 |
+ MD |
|
| 14 |
+ |
|
| 15 |
+ def default_options |
|
| 16 |
+ {
|
|
| 17 |
+ 'data' => '{{ data }}',
|
|
| 18 |
+ 'data_key' => 'data', |
|
| 19 |
+ } |
|
| 20 |
+ end |
|
| 21 |
+ |
|
| 22 |
+ event_description do |
|
| 23 |
+ "Events will looks like this:\n\n %s" % Utils.pretty_print(interpolated['data_key'] => {parsed: 'object'})
|
|
| 24 |
+ end |
|
| 25 |
+ |
|
| 26 |
+ form_configurable :data |
|
| 27 |
+ form_configurable :data_key |
|
| 28 |
+ |
|
| 29 |
+ def validate_options |
|
| 30 |
+ errors.add(:base, "data needs to be present") if options['data'].blank? |
|
| 31 |
+ errors.add(:base, "data_key needs to be present") if options['data_key'].blank? |
|
| 32 |
+ end |
|
| 33 |
+ |
|
| 34 |
+ def working? |
|
| 35 |
+ received_event_without_error? |
|
| 36 |
+ end |
|
| 37 |
+ |
|
| 38 |
+ def receive(incoming_events) |
|
| 39 |
+ incoming_events.each do |event| |
|
| 40 |
+ begin |
|
| 41 |
+ mo = interpolated(event) |
|
| 42 |
+ create_event payload: { mo['data_key'] => JSON.parse(mo['data']) }
|
|
| 43 |
+ rescue JSON::JSONError => e |
|
| 44 |
+ error("Could not parse JSON: #{e.class} '#{e.message}'")
|
|
| 45 |
+ end |
|
| 46 |
+ end |
|
| 47 |
+ end |
|
| 48 |
+ end |
|
| 49 |
+end |
@@ -0,0 +1,52 @@ |
||
| 1 |
+require 'rails_helper' |
|
| 2 |
+ |
|
| 3 |
+describe Agents::JsonParseAgent do |
|
| 4 |
+ before(:each) do |
|
| 5 |
+ @checker = Agents::JsonParseAgent.new(:name => "somename", :options => Agents::JsonParseAgent.new.default_options) |
|
| 6 |
+ @checker.user = users(:jane) |
|
| 7 |
+ @checker.save! |
|
| 8 |
+ end |
|
| 9 |
+ |
|
| 10 |
+ it "event description does not throw an exception" do |
|
| 11 |
+ expect(@checker.event_description).to include('parsed')
|
|
| 12 |
+ end |
|
| 13 |
+ |
|
| 14 |
+ describe "validating" do |
|
| 15 |
+ before do |
|
| 16 |
+ expect(@checker).to be_valid |
|
| 17 |
+ end |
|
| 18 |
+ |
|
| 19 |
+ it "requires data to be present" do |
|
| 20 |
+ @checker.options['data'] = '' |
|
| 21 |
+ expect(@checker).not_to be_valid |
|
| 22 |
+ end |
|
| 23 |
+ |
|
| 24 |
+ it "requires data_key to be set" do |
|
| 25 |
+ @checker.options['data_key'] = '' |
|
| 26 |
+ expect(@checker).not_to be_valid |
|
| 27 |
+ end |
|
| 28 |
+ end |
|
| 29 |
+ |
|
| 30 |
+ context '#working' do |
|
| 31 |
+ it 'is not working without having received an event' do |
|
| 32 |
+ expect(@checker).not_to be_working |
|
| 33 |
+ end |
|
| 34 |
+ |
|
| 35 |
+ it 'is working after receiving an event without error' do |
|
| 36 |
+ @checker.last_receive_at = Time.now |
|
| 37 |
+ expect(@checker).to be_working |
|
| 38 |
+ end |
|
| 39 |
+ end |
|
| 40 |
+ |
|
| 41 |
+ describe "#receive" do |
|
| 42 |
+ it "parses valid JSON" do |
|
| 43 |
+ event = Event.new(payload: { data: '{"test": "data"}' } )
|
|
| 44 |
+ expect { @checker.receive([event]) }.to change(Event, :count).by(1)
|
|
| 45 |
+ end |
|
| 46 |
+ |
|
| 47 |
+ it "writes to the error log when the JSON could not be parsed" do |
|
| 48 |
+ event = Event.new(payload: { data: '{"test": "data}' } )
|
|
| 49 |
+ expect { @checker.receive([event]) }.to change(AgentLog, :count).by(1)
|
|
| 50 |
+ end |
|
| 51 |
+ end |
|
| 52 |
+end |