+ delete :destroy, params: {:id => events(:jane_website_agent_event).to_param}
}.to raise_error(ActiveRecord::RecordNotFound)
end
end
@@ -37,11 +37,11 @@ describe JobsController do |
||
37 | 37 |
end |
38 | 38 |
|
39 | 39 |
it "destroy a job which is not running" do |
40 |
- expect { delete :destroy, id: @not_running.id }.to change(Delayed::Job, :count).by(-1) |
|
40 |
+ expect { delete :destroy, params: {id: @not_running.id} }.to change(Delayed::Job, :count).by(-1) |
|
41 | 41 |
end |
42 | 42 |
|
43 | 43 |
it "does not destroy a running job" do |
44 |
- expect { delete :destroy, id: @running.id }.to change(Delayed::Job, :count).by(0) |
|
44 |
+ expect { delete :destroy, params: {id: @running.id} }.to change(Delayed::Job, :count).by(0) |
|
45 | 45 |
end |
46 | 46 |
end |
47 | 47 |
|
@@ -54,15 +54,15 @@ describe JobsController do |
||
54 | 54 |
end |
55 | 55 |
|
56 | 56 |
it "queue a job which is not running" do |
57 |
- expect { put :run, id: @not_running.id }.to change { @not_running.reload.run_at } |
|
57 |
+ expect { put :run, params: {id: @not_running.id} }.to change { @not_running.reload.run_at } |
|
58 | 58 |
end |
59 | 59 |
|
60 | 60 |
it "queue a job that failed" do |
61 |
- expect { put :run, id: @failed.id }.to change { @failed.reload.run_at } |
|
61 |
+ expect { put :run, params: {id: @failed.id} }.to change { @failed.reload.run_at } |
|
62 | 62 |
end |
63 | 63 |
|
64 | 64 |
it "not queue a running job" do |
65 |
- expect { put :run, id: @running.id }.not_to change { @not_running.reload.run_at } |
|
65 |
+ expect { put :run, params: {id: @running.id} }.not_to change { @not_running.reload.run_at } |
|
66 | 66 |
end |
67 | 67 |
end |
68 | 68 |
|
@@ -4,7 +4,7 @@ describe LogsController do |
||
4 | 4 |
describe "GET index" do |
5 | 5 |
it "can filter by Agent" do |
6 | 6 |
sign_in users(:bob) |
7 |
- get :index, :agent_id => agents(:bob_weather_agent).id |
|
7 |
+ get :index, params: {:agent_id => agents(:bob_weather_agent).id} |
|
8 | 8 |
expect(assigns(:logs).length).to eq(agents(:bob_weather_agent).logs.length) |
9 | 9 |
expect(assigns(:logs).all? {|i| expect(i.agent).to eq(agents(:bob_weather_agent)) }).to be_truthy |
10 | 10 |
end |
@@ -12,7 +12,7 @@ describe LogsController do |
||
12 | 12 |
it "only loads Agents owned by the current user" do |
13 | 13 |
sign_in users(:bob) |
14 | 14 |
expect { |
15 |
- get :index, :agent_id => agents(:jane_weather_agent).id |
|
15 |
+ get :index, params: {:agent_id => agents(:jane_weather_agent).id} |
|
16 | 16 |
}.to raise_error(ActiveRecord::RecordNotFound) |
17 | 17 |
end |
18 | 18 |
end |
@@ -22,7 +22,7 @@ describe LogsController do |
||
22 | 22 |
agents(:bob_weather_agent).last_error_log_at = 2.hours.ago |
23 | 23 |
sign_in users(:bob) |
24 | 24 |
expect { |
25 |
- delete :clear, :agent_id => agents(:bob_weather_agent).id |
|
25 |
+ delete :clear, params: {:agent_id => agents(:bob_weather_agent).id} |
|
26 | 26 |
}.to change { AgentLog.count }.by(-1 * agents(:bob_weather_agent).logs.count) |
27 | 27 |
expect(assigns(:logs).length).to eq(0) |
28 | 28 |
expect(agents(:bob_weather_agent).reload.logs.count).to eq(0) |
@@ -32,7 +32,7 @@ describe LogsController do |
||
32 | 32 |
it "only deletes logs for an Agent owned by the current user" do |
33 | 33 |
sign_in users(:bob) |
34 | 34 |
expect { |
35 |
- delete :clear, :agent_id => agents(:jane_weather_agent).id |
|
35 |
+ delete :clear, params: {:agent_id => agents(:jane_weather_agent).id} |
|
36 | 36 |
}.to raise_error(ActiveRecord::RecordNotFound) |
37 | 37 |
end |
38 | 38 |
end |
@@ -5,22 +5,23 @@ describe OmniauthCallbacksController do |
||
5 | 5 |
sign_in users(:bob) |
6 | 6 |
OmniAuth.config.test_mode = true |
7 | 7 |
request.env["devise.mapping"] = Devise.mappings[:user] |
8 |
- request.env["omniauth.auth"] = JSON.parse(File.read(Rails.root.join('spec/data_fixtures/services/twitter.json'))) |
|
9 | 8 |
end |
10 | 9 |
|
11 | 10 |
describe "accepting a callback url" do |
12 | 11 |
it "should update the user's credentials" do |
12 |
+ request.env["omniauth.auth"] = JSON.parse(File.read(Rails.root.join('spec/data_fixtures/services/twitter.json'))) |
|
13 | 13 |
expect { |
14 | 14 |
get :twitter |
15 | 15 |
}.to change { users(:bob).services.count }.by(1) |
16 | 16 |
end |
17 |
+ end |
|
17 | 18 |
|
18 |
- # it "should work with an unknown provider (for now)" do |
|
19 |
- # request.env["omniauth.auth"]['provider'] = 'unknown' |
|
20 |
- # expect { |
|
21 |
- # get :unknown |
|
22 |
- # }.to change { users(:bob).services.count }.by(1) |
|
23 |
- # expect(users(:bob).services.first.provider).to eq('unknown') |
|
24 |
- # end |
|
19 |
+ describe "handling a provider with non-standard omniauth options" do |
|
20 |
+ it "should update the user's credentials" do |
|
21 |
+ request.env["omniauth.auth"] = JSON.parse(File.read(Rails.root.join('spec/data_fixtures/services/37signals.json'))) |
|
22 |
+ expect { |
|
23 |
+ get "37signals" |
|
24 |
+ }.to change { users(:bob).services.count }.by(1) |
|
25 |
+ end |
|
25 | 26 |
end |
26 | 27 |
end |
@@ -15,7 +15,7 @@ describe ScenarioImportsController do |
||
15 | 15 |
|
16 | 16 |
describe "POST create" do |
17 | 17 |
it "initializes a ScenarioImport for current_user, passing in params" do |
18 |
- post :create, :scenario_import => { :url => "bad url" } |
|
18 |
+ post :create, params: {:scenario_import => { :url => "bad url" }} |
|
19 | 19 |
expect(assigns(:scenario_import).user).to eq(users(:bob)) |
20 | 20 |
expect(assigns(:scenario_import).url).to eq("bad url") |
21 | 21 |
expect(assigns(:scenario_import)).not_to be_valid |
@@ -18,34 +18,34 @@ describe ScenariosController do |
||
18 | 18 |
|
19 | 19 |
describe "GET show" do |
20 | 20 |
it "only shows Scenarios for the current user" do |
21 |
- get :show, :id => scenarios(:bob_weather).to_param |
|
21 |
+ get :show, params: {:id => scenarios(:bob_weather).to_param} |
|
22 | 22 |
expect(assigns(:scenario)).to eq(scenarios(:bob_weather)) |
23 | 23 |
|
24 | 24 |
expect { |
25 |
- get :show, :id => scenarios(:jane_weather).to_param |
|
25 |
+ get :show, params: {:id => scenarios(:jane_weather).to_param} |
|
26 | 26 |
}.to raise_error(ActiveRecord::RecordNotFound) |
27 | 27 |
end |
28 | 28 |
|
29 | 29 |
it "loads Agents for the requested Scenario" do |
30 |
- get :show, :id => scenarios(:bob_weather).to_param |
|
30 |
+ get :show, params: {:id => scenarios(:bob_weather).to_param} |
|
31 | 31 |
expect(assigns(:agents).pluck(:id).sort).to eq(scenarios(:bob_weather).agents.pluck(:id).sort) |
32 | 32 |
end |
33 | 33 |
end |
34 | 34 |
|
35 | 35 |
describe "GET share" do |
36 | 36 |
it "only displays Scenario share information for the current user" do |
37 |
- get :share, :id => scenarios(:bob_weather).to_param |
|
37 |
+ get :share, params: {:id => scenarios(:bob_weather).to_param} |
|
38 | 38 |
expect(assigns(:scenario)).to eq(scenarios(:bob_weather)) |
39 | 39 |
|
40 | 40 |
expect { |
41 |
- get :share, :id => scenarios(:jane_weather).to_param |
|
41 |
+ get :share, params: {:id => scenarios(:jane_weather).to_param} |
|
42 | 42 |
}.to raise_error(ActiveRecord::RecordNotFound) |
43 | 43 |
end |
44 | 44 |
end |
45 | 45 |
|
46 | 46 |
describe "GET export" do |
47 | 47 |
it "returns a JSON file download from an instantiated AgentsExporter" do |
48 |
- get :export, :id => scenarios(:bob_weather).to_param |
|
48 |
+ get :export, params: {:id => scenarios(:bob_weather).to_param} |
|
49 | 49 |
expect(assigns(:exporter).options[:name]).to eq(scenarios(:bob_weather).name) |
50 | 50 |
expect(assigns(:exporter).options[:description]).to eq(scenarios(:bob_weather).description) |
51 | 51 |
expect(assigns(:exporter).options[:agents]).to eq(scenarios(:bob_weather).agents) |
@@ -59,11 +59,11 @@ describe ScenariosController do |
||
59 | 59 |
end |
60 | 60 |
|
61 | 61 |
it "only exports private Scenarios for the current user" do |
62 |
- get :export, :id => scenarios(:bob_weather).to_param |
|
62 |
+ get :export, params: {:id => scenarios(:bob_weather).to_param} |
|
63 | 63 |
expect(assigns(:scenario)).to eq(scenarios(:bob_weather)) |
64 | 64 |
|
65 | 65 |
expect { |
66 |
- get :export, :id => scenarios(:jane_weather).to_param |
|
66 |
+ get :export, params: {:id => scenarios(:jane_weather).to_param} |
|
67 | 67 |
}.to raise_error(ActiveRecord::RecordNotFound) |
68 | 68 |
end |
69 | 69 |
|
@@ -73,14 +73,14 @@ describe ScenariosController do |
||
73 | 73 |
end |
74 | 74 |
|
75 | 75 |
it "exports public scenarios for other users when logged in" do |
76 |
- get :export, :id => scenarios(:jane_weather).to_param |
|
76 |
+ get :export, params: {:id => scenarios(:jane_weather).to_param} |
|
77 | 77 |
expect(assigns(:scenario)).to eq(scenarios(:jane_weather)) |
78 | 78 |
expect(assigns(:exporter).options[:source_url]).to eq(export_scenario_url(scenarios(:jane_weather))) |
79 | 79 |
end |
80 | 80 |
|
81 | 81 |
it "exports public scenarios for other users when logged out" do |
82 | 82 |
sign_out :user |
83 |
- get :export, :id => scenarios(:jane_weather).to_param |
|
83 |
+ get :export, params: {:id => scenarios(:jane_weather).to_param} |
|
84 | 84 |
expect(assigns(:scenario)).to eq(scenarios(:jane_weather)) |
85 | 85 |
expect(assigns(:exporter).options[:source_url]).to eq(export_scenario_url(scenarios(:jane_weather))) |
86 | 86 |
end |
@@ -89,11 +89,11 @@ describe ScenariosController do |
||
89 | 89 |
|
90 | 90 |
describe "GET edit" do |
91 | 91 |
it "only shows Scenarios for the current user" do |
92 |
- get :edit, :id => scenarios(:bob_weather).to_param |
|
92 |
+ get :edit, params: {:id => scenarios(:bob_weather).to_param} |
|
93 | 93 |
expect(assigns(:scenario)).to eq(scenarios(:bob_weather)) |
94 | 94 |
|
95 | 95 |
expect { |
96 |
- get :edit, :id => scenarios(:jane_weather).to_param |
|
96 |
+ get :edit, params: {:id => scenarios(:jane_weather).to_param} |
|
97 | 97 |
}.to raise_error(ActiveRecord::RecordNotFound) |
98 | 98 |
end |
99 | 99 |
end |
@@ -101,13 +101,13 @@ describe ScenariosController do |
||
101 | 101 |
describe "POST create" do |
102 | 102 |
it "creates Scenarios for the current user" do |
103 | 103 |
expect { |
104 |
- post :create, :scenario => valid_attributes |
|
104 |
+ post :create, params: {:scenario => valid_attributes} |
|
105 | 105 |
}.to change { users(:bob).scenarios.count }.by(1) |
106 | 106 |
end |
107 | 107 |
|
108 | 108 |
it "shows errors" do |
109 | 109 |
expect { |
110 |
- post :create, :scenario => valid_attributes(:name => "") |
|
110 |
+ post :create, params: {:scenario => valid_attributes(:name => "")} |
|
111 | 111 |
}.not_to change { users(:bob).scenarios.count } |
112 | 112 |
expect(assigns(:scenario)).to have(1).errors_on(:name) |
113 | 113 |
expect(response).to render_template("new") |
@@ -115,35 +115,41 @@ describe ScenariosController do |
||
115 | 115 |
|
116 | 116 |
it "will not create Scenarios for other users" do |
117 | 117 |
expect { |
118 |
- post :create, :scenario => valid_attributes(:user_id => users(:jane).id) |
|
119 |
- }.to raise_error(ActiveModel::MassAssignmentSecurity::Error) |
|
118 |
+ post :create, params: {:scenario => valid_attributes(:user_id => users(:jane).id)} |
|
119 |
+ }.to raise_error(ActionController::UnpermittedParameters) |
|
120 | 120 |
end |
121 | 121 |
end |
122 | 122 |
|
123 | 123 |
describe "PUT update" do |
124 | 124 |
it "updates attributes on Scenarios for the current user" do |
125 |
- post :update, :id => scenarios(:bob_weather).to_param, :scenario => { :name => "new_name", :public => "1" } |
|
125 |
+ post :update, params: {:id => scenarios(:bob_weather).to_param, :scenario => { :name => "new_name", :public => "1" }} |
|
126 | 126 |
expect(response).to redirect_to(scenario_path(scenarios(:bob_weather))) |
127 | 127 |
expect(scenarios(:bob_weather).reload.name).to eq("new_name") |
128 | 128 |
expect(scenarios(:bob_weather)).to be_public |
129 | 129 |
|
130 | 130 |
expect { |
131 |
- post :update, :id => scenarios(:jane_weather).to_param, :scenario => { :name => "new_name" } |
|
131 |
+ post :update, params: {:id => scenarios(:jane_weather).to_param, :scenario => { :name => "new_name" }} |
|
132 | 132 |
}.to raise_error(ActiveRecord::RecordNotFound) |
133 | 133 |
expect(scenarios(:jane_weather).reload.name).not_to eq("new_name") |
134 | 134 |
end |
135 | 135 |
|
136 | 136 |
it "shows errors" do |
137 |
- post :update, :id => scenarios(:bob_weather).to_param, :scenario => { :name => "" } |
|
137 |
+ post :update, params: {:id => scenarios(:bob_weather).to_param, :scenario => { :name => "" }} |
|
138 | 138 |
expect(assigns(:scenario)).to have(1).errors_on(:name) |
139 | 139 |
expect(response).to render_template("edit") |
140 | 140 |
end |
141 |
+ |
|
142 |
+ it 'adds an agent to the scenario' do |
|
143 |
+ expect { |
|
144 |
+ post :update, params: {:id => scenarios(:bob_weather).to_param, :scenario => { :name => "new_name", :public => "1", agent_ids: scenarios(:bob_weather).agent_ids + [agents(:bob_website_agent).id] }} |
|
145 |
+ }.to change { scenarios(:bob_weather).reload.agent_ids.length }.by(1) |
|
146 |
+ end |
|
141 | 147 |
end |
142 | 148 |
|
143 | 149 |
describe 'PUT enable_or_disable_all_agents' do |
144 | 150 |
it 'updates disabled on all agents in a scenario for the current user' do |
145 | 151 |
@params = {"scenario"=>{"disabled"=>"true"}, "commit"=>"Yes", "id"=> scenarios(:bob_weather).id} |
146 |
- put :enable_or_disable_all_agents, @params |
|
152 |
+ put :enable_or_disable_all_agents, params: @params |
|
147 | 153 |
expect(agents(:bob_rain_notifier_agent).disabled).to eq(true) |
148 | 154 |
expect(response).to redirect_to(scenario_path(scenarios(:bob_weather))) |
149 | 155 |
end |
@@ -152,17 +158,17 @@ describe ScenariosController do |
||
152 | 158 |
describe "DELETE destroy" do |
153 | 159 |
it "destroys only Scenarios owned by the current user" do |
154 | 160 |
expect { |
155 |
- delete :destroy, :id => scenarios(:bob_weather).to_param |
|
161 |
+ delete :destroy, params: {:id => scenarios(:bob_weather).to_param} |
|
156 | 162 |
}.to change(Scenario, :count).by(-1) |
157 | 163 |
|
158 | 164 |
expect { |
159 |
- delete :destroy, :id => scenarios(:jane_weather).to_param |
|
165 |
+ delete :destroy, params: {:id => scenarios(:jane_weather).to_param} |
|
160 | 166 |
}.to raise_error(ActiveRecord::RecordNotFound) |
161 | 167 |
end |
162 | 168 |
|
163 | 169 |
it "passes the mode to the model" do |
164 | 170 |
expect { |
165 |
- delete :destroy, id: scenarios(:bob_weather).to_param, mode: 'all_agents' |
|
171 |
+ delete :destroy, params: {id: scenarios(:bob_weather).to_param, mode: 'all_agents'} |
|
166 | 172 |
}.to change(Agent, :count).by(-2) |
167 | 173 |
end |
168 | 174 |
end |
@@ -14,14 +14,14 @@ describe ServicesController do |
||
14 | 14 |
|
15 | 15 |
describe "POST toggle_availability" do |
16 | 16 |
it "should work for service of the user" do |
17 |
- post :toggle_availability, :id => services(:generic).to_param |
|
17 |
+ post :toggle_availability, params: {:id => services(:generic).to_param} |
|
18 | 18 |
expect(assigns(:service)).to eq(services(:generic)) |
19 | 19 |
redirect_to(services_path) |
20 | 20 |
end |
21 | 21 |
|
22 | 22 |
it "should not work for a service of another user" do |
23 | 23 |
expect { |
24 |
- post :toggle_availability, :id => services(:global).to_param |
|
24 |
+ post :toggle_availability, params: {:id => services(:global).to_param} |
|
25 | 25 |
}.to raise_error(ActiveRecord::RecordNotFound) |
26 | 26 |
end |
27 | 27 |
end |
@@ -29,11 +29,11 @@ describe ServicesController do |
||
29 | 29 |
describe "DELETE destroy" do |
30 | 30 |
it "destroys only services owned by the current user" do |
31 | 31 |
expect { |
32 |
- delete :destroy, :id => services(:generic).to_param |
|
32 |
+ delete :destroy, params: {:id => services(:generic).to_param} |
|
33 | 33 |
}.to change(Service, :count).by(-1) |
34 | 34 |
|
35 | 35 |
expect { |
36 |
- delete :destroy, :id => services(:global).to_param |
|
36 |
+ delete :destroy, params: {:id => services(:global).to_param} |
|
37 | 37 |
}.to raise_error(ActiveRecord::RecordNotFound) |
38 | 38 |
end |
39 | 39 |
end |
@@ -22,30 +22,30 @@ describe UserCredentialsController do |
||
22 | 22 |
|
23 | 23 |
describe "GET edit" do |
24 | 24 |
it "only shows UserCredentials for the current user" do |
25 |
- get :edit, :id => user_credentials(:bob_aws_secret).to_param |
|
25 |
+ get :edit, params: {:id => user_credentials(:bob_aws_secret).to_param} |
|
26 | 26 |
expect(assigns(:user_credential)).to eq(user_credentials(:bob_aws_secret)) |
27 | 27 |
|
28 | 28 |
expect { |
29 |
- get :edit, :id => user_credentials(:jane_aws_secret).to_param |
|
29 |
+ get :edit, params: {:id => user_credentials(:jane_aws_secret).to_param} |
|
30 | 30 |
}.to raise_error(ActiveRecord::RecordNotFound) |
31 | 31 |
end |
32 | 32 |
end |
33 | 33 |
|
34 | 34 |
describe "Post import" do |
35 | 35 |
it "asserts user credentials were created for current user only" do |
36 |
- post :import, :file => @file |
|
36 |
+ post :import, params: {:file => @file} |
|
37 | 37 |
expect(controller.current_user.id).to eq(users(:bob).id) |
38 | 38 |
expect(controller.current_user.user_credentials).to eq(users(:bob).user_credentials) |
39 | 39 |
end |
40 | 40 |
|
41 | 41 |
it "asserts that primary id in json file is ignored" do |
42 |
- post :import, :file => @file |
|
42 |
+ post :import, params: {:file => @file} |
|
43 | 43 |
expect(controller.current_user.user_credentials.last.id).not_to eq(24) |
44 | 44 |
end |
45 | 45 |
|
46 | 46 |
it "duplicate credential name shows an error that it is not saved" do |
47 | 47 |
file1 = fixture_file_upload('multiple_user_credentials.json') |
48 |
- post :import, :file => file1 |
|
48 |
+ post :import, params: {:file => file1} |
|
49 | 49 |
expect(flash[:notice]).to eq("One or more of the uploaded credentials was not imported due to an error. Perhaps an existing credential had the same name?") |
50 | 50 |
expect(response).to redirect_to(user_credentials_path) |
51 | 51 |
end |
@@ -54,13 +54,13 @@ describe UserCredentialsController do |
||
54 | 54 |
describe "POST create" do |
55 | 55 |
it "creates UserCredentials for the current user" do |
56 | 56 |
expect { |
57 |
- post :create, :user_credential => valid_attributes |
|
57 |
+ post :create, params: {:user_credential => valid_attributes} |
|
58 | 58 |
}.to change { users(:bob).user_credentials.count }.by(1) |
59 | 59 |
end |
60 | 60 |
|
61 | 61 |
it "shows errors" do |
62 | 62 |
expect { |
63 |
- post :create, :user_credential => valid_attributes(:credential_name => "") |
|
63 |
+ post :create, params: {:user_credential => valid_attributes(:credential_name => "")} |
|
64 | 64 |
}.not_to change { users(:bob).user_credentials.count } |
65 | 65 |
expect(assigns(:user_credential)).to have(1).errors_on(:credential_name) |
66 | 66 |
expect(response).to render_template("new") |
@@ -68,25 +68,25 @@ describe UserCredentialsController do |
||
68 | 68 |
|
69 | 69 |
it "will not create UserCredentials for other users" do |
70 | 70 |
expect { |
71 |
- post :create, :user_credential => valid_attributes(:user_id => users(:jane).id) |
|
72 |
- }.to raise_error(ActiveModel::MassAssignmentSecurity::Error) |
|
71 |
+ post :create, params: {:user_credential => valid_attributes(:user_id => users(:jane).id)} |
|
72 |
+ }.to raise_error(ActionController::UnpermittedParameters) |
|
73 | 73 |
end |
74 | 74 |
end |
75 | 75 |
|
76 | 76 |
describe "PUT update" do |
77 | 77 |
it "updates attributes on UserCredentials for the current user" do |
78 |
- post :update, :id => user_credentials(:bob_aws_key).to_param, :user_credential => { :credential_name => "new_name" } |
|
78 |
+ post :update, params: {:id => user_credentials(:bob_aws_key).to_param, :user_credential => { :credential_name => "new_name" }} |
|
79 | 79 |
expect(response).to redirect_to(user_credentials_path) |
80 | 80 |
expect(user_credentials(:bob_aws_key).reload.credential_name).to eq("new_name") |
81 | 81 |
|
82 | 82 |
expect { |
83 |
- post :update, :id => user_credentials(:jane_aws_key).to_param, :user_credential => { :credential_name => "new_name" } |
|
83 |
+ post :update, params: {:id => user_credentials(:jane_aws_key).to_param, :user_credential => { :credential_name => "new_name" }} |
|
84 | 84 |
}.to raise_error(ActiveRecord::RecordNotFound) |
85 | 85 |
expect(user_credentials(:jane_aws_key).reload.credential_name).not_to eq("new_name") |
86 | 86 |
end |
87 | 87 |
|
88 | 88 |
it "shows errors" do |
89 |
- post :update, :id => user_credentials(:bob_aws_key).to_param, :user_credential => { :credential_name => "" } |
|
89 |
+ post :update, params: {:id => user_credentials(:bob_aws_key).to_param, :user_credential => { :credential_name => "" }} |
|
90 | 90 |
expect(assigns(:user_credential)).to have(1).errors_on(:credential_name) |
91 | 91 |
expect(response).to render_template("edit") |
92 | 92 |
end |
@@ -95,11 +95,11 @@ describe UserCredentialsController do |
||
95 | 95 |
describe "DELETE destroy" do |
96 | 96 |
it "destroys only UserCredentials owned by the current user" do |
97 | 97 |
expect { |
98 |
- delete :destroy, :id => user_credentials(:bob_aws_key).to_param |
|
98 |
+ delete :destroy, params: {:id => user_credentials(:bob_aws_key).to_param} |
|
99 | 99 |
}.to change(UserCredential, :count).by(-1) |
100 | 100 |
|
101 | 101 |
expect { |
102 |
- delete :destroy, :id => user_credentials(:jane_aws_key).to_param |
|
102 |
+ delete :destroy, params: {:id => user_credentials(:jane_aws_key).to_param} |
|
103 | 103 |
}.to raise_error(ActiveRecord::RecordNotFound) |
104 | 104 |
end |
105 | 105 |
end |
@@ -2,16 +2,19 @@ require 'rails_helper' |
||
2 | 2 |
|
3 | 3 |
module Users |
4 | 4 |
describe RegistrationsController do |
5 |
- include Devise::TestHelpers |
|
6 |
- |
|
7 | 5 |
describe "POST create" do |
6 |
+ before do |
|
7 |
+ @request.env["devise.mapping"] = Devise.mappings[:user] |
|
8 |
+ end |
|
9 |
+ |
|
8 | 10 |
context 'with valid params' do |
9 | 11 |
it "imports the default scenario for the new user" do |
10 | 12 |
mock(DefaultScenarioImporter).import(is_a(User)) |
11 | 13 |
|
12 |
- @request.env["devise.mapping"] = Devise.mappings[:user] |
|
13 |
- post :create, :user => {username: 'jdoe', email: 'jdoe@example.com', |
|
14 |
- password: 's3cr3t55', password_confirmation: 's3cr3t55', admin: false, invitation_code: 'try-huginn'} |
|
14 |
+ post :create, params: { |
|
15 |
+ :user => {username: 'jdoe', email: 'jdoe@example.com', |
|
16 |
+ password: 's3cr3t55', password_confirmation: 's3cr3t55', invitation_code: 'try-huginn'} |
|
17 |
+ } |
|
15 | 18 |
end |
16 | 19 |
end |
17 | 20 |
|
@@ -19,9 +22,12 @@ module Users |
||
19 | 22 |
it "does not import the default scenario" do |
20 | 23 |
stub(DefaultScenarioImporter).import(is_a(User)) { fail "Should not attempt import" } |
21 | 24 |
|
22 |
- @request.env["devise.mapping"] = Devise.mappings[:user] |
|
23 | 25 |
setup_controller_for_warden |
24 |
- post :create, :user => {} |
|
26 |
+ post :create, params: {:user => {}} |
|
27 |
+ end |
|
28 |
+ |
|
29 |
+ it 'does not allow to set the admin flag' do |
|
30 |
+ expect { post :create, params: {:user => {admin: 'true'}} }.to raise_error(ActionController::UnpermittedParameters) |
|
25 | 31 |
end |
26 | 32 |
end |
27 | 33 |
end |
@@ -26,14 +26,14 @@ describe WebRequestsController do |
||
26 | 26 |
|
27 | 27 |
it "should not require login to receive a web request" do |
28 | 28 |
expect(@agent.last_web_request_at).to be_nil |
29 |
- post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" |
|
29 |
+ post :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"} |
|
30 | 30 |
expect(@agent.reload.last_web_request_at).to be_within(2).of(Time.now) |
31 | 31 |
expect(response.body).to eq("success") |
32 | 32 |
expect(response).to be_success |
33 | 33 |
end |
34 | 34 |
|
35 | 35 |
it "should call receive_web_request" do |
36 |
- post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" |
|
36 |
+ post :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"} |
|
37 | 37 |
@agent.reload |
38 | 38 |
expect(@agent.memory[:web_request_values]).to eq({ 'key' => "value", 'another_key' => "5" }) |
39 | 39 |
expect(@agent.memory[:web_request_format]).to eq("text/html") |
@@ -42,14 +42,14 @@ describe WebRequestsController do |
||
42 | 42 |
expect(response.headers['Content-Type']).to eq('text/plain; charset=utf-8') |
43 | 43 |
expect(response).to be_success |
44 | 44 |
|
45 |
- post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "not_my_secret", :no => "go" |
|
45 |
+ post :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "not_my_secret", :no => "go"} |
|
46 | 46 |
expect(@agent.reload.memory[:web_request_values]).not_to eq({ 'no' => "go" }) |
47 | 47 |
expect(response.body).to eq("failure") |
48 | 48 |
expect(response).to be_missing |
49 | 49 |
end |
50 | 50 |
|
51 | 51 |
it "should accept gets" do |
52 |
- get :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" |
|
52 |
+ get :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"} |
|
53 | 53 |
@agent.reload |
54 | 54 |
expect(@agent.memory[:web_request_values]).to eq({ 'key' => "value", 'another_key' => "5" }) |
55 | 55 |
expect(@agent.memory[:web_request_format]).to eq("text/html") |
@@ -59,19 +59,19 @@ describe WebRequestsController do |
||
59 | 59 |
end |
60 | 60 |
|
61 | 61 |
it "should pass through the received format" do |
62 |
- get :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5", :format => :json |
|
62 |
+ get :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"}, :format => :json |
|
63 | 63 |
@agent.reload |
64 | 64 |
expect(@agent.memory[:web_request_values]).to eq({ 'key' => "value", 'another_key' => "5" }) |
65 | 65 |
expect(@agent.memory[:web_request_format]).to eq("application/json") |
66 | 66 |
expect(@agent.memory[:web_request_method]).to eq("get") |
67 | 67 |
|
68 |
- post :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5", :format => :xml |
|
68 |
+ post :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"}, :format => :xml |
|
69 | 69 |
@agent.reload |
70 | 70 |
expect(@agent.memory[:web_request_values]).to eq({ 'key' => "value", 'another_key' => "5" }) |
71 | 71 |
expect(@agent.memory[:web_request_format]).to eq("application/xml") |
72 | 72 |
expect(@agent.memory[:web_request_method]).to eq("post") |
73 | 73 |
|
74 |
- put :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5", :format => :atom |
|
74 |
+ put :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"}, :format => :atom |
|
75 | 75 |
@agent.reload |
76 | 76 |
expect(@agent.memory[:web_request_values]).to eq({ 'key' => "value", 'another_key' => "5" }) |
77 | 77 |
expect(@agent.memory[:web_request_format]).to eq("application/atom+xml") |
@@ -81,17 +81,17 @@ describe WebRequestsController do |
||
81 | 81 |
it "can accept a content-type to return" do |
82 | 82 |
@agent.memory['content_type'] = 'application/json' |
83 | 83 |
@agent.save! |
84 |
- get :handle_request, :user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5" |
|
84 |
+ get :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => @agent.id, :secret => "my_secret", :key => "value", :another_key => "5"} |
|
85 | 85 |
expect(response.headers['Content-Type']).to eq('application/json; charset=utf-8') |
86 | 86 |
end |
87 | 87 |
|
88 | 88 |
it "should fail on incorrect users" do |
89 |
- post :handle_request, :user_id => users(:jane).to_param, :agent_id => @agent.id, :secret => "my_secret", :no => "go" |
|
89 |
+ post :handle_request, params: {:user_id => users(:jane).to_param, :agent_id => @agent.id, :secret => "my_secret", :no => "go"} |
|
90 | 90 |
expect(response).to be_missing |
91 | 91 |
end |
92 | 92 |
|
93 | 93 |
it "should fail on incorrect agents" do |
94 |
- post :handle_request, :user_id => users(:bob).to_param, :agent_id => 454545, :secret => "my_secret", :no => "go" |
|
94 |
+ post :handle_request, params: {:user_id => users(:bob).to_param, :agent_id => 454545, :secret => "my_secret", :no => "go"} |
|
95 | 95 |
expect(response).to be_missing |
96 | 96 |
end |
97 | 97 |
|
@@ -102,7 +102,7 @@ describe WebRequestsController do |
||
102 | 102 |
end |
103 | 103 |
|
104 | 104 |
it "should create events without requiring login" do |
105 |
- post :update_location, user_id: users(:bob).to_param, secret: "my_secret", longitude: 123, latitude: 45, something: "else" |
|
105 |
+ post :update_location, params: {user_id: users(:bob).to_param, secret: "my_secret", longitude: 123, latitude: 45, something: "else"} |
|
106 | 106 |
expect(@agent.events.last.payload).to eq({ 'longitude' => "123", 'latitude' => "45", 'something' => "else" }) |
107 | 107 |
expect(@agent.events.last.lat).to eq(45) |
108 | 108 |
expect(@agent.events.last.lng).to eq(123) |
@@ -112,13 +112,13 @@ describe WebRequestsController do |
||
112 | 112 |
@jane_agent = Agent.build_for_type("Agents::UserLocationAgent", users(:jane), name: "something", options: { secret: "my_secret" }) |
113 | 113 |
@jane_agent.save! |
114 | 114 |
|
115 |
- post :update_location, user_id: users(:bob).to_param, secret: "my_secret", longitude: 123, latitude: 45, something: "else" |
|
115 |
+ post :update_location, params: {user_id: users(:bob).to_param, secret: "my_secret", longitude: 123, latitude: 45, something: "else"} |
|
116 | 116 |
expect(@agent.events.last.payload).to eq({ 'longitude' => "123", 'latitude' => "45", 'something' => "else" }) |
117 | 117 |
expect(@jane_agent.events).to be_empty |
118 | 118 |
end |
119 | 119 |
|
120 | 120 |
it "should raise a 404 error when given an invalid user id" do |
121 |
- post :update_location, user_id: "123", secret: "not_my_secret", longitude: 123, latitude: 45, something: "else" |
|
121 |
+ post :update_location, params: {user_id: "123", secret: "not_my_secret", longitude: 123, latitude: 45, something: "else"} |
|
122 | 122 |
expect(response).to be_missing |
123 | 123 |
end |
124 | 124 |
|
@@ -127,7 +127,7 @@ describe WebRequestsController do |
||
127 | 127 |
@agent2.save! |
128 | 128 |
|
129 | 129 |
expect { |
130 |
- post :update_location, user_id: users(:bob).to_param, secret: "my_secret2", longitude: 123, latitude: 45, something: "else" |
|
130 |
+ post :update_location, params: {user_id: users(:bob).to_param, secret: "my_secret2", longitude: 123, latitude: 45, something: "else"} |
|
131 | 131 |
expect(@agent2.events.last.payload).to eq({ 'longitude' => "123", 'latitude' => "45", 'something' => "else" }) |
132 | 132 |
}.not_to change { @agent.events.count } |
133 | 133 |
end |
@@ -44,6 +44,7 @@ |
||
44 | 44 |
<category>calendar</category> |
45 | 45 |
<category>menubar</category> |
46 | 46 |
<category>osx</category> |
47 |
+ <enclosure url="http://c.1tw.org/images/2015/itsy.png" length="48249" type="image/png" /> |
|
47 | 48 |
</item> |
48 | 49 |
<item> |
49 | 50 |
<title>Magic Wormhole</title> |
@@ -208,8 +209,7 @@ |
||
208 | 209 |
</item> |
209 | 210 |
<item> |
210 | 211 |
<title>Showgoers</title> |
211 |
- <description><a href="http://showgoers.tv/">Showgoers</a>: <blockquote> <p>Showgoers is a Chrome browser extension to synchronize your Netflix player with someone else so that you can co-watch the same movie on different computers with no hassle. Syncing up your player is as easy as sharing a URL.</p> </blockquote> |
|
212 |
- </description> |
|
212 |
+ <description><a href="http://showgoers.tv/" onmouseover="javascript:void(0)">Showgoers</a>: <blockquote> <p>Showgoers is a Chrome browser extension to synchronize your Netflix player with someone else so that you can co-watch the same movie on different computers with no hassle. Syncing up your player is as easy as sharing a URL.</p> </blockquote><script>some code</script></description> |
|
213 | 213 |
<link>http://onethingwell.org/post/125509667816</link> |
214 | 214 |
<guid>http://onethingwell.org/post/125509667816</guid> |
215 | 215 |
<pubDate>Fri, 31 Jul 2015 13:00:13 +0100</pubDate> |
@@ -12,6 +12,7 @@ |
||
12 | 12 |
<li><a href="https://www.google.ca/search?q=위키백과:대문">unicode param</a></li> |
13 | 13 |
<li><a href="http://ko.wikipedia.org/wiki/%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:%EB%8C%80%EB%AC%B8">percent encoded url</a></li> |
14 | 14 |
<li><a href="https://www.google.ca/search?q=%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:%EB%8C%80%EB%AC%B8">percent encoded param</a></li> |
15 |
+ <li><a href="http://[::1]/path[]?query[]=foo">brackets</a></li> |
|
15 | 16 |
</ul> |
16 | 17 |
</body> |
17 |
-</html> |
|
18 |
+</html> |
@@ -0,0 +1,76 @@ |
||
1 |
+require 'rails_helper' |
|
2 |
+ |
|
3 |
+describe "Dry running an Agent", js: true do |
|
4 |
+ let(:agent) { agents(:bob_website_agent) } |
|
5 |
+ let(:formatting_agent) { agents(:bob_formatting_agent) } |
|
6 |
+ let(:user) { users(:bob) } |
|
7 |
+ let(:emitter) { agents(:bob_weather_agent) } |
|
8 |
+ |
|
9 |
+ before(:each) do |
|
10 |
+ login_as(user) |
|
11 |
+ end |
|
12 |
+ |
|
13 |
+ def open_dry_run_modal(agent) |
|
14 |
+ visit edit_agent_path(agent) |
|
15 |
+ click_on("Dry Run") |
|
16 |
+ expect(page).to have_text('Event to send') |
|
17 |
+ end |
|
18 |
+ |
|
19 |
+ context 'successful dry runs' do |
|
20 |
+ before do |
|
21 |
+ stub_request(:get, "http://xkcd.com/"). |
|
22 |
+ with(:headers => {'Accept-Encoding'=>'gzip,deflate', 'User-Agent'=>'Huginn - https://github.com/cantino/huginn'}). |
|
23 |
+ to_return(:status => 200, :body => File.read(Rails.root.join("spec/data_fixtures/xkcd.html")), :headers => {}) |
|
24 |
+ end |
|
25 |
+ |
|
26 |
+ it 'shows the dry run pop up without previous events and selects the events tab when a event was created' do |
|
27 |
+ open_dry_run_modal(agent) |
|
28 |
+ click_on("Dry Run") |
|
29 |
+ expect(page).to have_text('Biologists play reverse') |
|
30 |
+ expect(page).to have_selector(:css, 'li[role="presentation"].active a[href="#tabEvents"]') |
|
31 |
+ end |
|
32 |
+ |
|
33 |
+ it 'shows the dry run pop up with previous events and allows use previously received event' do |
|
34 |
+ emitter.events << Event.new(payload: {url: "http://xkcd.com/"}) |
|
35 |
+ agent.sources << emitter |
|
36 |
+ agent.options.merge!('url' => '', 'url_from_event' => '{{url}}') |
|
37 |
+ agent.save! |
|
38 |
+ |
|
39 |
+ open_dry_run_modal(agent) |
|
40 |
+ find('.dry-run-event-sample').click |
|
41 |
+ within(:css, '.modal .builder') do |
|
42 |
+ expect(page).to have_text('http://xkcd.com/') |
|
43 |
+ end |
|
44 |
+ click_on("Dry Run") |
|
45 |
+ expect(page).to have_text('Biologists play reverse') |
|
46 |
+ expect(page).to have_selector(:css, 'li[role="presentation"].active a[href="#tabEvents"]') |
|
47 |
+ end |
|
48 |
+ |
|
49 |
+ it 'sends escape characters correctly to the backend' do |
|
50 |
+ emitter.events << Event.new(payload: {data: "Line 1\nLine 2\nLine 3"}) |
|
51 |
+ formatting_agent.sources << emitter |
|
52 |
+ formatting_agent.options.merge!('instructions' => {'data' => "{{data | newline_to_br | strip_newlines | split: '<br />' | join: ','}}"}) |
|
53 |
+ formatting_agent.save! |
|
54 |
+ |
|
55 |
+ open_dry_run_modal(formatting_agent) |
|
56 |
+ find('.dry-run-event-sample').click |
|
57 |
+ within(:css, '.modal .builder') do |
|
58 |
+ expect(page).to have_text('Line 1\nLine 2\nLine 3') |
|
59 |
+ end |
|
60 |
+ click_on("Dry Run") |
|
61 |
+ expect(page).to have_text('Line 1,Line 2,Line 3') |
|
62 |
+ expect(page).to have_selector(:css, 'li[role="presentation"].active a[href="#tabEvents"]') |
|
63 |
+ end |
|
64 |
+ end |
|
65 |
+ |
|
66 |
+ it 'shows the dry run pop up without previous events and selects the log tab when no event was created' do |
|
67 |
+ stub_request(:get, "http://xkcd.com/"). |
|
68 |
+ with(:headers => {'Accept-Encoding'=>'gzip,deflate', 'User-Agent'=>'Huginn - https://github.com/cantino/huginn'}). |
|
69 |
+ to_return(:status => 200, :body => "", :headers => {}) |
|
70 |
+ |
|
71 |
+ open_dry_run_modal(agent) |
|
72 |
+ click_on("Dry Run") |
|
73 |
+ expect(page).to have_text('Dry Run started') |
|
74 |
+ expect(page).to have_selector(:css, 'li[role="presentation"].active a[href="#tabLog"]') |
|
75 |
+ end |
|
76 |
+end |
@@ -0,0 +1,10 @@ |
||
1 |
+require 'capybara_helper' |
|
2 |
+ |
|
3 |
+describe "form configuring agents", js: true do |
|
4 |
+ it 'completes fields with predefined array values' do |
|
5 |
+ login_as(users(:bob)) |
|
6 |
+ visit edit_agent_path(agents(:bob_csv_agent)) |
|
7 |
+ check('Propagate immediately') |
|
8 |
+ select2("serialize", from: "Mode") |
|
9 |
+ end |
|
10 |
+end |
@@ -0,0 +1,46 @@ |
||
1 |
+require 'rails_helper' |
|
2 |
+ |
|
3 |
+describe ScenarioImportsController do |
|
4 |
+ let(:user) { users(:bob) } |
|
5 |
+ |
|
6 |
+ before do |
|
7 |
+ login_as(user) |
|
8 |
+ end |
|
9 |
+ |
|
10 |
+ it 'renders the import form' do |
|
11 |
+ visit new_scenario_imports_path |
|
12 |
+ expect(page).to have_text('Import a Public Scenario') |
|
13 |
+ end |
|
14 |
+ |
|
15 |
+ it 'requires a URL or file uplaod' do |
|
16 |
+ visit new_scenario_imports_path |
|
17 |
+ click_on 'Start Import' |
|
18 |
+ expect(page).to have_text('Please provide either a Scenario JSON File or a Public Scenario URL.') |
|
19 |
+ end |
|
20 |
+ |
|
21 |
+ it 'imports a scenario that does not exist yet' do |
|
22 |
+ visit new_scenario_imports_path |
|
23 |
+ attach_file('Option 2: Upload a Scenario JSON File', File.join(Rails.root, 'data/default_scenario.json')) |
|
24 |
+ click_on 'Start Import' |
|
25 |
+ expect(page).to have_text('This scenario has a few agents to get you started. Feel free to change them or delete them as you see fit!') |
|
26 |
+ expect(page).not_to have_text('This Scenario already exists in your system.') |
|
27 |
+ check('I confirm that I want to import these Agents.') |
|
28 |
+ click_on 'Finish Import' |
|
29 |
+ expect(page).to have_text('Import successful!') |
|
30 |
+ end |
|
31 |
+ |
|
32 |
+ it 'asks to accept conflicts when the scenario was modified' do |
|
33 |
+ DefaultScenarioImporter.seed(user) |
|
34 |
+ agent = user.agents.where(name: 'Rain Notifier').first |
|
35 |
+ agent.options['expected_receive_period_in_days'] = 9001 |
|
36 |
+ agent.save! |
|
37 |
+ visit new_scenario_imports_path |
|
38 |
+ attach_file('Option 2: Upload a Scenario JSON File', File.join(Rails.root, 'data/default_scenario.json')) |
|
39 |
+ click_on 'Start Import' |
|
40 |
+ expect(page).to have_text('This Scenario already exists in your system.') |
|
41 |
+ expect(page).to have_text('9001') |
|
42 |
+ check('I confirm that I want to import these Agents.') |
|
43 |
+ click_on 'Finish Import' |
|
44 |
+ expect(page).to have_text('Import successful!') |
|
45 |
+ end |
|
46 |
+end |
@@ -0,0 +1,21 @@ |
||
1 |
+require 'capybara_helper' |
|
2 |
+ |
|
3 |
+describe "handling undefined agents" do |
|
4 |
+ before do |
|
5 |
+ login_as(users(:bob)) |
|
6 |
+ agent = agents(:bob_website_agent) |
|
7 |
+ agent.update_attribute(:type, 'Agents::UndefinedAgent') |
|
8 |
+ end |
|
9 |
+ |
|
10 |
+ it 'renders the error page' do |
|
11 |
+ visit agents_path |
|
12 |
+ expect(page).to have_text("Error: Agent(s) are 'missing in action'") |
|
13 |
+ expect(page).to have_text('Undefined Agent') |
|
14 |
+ end |
|
15 |
+ |
|
16 |
+ it 'deletes all undefined agents' do |
|
17 |
+ visit agents_path |
|
18 |
+ click_on('Delete Missing Agents') |
|
19 |
+ expect(page).to have_text('Your Agents') |
|
20 |
+ end |
|
21 |
+end |
@@ -60,6 +60,14 @@ bob_weather_agent: |
||
60 | 60 |
keep_events_for: <%= 45.days %> |
61 | 61 |
options: <%= { :location => 94102, :lat => 37.779329, :lng => -122.41915, :api_key => 'test' }.to_json.inspect %> |
62 | 62 |
|
63 |
+bob_formatting_agent: |
|
64 |
+ type: Agents::EventFormattingAgent |
|
65 |
+ user: bob |
|
66 |
+ name: "Formatting Agent" |
|
67 |
+ guid: <%= SecureRandom.hex %> |
|
68 |
+ keep_events_for: <%= 45.days %> |
|
69 |
+ options: <%= { instructions: {}, mode: 'clean' }.to_json.inspect %> |
|
70 |
+ |
|
63 | 71 |
jane_weather_agent: |
64 | 72 |
type: Agents::WeatherAgent |
65 | 73 |
user: jane |
@@ -136,14 +144,28 @@ bob_manual_event_agent: |
||
136 | 144 |
bob_basecamp_agent: |
137 | 145 |
type: Agents::BasecampAgent |
138 | 146 |
user: bob |
147 |
+ name: "bob basecamp agent" |
|
139 | 148 |
service: generic |
140 | 149 |
guid: <%= SecureRandom.hex %> |
150 |
+ options: <%= { |
|
151 |
+ :project_id => "12345", |
|
152 |
+ }.to_json.inspect %> |
|
153 |
+ |
|
154 |
+bob_csv_agent: |
|
155 |
+ type: Agents::CsvAgent |
|
156 |
+ user: bob |
|
157 |
+ name: "Bob's CsvAgent" |
|
158 |
+ guid: <%= SecureRandom.hex %> |
|
141 | 159 |
|
142 | 160 |
jane_basecamp_agent: |
143 | 161 |
type: Agents::BasecampAgent |
144 | 162 |
user: jane |
163 |
+ name: "jane basecamp agent" |
|
145 | 164 |
service: generic |
146 | 165 |
guid: <%= SecureRandom.hex %> |
166 |
+ options: <%= { |
|
167 |
+ :project_id => "12345", |
|
168 |
+ }.to_json.inspect %> |
|
147 | 169 |
|
148 | 170 |
|
149 | 171 |
bob_data_output_agent: |
@@ -44,17 +44,17 @@ describe Agents::BoxcarAgent do |
||
44 | 44 |
|
45 | 45 |
it "should raise error when invalid response arrives" do |
46 | 46 |
stub(HTTParty).post { {"blah" => "blah"} } |
47 |
- expect{@checker.send_notification}.to raise_error |
|
47 |
+ expect { @checker.send_notification({}) }.to raise_error(StandardError, /Invalid response from Boxcar:/) |
|
48 | 48 |
end |
49 | 49 |
|
50 | 50 |
it "should raise error when response says unauthorized" do |
51 |
- stub(HTTParty).post '{"Response":"Not authorized"}' |
|
52 |
- expect{@checker.send_notification}.to raise_error |
|
51 |
+ stub(HTTParty).post { {"Response" => "Not authorized"} } |
|
52 |
+ expect { @checker.send_notification({}) }.to raise_error(StandardError, /Not authorized/) |
|
53 | 53 |
end |
54 | 54 |
|
55 | 55 |
it "should raise error when response has an error" do |
56 |
- stub(HTTParty).post '{"error": {"message": "Sample error"}}' |
|
57 |
- expect{@checker.send_notification}.to raise_error |
|
56 |
+ stub(HTTParty).post { {"error" => {"message" => "Sample error"}} } |
|
57 |
+ expect { @checker.send_notification({}) }.to raise_error(StandardError, /Sample error/) |
|
58 | 58 |
end |
59 | 59 |
end |
60 | 60 |
end |
@@ -142,7 +142,7 @@ describe Agents::DataOutputAgent do |
||
142 | 142 |
"url" => "http://imgs.xkcd.com/comics/evolving0.png", |
143 | 143 |
"title" => "Evolving yet again with a past date", |
144 | 144 |
"date" => '2014/05/05', |
145 |
- "hovertext" => "Something else" |
|
145 |
+ "hovertext" => "A small text" |
|
146 | 146 |
} |
147 | 147 |
end |
148 | 148 |
|
@@ -166,7 +166,7 @@ describe Agents::DataOutputAgent do |
||
166 | 166 |
|
167 | 167 |
<item> |
168 | 168 |
<title>Evolving yet again with a past date</title> |
169 |
- <description>Secret hovertext: Something else</description> |
|
169 |
+ <description>Secret hovertext: A small text</description> |
|
170 | 170 |
<link>http://imgs.xkcd.com/comics/evolving0.png</link> |
171 | 171 |
<pubDate>#{Time.zone.parse(event3.payload['date']).rfc2822}</pubDate> |
172 | 172 |
<guid isPermaLink="false">#{event3.id}</guid> |
@@ -216,7 +216,7 @@ describe Agents::DataOutputAgent do |
||
216 | 216 |
'items' => [ |
217 | 217 |
{ |
218 | 218 |
'title' => 'Evolving yet again with a past date', |
219 |
- 'description' => 'Secret hovertext: Something else', |
|
219 |
+ 'description' => 'Secret hovertext: A small text', |
|
220 | 220 |
'link' => 'http://imgs.xkcd.com/comics/evolving0.png', |
221 | 221 |
'guid' => {"contents" => event3.id, "isPermaLink" => "false"}, |
222 | 222 |
'pubDate' => Time.zone.parse(event3.payload['date']).rfc2822, |
@@ -242,16 +242,62 @@ describe Agents::DataOutputAgent do |
||
242 | 242 |
}) |
243 | 243 |
end |
244 | 244 |
|
245 |
+ context 'with more events' do |
|
246 |
+ let!(:event4) do |
|
247 |
+ agents(:bob_website_agent).create_event payload: { |
|
248 |
+ 'site_title' => 'XKCD', |
|
249 |
+ 'url' => 'http://imgs.xkcd.com/comics/comic1.png', |
|
250 |
+ 'title' => 'Comic 1', |
|
251 |
+ 'date' => '', |
|
252 |
+ 'hovertext' => 'Hovertext for Comic 1' |
|
253 |
+ } |
|
254 |
+ end |
|
255 |
+ |
|
256 |
+ let!(:event5) do |
|
257 |
+ agents(:bob_website_agent).create_event payload: { |
|
258 |
+ 'site_title' => 'XKCD', |
|
259 |
+ 'url' => 'http://imgs.xkcd.com/comics/comic2.png', |
|
260 |
+ 'title' => 'Comic 2', |
|
261 |
+ 'date' => '', |
|
262 |
+ 'hovertext' => 'Hovertext for Comic 2' |
|
263 |
+ } |
|
264 |
+ end |
|
265 |
+ |
|
266 |
+ let!(:event6) do |
|
267 |
+ agents(:bob_website_agent).create_event payload: { |
|
268 |
+ 'site_title' => 'XKCD', |
|
269 |
+ 'url' => 'http://imgs.xkcd.com/comics/comic3.png', |
|
270 |
+ 'title' => 'Comic 3', |
|
271 |
+ 'date' => '', |
|
272 |
+ 'hovertext' => 'Hovertext for Comic 3' |
|
273 |
+ } |
|
274 |
+ end |
|
275 |
+ |
|
276 |
+ describe 'limiting' do |
|
277 |
+ it 'can select the last `events_to_show` events' do |
|
278 |
+ agent.options['events_to_show'] = 2 |
|
279 |
+ content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json') |
|
280 |
+ expect(content['items'].map {|i| i["title"] }).to eq(["Comic 3", "Comic 2"]) |
|
281 |
+ end |
|
282 |
+ end |
|
283 |
+ end |
|
284 |
+ |
|
245 | 285 |
describe 'ordering' do |
246 | 286 |
before do |
247 |
- agent.options['events_order'] = ['{{title}}'] |
|
287 |
+ agent.options['events_order'] = ['{{hovertext}}'] |
|
288 |
+ agent.options['events_list_order'] = ['{{title}}'] |
|
248 | 289 |
end |
249 | 290 |
|
250 |
- it 'can reorder the events_to_show last events based on a Liquid expression' do |
|
291 |
+ it 'can reorder the last `events_to_show` events based on a Liquid expression' do |
|
292 |
+ agent.options['events_to_show'] = 2 |
|
293 |
+ asc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json') |
|
294 |
+ expect(asc_content['items'].map {|i| i["title"] }).to eq(["Evolving", "Evolving again"]) |
|
295 |
+ |
|
296 |
+ agent.options['events_to_show'] = 40 |
|
251 | 297 |
asc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json') |
252 | 298 |
expect(asc_content['items'].map {|i| i["title"] }).to eq(["Evolving", "Evolving again", "Evolving yet again with a past date"]) |
253 | 299 |
|
254 |
- agent.options['events_order'] = [['{{title}}', 'string', true]] |
|
300 |
+ agent.options['events_list_order'] = [['{{title}}', 'string', true]] |
|
255 | 301 |
|
256 | 302 |
desc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json') |
257 | 303 |
expect(desc_content['items']).to eq(asc_content['items'].reverse) |
@@ -8,11 +8,11 @@ describe Agents::EmailDigestAgent do |
||
8 | 8 |
end |
9 | 9 |
|
10 | 10 |
before do |
11 |
- @checker = Agents::EmailDigestAgent.new(:name => "something", :options => { :expected_receive_period_in_days => "2", :subject => "something interesting" }) |
|
11 |
+ @checker = Agents::EmailDigestAgent.new(:name => "something", :options => {:expected_receive_period_in_days => "2", :subject => "something interesting"}) |
|
12 | 12 |
@checker.user = users(:bob) |
13 | 13 |
@checker.save! |
14 | 14 |
|
15 |
- @checker1 = Agents::EmailDigestAgent.new(:name => "something", :options => { :expected_receive_period_in_days => "2", :subject => "something interesting", :content_type => "text/plain" }) |
|
15 |
+ @checker1 = Agents::EmailDigestAgent.new(:name => "something", :options => {:expected_receive_period_in_days => "2", :subject => "something interesting", :content_type => "text/plain"}) |
|
16 | 16 |
@checker1.user = users(:bob) |
17 | 17 |
@checker1.save! |
18 | 18 |
end |
@@ -25,16 +25,16 @@ describe Agents::EmailDigestAgent do |
||
25 | 25 |
it "queues any payloads it receives" do |
26 | 26 |
event1 = Event.new |
27 | 27 |
event1.agent = agents(:bob_rain_notifier_agent) |
28 |
- event1.payload = { :data => "Something you should know about" } |
|
28 |
+ event1.payload = {:data => "Something you should know about"} |
|
29 | 29 |
event1.save! |
30 | 30 |
|
31 | 31 |
event2 = Event.new |
32 | 32 |
event2.agent = agents(:bob_weather_agent) |
33 |
- event2.payload = { :data => "Something else you should know about" } |
|
33 |
+ event2.payload = {:data => "Something else you should know about"} |
|
34 | 34 |
event2.save! |
35 | 35 |
|
36 | 36 |
Agents::EmailDigestAgent.async_receive(@checker.id, [event1.id, event2.id]) |
37 |
- expect(@checker.reload.memory[:queue]).to eq([{ 'data' => "Something you should know about" }, { 'data' => "Something else you should know about" }]) |
|
37 |
+ expect(@checker.reload.memory['events']).to match([event1.id, event2.id]) |
|
38 | 38 |
end |
39 | 39 |
end |
40 | 40 |
|
@@ -44,25 +44,34 @@ describe Agents::EmailDigestAgent do |
||
44 | 44 |
Agents::EmailDigestAgent.async_check(@checker.id) |
45 | 45 |
expect(ActionMailer::Base.deliveries).to eq([]) |
46 | 46 |
|
47 |
- @checker.memory[:queue] = [{ :data => "Something you should know about" }, |
|
48 |
- { :title => "Foo", :url => "http://google.com", :bar => 2 }, |
|
49 |
- { "message" => "hi", :woah => "there" }, |
|
50 |
- { "test" => 2 }] |
|
51 |
- @checker.memory[:events] = [1,2,3,4] |
|
52 |
- @checker.save! |
|
53 |
- |
|
54 |
- Agents::EmailDigestAgent.async_check(@checker.id) |
|
47 |
+ payloads = [ |
|
48 |
+ {:data => "Something you should know about"}, |
|
49 |
+ {:title => "Foo", :url => "http://google.com", :bar => 2}, |
|
50 |
+ {"message" => "hi", :woah => "there"}, |
|
51 |
+ {"test" => 2} |
|
52 |
+ ] |
|
53 |
+ |
|
54 |
+ events = payloads.map do |payload| |
|
55 |
+ Event.new.tap do |event| |
|
56 |
+ event.agent = agents(:bob_weather_agent) |
|
57 |
+ event.payload = payload |
|
58 |
+ event.save! |
|
59 |
+ end |
|
60 |
+ end |
|
61 |
+ |
|
62 |
+ Agents::DigestAgent.async_receive(@checker.id, events.map(&:id)) |
|
63 |
+ @checker.sources << agents(:bob_weather_agent) |
|
64 |
+ Agents::DigestAgent.async_check(@checker.id) |
|
55 | 65 |
|
56 | 66 |
expect(ActionMailer::Base.deliveries.last.to).to eq(["bob@example.com"]) |
57 | 67 |
expect(ActionMailer::Base.deliveries.last.subject).to eq("something interesting") |
58 | 68 |
expect(get_message_part(ActionMailer::Base.deliveries.last, /plain/).strip).to eq("Event\n data: Something you should know about\n\nFoo\n bar: 2\n url: http://google.com\n\nhi\n woah: there\n\nEvent\n test: 2") |
59 |
- expect(@checker.reload.memory[:queue]).to be_empty |
|
69 |
+ expect(@checker.reload.memory[:events]).to be_empty |
|
60 | 70 |
end |
61 | 71 |
|
62 | 72 |
it "logs and re-raises mailer errors" do |
63 | 73 |
mock(SystemMailer).send_message(anything) { raise Net::SMTPAuthenticationError.new("Wrong password") } |
64 | 74 |
|
65 |
- @checker.memory[:queue] = [{ :data => "Something you should know about" }] |
|
66 | 75 |
@checker.memory[:events] = [1] |
67 | 76 |
@checker.save! |
68 | 77 |
|
@@ -71,8 +80,6 @@ describe Agents::EmailDigestAgent do |
||
71 | 80 |
}.to raise_error(/Wrong password/) |
72 | 81 |
|
73 | 82 |
expect(@checker.reload.memory[:events]).not_to be_empty |
74 |
- expect(@checker.reload.memory[:queue]).not_to be_empty |
|
75 |
- |
|
76 | 83 |
expect(@checker.logs.last.message).to match(/Error sending digest mail .* Wrong password/) |
77 | 84 |
end |
78 | 85 |
|
@@ -84,7 +91,7 @@ describe Agents::EmailDigestAgent do |
||
84 | 91 |
Agent.async_check(agents(:bob_weather_agent).id) |
85 | 92 |
|
86 | 93 |
Agent.receive! |
87 |
- expect(@checker.reload.memory[:queue]).not_to be_empty |
|
94 |
+ expect(@checker.reload.memory[:events]).not_to be_empty |
|
88 | 95 |
|
89 | 96 |
Agents::EmailDigestAgent.async_check(@checker.id) |
90 | 97 |
|
@@ -94,18 +101,14 @@ describe Agents::EmailDigestAgent do |
||
94 | 101 |
expect(plain_email_text).to match(/avehumidity/) |
95 | 102 |
expect(html_email_text).to match(/avehumidity/) |
96 | 103 |
|
97 |
- expect(@checker.reload.memory[:queue]).to be_empty |
|
104 |
+ expect(@checker.reload.memory[:events]).to be_empty |
|
98 | 105 |
end |
99 |
- |
|
106 |
+ |
|
100 | 107 |
it "should send email with correct content type" do |
101 | 108 |
Agents::EmailDigestAgent.async_check(@checker1.id) |
102 | 109 |
expect(ActionMailer::Base.deliveries).to eq([]) |
103 | 110 |
|
104 |
- @checker1.memory[:queue] = [{ :data => "Something you should know about" }, |
|
105 |
- { :title => "Foo", :url => "http://google.com", :bar => 2 }, |
|
106 |
- { "message" => "hi", :woah => "there" }, |
|
107 |
- { "test" => 2 }] |
|
108 |
- @checker1.memory[:events] = [1,2,3,4] |
|
111 |
+ @checker1.memory[:events] = [1, 2, 3, 4] |
|
109 | 112 |
@checker1.save! |
110 | 113 |
|
111 | 114 |
Agents::EmailDigestAgent.async_check(@checker1.id) |
@@ -57,6 +57,11 @@ describe Agents::PostAgent do |
||
57 | 57 |
end |
58 | 58 |
|
59 | 59 |
it_behaves_like WebRequestConcern |
60 |
+ it_behaves_like 'FileHandlingConsumer' |
|
61 |
+ |
|
62 |
+ it 'renders the description markdown without errors' do |
|
63 |
+ expect { @checker.description }.not_to raise_error |
|
64 |
+ end |
|
60 | 65 |
|
61 | 66 |
describe "making requests" do |
62 | 67 |
it "can make requests of each type" do |
@@ -149,6 +154,19 @@ describe Agents::PostAgent do |
||
149 | 154 |
headers = @sent_requests[:post].first.headers |
150 | 155 |
expect(headers["Foo"]).to eq("a_variable") |
151 | 156 |
end |
157 |
+ |
|
158 |
+ it 'makes a multipart request when receiving a file_pointer' do |
|
159 |
+ WebMock.reset! |
|
160 |
+ stub_request(:post, "http://www.example.com/"). |
|
161 |
+ with(:body => "-------------RubyMultipartPost\r\nContent-Disposition: form-data; name=\"default\"\r\n\r\nvalue\r\n-------------RubyMultipartPost\r\nContent-Disposition: form-data; name=\"file\"; filename=\"local.path\"\r\nContent-Length: 8\r\nContent-Type: \r\nContent-Transfer-Encoding: binary\r\n\r\ntestdata\r\n-------------RubyMultipartPost--\r\n\r\n", |
|
162 |
+ :headers => {'Accept-Encoding'=>'gzip,deflate', 'Content-Length'=>'307', 'Content-Type'=>'multipart/form-data; boundary=-----------RubyMultipartPost', 'User-Agent'=>'Huginn - https://github.com/cantino/huginn'}). |
|
163 |
+ to_return(:status => 200, :body => "", :headers => {}) |
|
164 |
+ event = Event.new(payload: {file_pointer: {agent_id: 111, file: 'test'}}) |
|
165 |
+ io_mock = mock() |
|
166 |
+ mock(@checker).get_io(event) { StringIO.new("testdata") } |
|
167 |
+ @checker.options['no_merge'] = true |
|
168 |
+ @checker.receive([event]) |
|
169 |
+ end |
|
152 | 170 |
end |
153 | 171 |
|
154 | 172 |
describe "#check" do |
@@ -2,27 +2,29 @@ require 'rails_helper' |
||
2 | 2 |
|
3 | 3 |
describe Agents::PushoverAgent do |
4 | 4 |
before do |
5 |
- @checker = Agents::PushoverAgent.new(:name => 'Some Name', |
|
6 |
- :options => { :token => 'x', |
|
7 |
- :user => 'x', |
|
8 |
- :message => 'Some Message', |
|
9 |
- :device => 'Some Device', |
|
10 |
- :title => 'Some Message Title', |
|
11 |
- :url => 'http://someurl.com', |
|
12 |
- :url_title => 'Some Url Title', |
|
13 |
- :priority => 0, |
|
14 |
- :timestamp => 'false', |
|
15 |
- :sound => 'pushover', |
|
16 |
- :retry => 0, |
|
17 |
- :expire => 0, |
|
18 |
- :expected_receive_period_in_days => '1'}) |
|
19 |
- |
|
5 |
+ @checker = Agents::PushoverAgent.new(name: 'Some Name', |
|
6 |
+ options: { |
|
7 |
+ token: 'x', |
|
8 |
+ user: 'x', |
|
9 |
+ message: "{{ message | default: text | default: 'Some Message' }}", |
|
10 |
+ device: "{{ device | default: 'Some Device' }}", |
|
11 |
+ title: "{{ title | default: 'Some Message Title' }}", |
|
12 |
+ url: "{{ url | default: 'http://someurl.com' }}", |
|
13 |
+ url_title: "{{ url_title | default: 'Some Url Title' }}", |
|
14 |
+ priority: "{{ priority | default: 0 }}", |
|
15 |
+ timestamp: "{{ timestamp | default: 'false' }}", |
|
16 |
+ sound: "{{ sound | default: 'pushover' }}", |
|
17 |
+ retry: "{{ retry | default: 0 }}", |
|
18 |
+ expire: "{{ expire | default: 0 }}", |
|
19 |
+ expected_receive_period_in_days: '1' |
|
20 |
+ }) |
|
21 |
+ |
|
20 | 22 |
@checker.user = users(:bob) |
21 | 23 |
@checker.save! |
22 | 24 |
|
23 | 25 |
@event = Event.new |
24 | 26 |
@event.agent = agents(:bob_weather_agent) |
25 |
- @event.payload = { :message => 'Looks like its going to rain' } |
|
27 |
+ @event.payload = { message: 'Looks like its going to rain' } |
|
26 | 28 |
@event.save! |
27 | 29 |
|
28 | 30 |
@sent_notifications = [] |
@@ -33,12 +35,12 @@ describe Agents::PushoverAgent do |
||
33 | 35 |
it 'should make sure multiple events are being received' do |
34 | 36 |
event1 = Event.new |
35 | 37 |
event1.agent = agents(:bob_rain_notifier_agent) |
36 |
- event1.payload = { :message => 'Some message' } |
|
38 |
+ event1.payload = { message: 'Some message' } |
|
37 | 39 |
event1.save! |
38 | 40 |
|
39 | 41 |
event2 = Event.new |
40 | 42 |
event2.agent = agents(:bob_weather_agent) |
41 |
- event2.payload = { :message => 'Some other message' } |
|
43 |
+ event2.payload = { message: 'Some other message' } |
|
42 | 44 |
event2.save! |
43 | 45 |
|
44 | 46 |
@checker.receive([@event,event1,event2]) |
@@ -50,7 +52,7 @@ describe Agents::PushoverAgent do |
||
50 | 52 |
it 'should make sure event message overrides default message' do |
51 | 53 |
event = Event.new |
52 | 54 |
event.agent = agents(:bob_rain_notifier_agent) |
53 |
- event.payload = { :message => 'Some new message'} |
|
55 |
+ event.payload = { message: 'Some new message'} |
|
54 | 56 |
event.save! |
55 | 57 |
|
56 | 58 |
@checker.receive([event]) |
@@ -60,7 +62,7 @@ describe Agents::PushoverAgent do |
||
60 | 62 |
it 'should make sure event text overrides default message' do |
61 | 63 |
event = Event.new |
62 | 64 |
event.agent = agents(:bob_rain_notifier_agent) |
63 |
- event.payload = { :text => 'Some new text'} |
|
65 |
+ event.payload = { text: 'Some new text'} |
|
64 | 66 |
event.save! |
65 | 67 |
|
66 | 68 |
@checker.receive([event]) |
@@ -70,7 +72,7 @@ describe Agents::PushoverAgent do |
||
70 | 72 |
it 'should make sure event title overrides default title' do |
71 | 73 |
event = Event.new |
72 | 74 |
event.agent = agents(:bob_rain_notifier_agent) |
73 |
- event.payload = { :message => 'Some message', :title => 'Some new title' } |
|
75 |
+ event.payload = { message: 'Some message', title: 'Some new title' } |
|
74 | 76 |
event.save! |
75 | 77 |
|
76 | 78 |
@checker.receive([event]) |
@@ -80,7 +82,7 @@ describe Agents::PushoverAgent do |
||
80 | 82 |
it 'should make sure event url overrides default url' do |
81 | 83 |
event = Event.new |
82 | 84 |
event.agent = agents(:bob_rain_notifier_agent) |
83 |
- event.payload = { :message => 'Some message', :url => 'Some new url' } |
|
85 |
+ event.payload = { message: 'Some message', url: 'Some new url' } |
|
84 | 86 |
event.save! |
85 | 87 |
|
86 | 88 |
@checker.receive([event]) |
@@ -90,7 +92,7 @@ describe Agents::PushoverAgent do |
||
90 | 92 |
it 'should make sure event url_title overrides default url_title' do |
91 | 93 |
event = Event.new |
92 | 94 |
event.agent = agents(:bob_rain_notifier_agent) |
93 |
- event.payload = { :message => 'Some message', :url_title => 'Some new url_title' } |
|
95 |
+ event.payload = { message: 'Some message', url_title: 'Some new url_title' } |
|
94 | 96 |
event.save! |
95 | 97 |
|
96 | 98 |
@checker.receive([event]) |
@@ -100,17 +102,17 @@ describe Agents::PushoverAgent do |
||
100 | 102 |
it 'should make sure event priority overrides default priority' do |
101 | 103 |
event = Event.new |
102 | 104 |
event.agent = agents(:bob_rain_notifier_agent) |
103 |
- event.payload = { :message => 'Some message', :priority => 1 } |
|
105 |
+ event.payload = { message: 'Some message', priority: '1' } |
|
104 | 106 |
event.save! |
105 | 107 |
|
106 | 108 |
@checker.receive([event]) |
107 |
- expect(@sent_notifications[0]['priority']).to eq(1) |
|
109 |
+ expect(@sent_notifications[0]['priority']).to eq('1') |
|
108 | 110 |
end |
109 | 111 |
|
110 | 112 |
it 'should make sure event timestamp overrides default timestamp' do |
111 | 113 |
event = Event.new |
112 | 114 |
event.agent = agents(:bob_rain_notifier_agent) |
113 |
- event.payload = { :message => 'Some message', :timestamp => 'false' } |
|
115 |
+ event.payload = { message: 'Some message', timestamp: 'false' } |
|
114 | 116 |
event.save! |
115 | 117 |
|
116 | 118 |
@checker.receive([event]) |
@@ -120,7 +122,7 @@ describe Agents::PushoverAgent do |
||
120 | 122 |
it 'should make sure event sound overrides default sound' do |
121 | 123 |
event = Event.new |
122 | 124 |
event.agent = agents(:bob_rain_notifier_agent) |
123 |
- event.payload = { :message => 'Some message', :sound => 'Some new sound' } |
|
125 |
+ event.payload = { message: 'Some message', sound: 'Some new sound' } |
|
124 | 126 |
event.save! |
125 | 127 |
|
126 | 128 |
@checker.receive([event]) |
@@ -130,21 +132,21 @@ describe Agents::PushoverAgent do |
||
130 | 132 |
it 'should make sure event retry overrides default retry' do |
131 | 133 |
event = Event.new |
132 | 134 |
event.agent = agents(:bob_rain_notifier_agent) |
133 |
- event.payload = { :message => 'Some message', :retry => 1 } |
|
135 |
+ event.payload = { message: 'Some message', retry: 1 } |
|
134 | 136 |
event.save! |
135 | 137 |
|
136 | 138 |
@checker.receive([event]) |
137 |
- expect(@sent_notifications[0]['retry']).to eq(1) |
|
139 |
+ expect(@sent_notifications[0]['retry']).to eq('1') |
|
138 | 140 |
end |
139 | 141 |
|
140 | 142 |
it 'should make sure event expire overrides default expire' do |
141 | 143 |
event = Event.new |
142 | 144 |
event.agent = agents(:bob_rain_notifier_agent) |
143 |
- event.payload = { :message => 'Some message', :expire => 60 } |
|
145 |
+ event.payload = { message: 'Some message', expire: '60' } |
|
144 | 146 |
event.save! |
145 | 147 |
|
146 | 148 |
@checker.receive([event]) |
147 |
- expect(@sent_notifications[0]['expire']).to eq(60) |
|
149 |
+ expect(@sent_notifications[0]['expire']).to eq('60') |
|
148 | 150 |
end |
149 | 151 |
end |
150 | 152 |
|
@@ -158,7 +160,7 @@ describe Agents::PushoverAgent do |
||
158 | 160 |
expect(@checker.reload).to be_working |
159 | 161 |
two_days_from_now = 2.days.from_now |
160 | 162 |
stub(Time).now { two_days_from_now } |
161 |
- |
|
163 |
+ |
|
162 | 164 |
# More time has passed than the expected receive period without any new events |
163 | 165 |
expect(@checker.reload).not_to be_working |
164 | 166 |
end |
@@ -55,16 +55,57 @@ describe Agents::RssAgent do |
||
55 | 55 |
end |
56 | 56 |
|
57 | 57 |
describe "emitting RSS events" do |
58 |
- it "should emit items as events" do |
|
58 |
+ it "should emit items as events for an Atom feed" do |
|
59 |
+ agent.options['include_feed_info'] = true |
|
60 |
+ |
|
59 | 61 |
expect { |
60 | 62 |
agent.check |
61 | 63 |
}.to change { agent.events.count }.by(20) |
62 | 64 |
|
63 | 65 |
first, *, last = agent.events.last(20) |
66 |
+ [first, last].each do |event| |
|
67 |
+ expect(first.payload['feed']).to include({ |
|
68 |
+ "type" => "atom", |
|
69 |
+ "title" => "Recent Commits to huginn:master", |
|
70 |
+ "url" => "https://github.com/cantino/huginn/commits/master", |
|
71 |
+ "links" => [ |
|
72 |
+ { |
|
73 |
+ "type" => "text/html", |
|
74 |
+ "rel" => "alternate", |
|
75 |
+ "href" => "https://github.com/cantino/huginn/commits/master", |
|
76 |
+ }, |
|
77 |
+ { |
|
78 |
+ "type" => "application/atom+xml", |
|
79 |
+ "rel" => "self", |
|
80 |
+ "href" => "https://github.com/cantino/huginn/commits/master.atom", |
|
81 |
+ }, |
|
82 |
+ ], |
|
83 |
+ }) |
|
84 |
+ end |
|
64 | 85 |
expect(first.payload['url']).to eq("https://github.com/cantino/huginn/commit/d0a844662846cf3c83b94c637c1803f03db5a5b0") |
65 | 86 |
expect(first.payload['urls']).to eq(["https://github.com/cantino/huginn/commit/d0a844662846cf3c83b94c637c1803f03db5a5b0"]) |
87 |
+ expect(first.payload['links']).to eq([ |
|
88 |
+ { |
|
89 |
+ "href" => "https://github.com/cantino/huginn/commit/d0a844662846cf3c83b94c637c1803f03db5a5b0", |
|
90 |
+ "rel" => "alternate", |
|
91 |
+ "type" => "text/html", |
|
92 |
+ } |
|
93 |
+ ]) |
|
94 |
+ expect(first.payload['authors']).to eq(["cantino (https://github.com/cantino)"]) |
|
95 |
+ expect(first.payload['date_published']).to be_nil |
|
96 |
+ expect(first.payload['last_updated']).to eq("2014-07-16T22:26:22-07:00") |
|
66 | 97 |
expect(last.payload['url']).to eq("https://github.com/cantino/huginn/commit/d465158f77dcd9078697e6167b50abbfdfa8b1af") |
67 | 98 |
expect(last.payload['urls']).to eq(["https://github.com/cantino/huginn/commit/d465158f77dcd9078697e6167b50abbfdfa8b1af"]) |
99 |
+ expect(last.payload['links']).to eq([ |
|
100 |
+ { |
|
101 |
+ "href" => "https://github.com/cantino/huginn/commit/d465158f77dcd9078697e6167b50abbfdfa8b1af", |
|
102 |
+ "rel" => "alternate", |
|
103 |
+ "type" => "text/html", |
|
104 |
+ } |
|
105 |
+ ]) |
|
106 |
+ expect(last.payload['authors']).to eq(["CloCkWeRX (https://github.com/CloCkWeRX)"]) |
|
107 |
+ expect(last.payload['date_published']).to be_nil |
|
108 |
+ expect(last.payload['last_updated']).to eq("2014-07-01T16:37:47+09:30") |
|
68 | 109 |
end |
69 | 110 |
|
70 | 111 |
it "should emit items as events in the order specified in the events_order option" do |
@@ -82,6 +123,33 @@ describe Agents::RssAgent do |
||
82 | 123 |
expect(last.payload['urls']).to eq(["https://github.com/cantino/huginn/commit/0e80f5341587aace2c023b06eb9265b776ac4535"]) |
83 | 124 |
end |
84 | 125 |
|
126 |
+ it "should emit items as events for a FeedBurner RSS 2.0 feed" do |
|
127 |
+ agent.options['url'] = "http://feeds.feedburner.com/SlickdealsnetFP?format=atom" # This is actually RSS 2.0 w/ Atom extension |
|
128 |
+ agent.options['include_feed_info'] = true |
|
129 |
+ agent.save! |
|
130 |
+ |
|
131 |
+ expect { |
|
132 |
+ agent.check |
|
133 |
+ }.to change { agent.events.count }.by(79) |
|
134 |
+ |
|
135 |
+ first, *, last = agent.events.last(79) |
|
136 |
+ expect(first.payload['feed']).to include({ |
|
137 |
+ "type" => "rss", |
|
138 |
+ "title" => "SlickDeals.net", |
|
139 |
+ "description" => "Slick online shopping deals.", |
|
140 |
+ "url" => "http://slickdeals.net/", |
|
141 |
+ }) |
|
142 |
+ # Feedjira extracts feedburner:origLink |
|
143 |
+ expect(first.payload['url']).to eq("http://slickdeals.net/permadeal/130160/green-man-gaming---pc-games-tomb-raider-game-of-the-year-6-hitman-absolution-elite-edition") |
|
144 |
+ expect(last.payload['feed']).to include({ |
|
145 |
+ "type" => "rss", |
|
146 |
+ "title" => "SlickDeals.net", |
|
147 |
+ "description" => "Slick online shopping deals.", |
|
148 |
+ "url" => "http://slickdeals.net/", |
|
149 |
+ }) |
|
150 |
+ expect(last.payload['url']).to eq("http://slickdeals.net/permadeal/129980/amazon---rearth-ringke-fusion-bumper-hybrid-case-for-iphone-6") |
|
151 |
+ end |
|
152 |
+ |
|
85 | 153 |
it "should track ids and not re-emit the same item when seen again" do |
86 | 154 |
agent.check |
87 | 155 |
expect(agent.memory['seen_ids']).to eq(agent.events.map {|e| e.payload['id'] }) |
@@ -155,17 +223,39 @@ describe Agents::RssAgent do |
||
155 | 223 |
@valid_options['url'] = 'http://onethingwell.org/rss' |
156 | 224 |
end |
157 | 225 |
|
226 |
+ it "captures timestamps normalized in the ISO 8601 format" do |
|
227 |
+ agent.check |
|
228 |
+ first, *, third = agent.events.take(3) |
|
229 |
+ expect(first.payload['date_published']).to eq('2015-08-20T17:00:10+01:00') |
|
230 |
+ expect(third.payload['date_published']).to eq('2015-08-20T13:00:07+01:00') |
|
231 |
+ end |
|
232 |
+ |
|
158 | 233 |
it "captures multiple categories" do |
159 | 234 |
agent.check |
160 | 235 |
first, *, third = agent.events.take(3) |
161 | 236 |
expect(first.payload['categories']).to eq(["csv", "crossplatform", "utilities"]) |
162 | 237 |
expect(third.payload['categories']).to eq(["web"]) |
163 | 238 |
end |
239 |
+ |
|
240 |
+ it "sanitizes HTML content" do |
|
241 |
+ agent.options['clean'] = true |
|
242 |
+ agent.check |
|
243 |
+ event = agent.events.last |
|
244 |
+ expect(event.payload['content']).to eq('<a href="http://showgoers.tv/">Showgoers</a>: <blockquote> <p>Showgoers is a Chrome browser extension to synchronize your Netflix player with someone else so that you can co-watch the same movie on different computers with no hassle. Syncing up your player is as easy as sharing a URL.</p> </blockquote>') |
|
245 |
+ expect(event.payload['description']).to eq('<a href="http://showgoers.tv/">Showgoers</a>: <blockquote> <p>Showgoers is a Chrome browser extension to synchronize your Netflix player with someone else so that you can co-watch the same movie on different computers with no hassle. Syncing up your player is as easy as sharing a URL.</p> </blockquote>') |
|
246 |
+ end |
|
247 |
+ |
|
248 |
+ it "captures an enclosure" do |
|
249 |
+ agent.check |
|
250 |
+ event = agent.events.fourth |
|
251 |
+ expect(event.payload['enclosure']).to eq({ "url" => "http://c.1tw.org/images/2015/itsy.png", "type" => "image/png", "length" => "48249" }) |
|
252 |
+ expect(event.payload['image']).to eq("http://c.1tw.org/images/2015/itsy.png") |
|
253 |
+ end |
|
164 | 254 |
end |
165 | 255 |
|
166 | 256 |
describe 'logging errors with the feed url' do |
167 | 257 |
it 'includes the feed URL when an exception is raised' do |
168 |
- mock(FeedNormalizer::FeedNormalizer).parse(anything, loose: true) { raise StandardError.new("Some error!") } |
|
258 |
+ mock(Feedjira::Feed).parse(anything) { raise StandardError.new("Some error!") } |
|
169 | 259 |
expect(lambda { |
170 | 260 |
agent.check |
171 | 261 |
}).not_to raise_error |
@@ -24,11 +24,11 @@ describe Agents::TwitterActionAgent do |
||
24 | 24 |
|
25 | 25 |
context 'when set up to retweet' do |
26 | 26 |
before do |
27 |
- @agent = build_agent({ |
|
28 |
- 'expected_receive_period_in_days' => '2', |
|
27 |
+ @agent = build_agent( |
|
29 | 28 |
'favorite' => 'false', |
30 | 29 |
'retweet' => 'true', |
31 |
- }) |
|
30 |
+ 'emit_error_events' => 'true' |
|
31 |
+ ) |
|
32 | 32 |
@agent.save! |
33 | 33 |
end |
34 | 34 |
|
@@ -68,9 +68,9 @@ describe Agents::TwitterActionAgent do |
||
68 | 68 |
context 'when set up to favorite' do |
69 | 69 |
before do |
70 | 70 |
@agent = build_agent( |
71 |
- 'expected_receive_period_in_days' => '2', |
|
72 | 71 |
'favorite' => 'true', |
73 | 72 |
'retweet' => 'false', |
73 |
+ 'emit_error_events' => 'true' |
|
74 | 74 |
) |
75 | 75 |
@agent.save! |
76 | 76 |
end |
@@ -107,13 +107,48 @@ describe Agents::TwitterActionAgent do |
||
107 | 107 |
end |
108 | 108 |
end |
109 | 109 |
end |
110 |
+ |
|
111 |
+ context 'with emit_error_events set to false' do |
|
112 |
+ it 'does re-raises the exception on failure' do |
|
113 |
+ agent = build_agent |
|
114 |
+ |
|
115 |
+ stub(agent.twitter).retweet(anything) { |
|
116 |
+ raise Twitter::Error.new('uh oh') |
|
117 |
+ } |
|
118 |
+ |
|
119 |
+ expect { agent.receive([@event1]) }.to raise_error(StandardError, /uh oh/) |
|
120 |
+ |
|
121 |
+ end |
|
122 |
+ end |
|
110 | 123 |
end |
111 | 124 |
|
112 | 125 |
describe "#validate_options" do |
126 |
+ it 'the default options are valid' do |
|
127 |
+ agent = build_agent(described_class.new.default_options) |
|
128 |
+ |
|
129 |
+ expect(agent).to be_valid |
|
130 |
+ end |
|
131 |
+ |
|
132 |
+ context 'emit_error_events' do |
|
133 |
+ it 'can be set to true' do |
|
134 |
+ agent = build_agent(described_class.new.default_options.merge('emit_error_events' => 'true')) |
|
135 |
+ expect(agent).to be_valid |
|
136 |
+ end |
|
137 |
+ |
|
138 |
+ it 'must be a boolean' do |
|
139 |
+ agent = build_agent(described_class.new.default_options.merge('emit_error_events' => 'notbolean')) |
|
140 |
+ expect(agent).not_to be_valid |
|
141 |
+ end |
|
142 |
+ end |
|
143 |
+ |
|
144 |
+ it 'expected_receive_period_in_days must be set' do |
|
145 |
+ agent = build_agent(described_class.new.default_options.merge('expected_receive_period_in_days' => '')) |
|
146 |
+ expect(agent).not_to be_valid |
|
147 |
+ end |
|
148 |
+ |
|
113 | 149 |
context 'when set up to neither favorite or retweet' do |
114 | 150 |
it 'is invalid' do |
115 | 151 |
agent = build_agent( |
116 |
- 'expected_receive_period_in_days' => '2', |
|
117 | 152 |
'favorite' => 'false', |
118 | 153 |
'retweet' => 'false', |
119 | 154 |
) |
@@ -129,11 +164,7 @@ describe Agents::TwitterActionAgent do |
||
129 | 164 |
end |
130 | 165 |
|
131 | 166 |
it 'checks if events have been received within the expected time period' do |
132 |
- agent = build_agent( |
|
133 |
- 'expected_receive_period_in_days' => '2', |
|
134 |
- 'favorite' => 'false', |
|
135 |
- 'retweet' => 'true', |
|
136 |
- ) |
|
167 |
+ agent = build_agent |
|
137 | 168 |
agent.save! |
138 | 169 |
|
139 | 170 |
expect(agent).not_to be_working # No events received |
@@ -147,10 +178,10 @@ describe Agents::TwitterActionAgent do |
||
147 | 178 |
end |
148 | 179 |
end |
149 | 180 |
|
150 |
- def build_agent(options) |
|
181 |
+ def build_agent(options = {}) |
|
151 | 182 |
described_class.new do |agent| |
152 | 183 |
agent.name = 'twitter stuff' |
153 |
- agent.options = options |
|
184 |
+ agent.options = agent.default_options.merge(options) |
|
154 | 185 |
agent.service = services(:generic) |
155 | 186 |
agent.user = users(:bob) |
156 | 187 |
end |
@@ -19,6 +19,16 @@ describe Agents::WeatherAgent do |
||
19 | 19 |
it "creates a valid agent" do |
20 | 20 |
expect(agent).to be_valid |
21 | 21 |
end |
22 |
+ |
|
23 |
+ it "is valid with put-your-key-here or your-key" do |
|
24 |
+ agent.options['api_key'] = 'put-your-key-here' |
|
25 |
+ expect(agent).to be_valid |
|
26 |
+ expect(agent.working?).to be_falsey |
|
27 |
+ |
|
28 |
+ agent.options['api_key'] = 'your-key' |
|
29 |
+ expect(agent).to be_valid |
|
30 |
+ expect(agent.working?).to be_falsey |
|
31 |
+ end |
|
22 | 32 |
|
23 | 33 |
describe "#service" do |
24 | 34 |
it "doesn't have a Service object attached" do |
@@ -49,6 +49,12 @@ describe Agents::WebhookAgent do |
||
49 | 49 |
expect(out).to eq(['', 201]) |
50 | 50 |
end |
51 | 51 |
|
52 |
+ it 'should respond with interpolated response message if configured with `response` option' do |
|
53 |
+ agent.options['response'] = '{{some_key.people[1].name}}' |
|
54 |
+ out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html") |
|
55 |
+ expect(out).to eq(['jon', 201]) |
|
56 |
+ end |
|
57 |
+ |
|
52 | 58 |
it 'should respond with `Event Created` if the response option is nil or missing' do |
53 | 59 |
agent.options['response'] = nil |
54 | 60 |
out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html") |
@@ -59,6 +65,26 @@ describe Agents::WebhookAgent do |
||
59 | 65 |
expect(out).to eq(['Event Created', 201]) |
60 | 66 |
end |
61 | 67 |
|
68 |
+ it 'should respond with customized response code if configured with `code` option' do |
|
69 |
+ agent.options['code'] = '200' |
|
70 |
+ out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html") |
|
71 |
+ expect(out).to eq(['Event Created', 200]) |
|
72 |
+ end |
|
73 |
+ |
|
74 |
+ it 'should respond with `201` if the code option is empty, nil or missing' do |
|
75 |
+ agent.options['code'] = '' |
|
76 |
+ out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html") |
|
77 |
+ expect(out).to eq(['Event Created', 201]) |
|
78 |
+ |
|
79 |
+ agent.options['code'] = nil |
|
80 |
+ out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html") |
|
81 |
+ expect(out).to eq(['Event Created', 201]) |
|
82 |
+ |
|
83 |
+ agent.options.delete('code') |
|
84 |
+ out = agent.receive_web_request({ 'secret' => 'foobar', 'some_key' => payload }, "post", "text/html") |
|
85 |
+ expect(out).to eq(['Event Created', 201]) |
|
86 |
+ end |
|
87 |
+ |
|
62 | 88 |
describe "receiving events" do |
63 | 89 |
|
64 | 90 |
context "default settings" do |
@@ -1105,8 +1105,8 @@ fire: hot |
||
1105 | 1105 |
|
1106 | 1106 |
describe "#check" do |
1107 | 1107 |
before do |
1108 |
- expect { @checker.check }.to change { Event.count }.by(7) |
|
1109 |
- @events = Event.last(7) |
|
1108 |
+ expect { @checker.check }.to change { Event.count }.by(8) |
|
1109 |
+ @events = Event.last(8) |
|
1110 | 1110 |
end |
1111 | 1111 |
|
1112 | 1112 |
it "should check hostname" do |
@@ -1143,6 +1143,11 @@ fire: hot |
||
1143 | 1143 |
event = @events[6] |
1144 | 1144 |
expect(event.payload['url']).to eq("https://www.google.ca/search?q=%EC%9C%84%ED%82%A4%EB%B0%B1%EA%B3%BC:%EB%8C%80%EB%AC%B8") |
1145 | 1145 |
end |
1146 |
+ |
|
1147 |
+ it "should check url with unescaped brackets in the path component" do |
|
1148 |
+ event = @events[7] |
|
1149 |
+ expect(event.payload['url']).to eq("http://[::1]/path%5B%5D?query[]=foo") |
|
1150 |
+ end |
|
1146 | 1151 |
end |
1147 | 1152 |
end |
1148 | 1153 |
end |
@@ -98,6 +98,7 @@ describe Service do |
||
98 | 98 |
expect(service.token).to eq('a1b2c3d4...') |
99 | 99 |
expect(service.secret).to eq('abcdef1234') |
100 | 100 |
end |
101 |
+ |
|
101 | 102 |
it "should work with 37signals services" do |
102 | 103 |
signals = JSON.parse(File.read(Rails.root.join('spec/data_fixtures/services/37signals.json'))) |
103 | 104 |
expect { |
@@ -113,6 +114,7 @@ describe Service do |
||
113 | 114 |
expect(service.options[:user_id]).to eq(12345) |
114 | 115 |
service.expires_at = Time.at(1401554352) |
115 | 116 |
end |
117 |
+ |
|
116 | 118 |
it "should work with github services" do |
117 | 119 |
signals = JSON.parse(File.read(Rails.root.join('spec/data_fixtures/services/github.json'))) |
118 | 120 |
expect { |
@@ -126,4 +128,27 @@ describe Service do |
||
126 | 128 |
expect(service.token).to eq('agithubtoken') |
127 | 129 |
end |
128 | 130 |
end |
131 |
+ |
|
132 |
+ describe 'omniauth options provider registry for non-conforming omniauth responses' do |
|
133 |
+ describe '.register_options_provider' do |
|
134 |
+ before do |
|
135 |
+ Service.register_options_provider('test-omniauth-provider') do |omniauth| |
|
136 |
+ { name: omniauth['special_field'] } |
|
137 |
+ end |
|
138 |
+ end |
|
139 |
+ |
|
140 |
+ after do |
|
141 |
+ Service.option_providers.delete('test-omniauth-provider') |
|
142 |
+ end |
|
143 |
+ |
|
144 |
+ it 'allows gem developers to add their own options provider to the registry' do |
|
145 |
+ actual_options = Service.get_options({ |
|
146 |
+ 'provider' => 'test-omniauth-provider', |
|
147 |
+ 'special_field' => 'A Great Name' |
|
148 |
+ }) |
|
149 |
+ |
|
150 |
+ expect(actual_options[:name]).to eq('A Great Name') |
|
151 |
+ end |
|
152 |
+ end |
|
153 |
+ end |
|
129 | 154 |
end |
@@ -8,14 +8,6 @@ describe UserCredential do |
||
8 | 8 |
it { should validate_presence_of(:user_id) } |
9 | 9 |
end |
10 | 10 |
|
11 |
- describe "mass assignment" do |
|
12 |
- it { should allow_mass_assignment_of :credential_name } |
|
13 |
- |
|
14 |
- it { should allow_mass_assignment_of :credential_value } |
|
15 |
- |
|
16 |
- it { should_not allow_mass_assignment_of :user_id } |
|
17 |
- end |
|
18 |
- |
|
19 | 11 |
describe "cleaning fields" do |
20 | 12 |
it "should trim whitespace" do |
21 | 13 |
user_credential = user_credentials(:bob_aws_key) |
@@ -1,6 +1,8 @@ |
||
1 | 1 |
require 'rails_helper' |
2 | 2 |
|
3 | 3 |
describe User do |
4 |
+ let(:bob) { users(:bob) } |
|
5 |
+ |
|
4 | 6 |
describe "validations" do |
5 | 7 |
describe "invitation_code" do |
6 | 8 |
context "when configured to use invitation codes" do |
@@ -64,4 +66,29 @@ describe User do |
||
64 | 66 |
expect(users(:bob).deactivated_at).to be_nil |
65 | 67 |
end |
66 | 68 |
end |
69 |
+ |
|
70 |
+ context '#undefined_agent_types' do |
|
71 |
+ it 'returns an empty array when no agents are undefined' do |
|
72 |
+ expect(bob.undefined_agent_types).to be_empty |
|
73 |
+ end |
|
74 |
+ |
|
75 |
+ it 'returns the undefined agent types' do |
|
76 |
+ agent = agents(:bob_website_agent) |
|
77 |
+ agent.update_attribute(:type, 'Agents::UndefinedAgent') |
|
78 |
+ expect(bob.undefined_agent_types).to match_array(['Agents::UndefinedAgent']) |
|
79 |
+ end |
|
80 |
+ end |
|
81 |
+ |
|
82 |
+ context '#undefined_agents' do |
|
83 |
+ it 'returns an empty array when no agents are undefined' do |
|
84 |
+ expect(bob.undefined_agents).to be_empty |
|
85 |
+ end |
|
86 |
+ |
|
87 |
+ it 'returns the undefined agent types' do |
|
88 |
+ agent = agents(:bob_website_agent) |
|
89 |
+ agent.update_attribute(:type, 'Agents::UndefinedAgent') |
|
90 |
+ expect(bob.undefined_agents).not_to be_empty |
|
91 |
+ expect(bob.undefined_agents.first).to be_a(Agent) |
|
92 |
+ end |
|
93 |
+ end |
|
67 | 94 |
end |
@@ -13,7 +13,7 @@ require 'rspec/rails' |
||
13 | 13 |
require 'rr' |
14 | 14 |
require 'webmock/rspec' |
15 | 15 |
|
16 |
-WebMock.disable_net_connect! |
|
16 |
+WebMock.disable_net_connect!(allow_localhost: true) |
|
17 | 17 |
|
18 | 18 |
# Requires supporting ruby files with custom matchers and macros, etc, |
19 | 19 |
# in spec/support/ and its subdirectories. |
@@ -66,7 +66,7 @@ RSpec.configure do |config| |
||
66 | 66 |
|
67 | 67 |
config.render_views |
68 | 68 |
|
69 |
- config.include Devise::TestHelpers, type: :controller |
|
69 |
+ config.include Devise::Test::ControllerHelpers, type: :controller |
|
70 | 70 |
config.include SpecHelpers |
71 | 71 |
config.include Delorean |
72 | 72 |
end |
@@ -1,6 +1,8 @@ |
||
1 | 1 |
require 'rails_helper' |
2 | 2 |
|
3 | 3 |
shared_examples_for 'FileHandlingConsumer' do |
4 |
+ let(:event) { Event.new(user: @checker.user, payload: {'file_pointer' => {'file' => 'text.txt', 'agent_id' => @checker.id}}) } |
|
5 |
+ |
|
4 | 6 |
it 'returns a file pointer' do |
5 | 7 |
expect(@checker.get_file_pointer('testfile')).to eq(file_pointer: { file: "testfile", agent_id: @checker.id}) |
6 | 8 |
end |
@@ -9,8 +11,26 @@ shared_examples_for 'FileHandlingConsumer' do |
||
9 | 11 |
@checker2 = @checker.dup |
10 | 12 |
@checker2.user = users(:bob) |
11 | 13 |
@checker2.save! |
12 |
- expect(@checker2.user.id).not_to eq(@checker.user.id) |
|
13 |
- event = Event.new(user: @checker.user, payload: {'file_pointer' => {'file' => 'test', 'agent_id' => @checker2.id}}) |
|
14 |
+ event.payload['file_pointer']['agent_id'] = @checker2.id |
|
14 | 15 |
expect { @checker.get_io(event) }.to raise_error(ActiveRecord::RecordNotFound) |
15 | 16 |
end |
16 |
-end |
|
17 |
+ |
|
18 |
+ context '#has_file_pointer?' do |
|
19 |
+ it 'returns true if the event contains a file pointer' do |
|
20 |
+ expect(@checker.has_file_pointer?(event)).to be_truthy |
|
21 |
+ end |
|
22 |
+ |
|
23 |
+ it 'returns false if the event does not contain a file pointer' do |
|
24 |
+ expect(@checker.has_file_pointer?(Event.new)).to be_falsy |
|
25 |
+ end |
|
26 |
+ end |
|
27 |
+ |
|
28 |
+ it '#get_upload_io returns a Faraday::UploadIO instance' do |
|
29 |
+ io_mock = mock() |
|
30 |
+ mock(@checker).get_io(event) { StringIO.new("testdata") } |
|
31 |
+ |
|
32 |
+ upload_io = @checker.get_upload_io(event) |
|
33 |
+ expect(upload_io).to be_a(Faraday::UploadIO) |
|
34 |
+ expect(upload_io.content_type).to eq('text/plain') |
|
35 |
+ end |
|
36 |
+end |
@@ -1,40 +1,146 @@ |
||
1 |
-// |
|
2 |
-// Use internal $.serializeArray to get list of form elements which is |
|
3 |
-// consistent with $.serialize |
|
4 |
-// |
|
5 |
-// From version 2.0.0, $.serializeObject will stop converting [name] values |
|
6 |
-// to camelCase format. This is *consistent* with other serialize methods: |
|
7 |
-// |
|
8 |
-// - $.serialize |
|
9 |
-// - $.serializeArray |
|
10 |
-// |
|
11 |
-// If you require camel casing, you can either download version 1.0.4 or map |
|
12 |
-// them yourself. |
|
13 |
-// |
|
14 |
- |
|
15 |
-(function($){ |
|
16 |
- $.fn.serializeObject = function () { |
|
17 |
- "use strict"; |
|
18 |
- |
|
19 |
- var result = {}; |
|
20 |
- var extend = function (i, element) { |
|
21 |
- var node = result[element.name]; |
|
22 |
- |
|
23 |
- // If node with same name exists already, need to convert it to an array as it |
|
24 |
- // is a multi-value field (i.e., checkboxes) |
|
25 |
- |
|
26 |
- if ('undefined' !== typeof node && node !== null) { |
|
27 |
- if ($.isArray(node)) { |
|
28 |
- node.push(element.value); |
|
29 |
- } else { |
|
30 |
- result[element.name] = [node, element.value]; |
|
1 |
+/** |
|
2 |
+ * jQuery serializeObject |
|
3 |
+ * @copyright 2014, macek <paulmacek@gmail.com> |
|
4 |
+ * @link https://github.com/macek/jquery-serialize-object |
|
5 |
+ * @license BSD |
|
6 |
+ * @version 2.5.0 |
|
7 |
+ */ |
|
8 |
+(function(root, factory) { |
|
9 |
+ |
|
10 |
+ // AMD |
|
11 |
+ if (typeof define === "function" && define.amd) { |
|
12 |
+ define(["exports", "jquery"], function(exports, $) { |
|
13 |
+ return factory(exports, $); |
|
14 |
+ }); |
|
15 |
+ } |
|
16 |
+ |
|
17 |
+ // CommonJS |
|
18 |
+ else if (typeof exports !== "undefined") { |
|
19 |
+ var $ = require("jquery"); |
|
20 |
+ factory(exports, $); |
|
21 |
+ } |
|
22 |
+ |
|
23 |
+ // Browser |
|
24 |
+ else { |
|
25 |
+ factory(root, (root.jQuery || root.Zepto || root.ender || root.$)); |
|
26 |
+ } |
|
27 |
+ |
|
28 |
+}(this, function(exports, $) { |
|
29 |
+ |
|
30 |
+ var patterns = { |
|
31 |
+ validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i, |
|
32 |
+ key: /[a-z0-9_]+|(?=\[\])/gi, |
|
33 |
+ push: /^$/, |
|
34 |
+ fixed: /^\d+$/, |
|
35 |
+ named: /^[a-z0-9_]+$/i |
|
36 |
+ }; |
|
37 |
+ |
|
38 |
+ function FormSerializer(helper, $form) { |
|
39 |
+ |
|
40 |
+ // private variables |
|
41 |
+ var data = {}, |
|
42 |
+ pushes = {}; |
|
43 |
+ |
|
44 |
+ // private API |
|
45 |
+ function build(base, key, value) { |
|
46 |
+ base[key] = value; |
|
47 |
+ return base; |
|
48 |
+ } |
|
49 |
+ |
|
50 |
+ function makeObject(root, value) { |
|
51 |
+ |
|
52 |
+ var keys = root.match(patterns.key), k; |
|
53 |
+ |
|
54 |
+ // nest, nest, ..., nest |
|
55 |
+ while ((k = keys.pop()) !== undefined) { |
|
56 |
+ // foo[] |
|
57 |
+ if (patterns.push.test(k)) { |
|
58 |
+ var idx = incrementPush(root.replace(/\[\]$/, '')); |
|
59 |
+ value = build([], idx, value); |
|
60 |
+ } |
|
61 |
+ |
|
62 |
+ // foo[n] |
|
63 |
+ else if (patterns.fixed.test(k)) { |
|
64 |
+ value = build([], k, value); |
|
65 |
+ } |
|
66 |
+ |
|
67 |
+ // foo; foo[bar] |
|
68 |
+ else if (patterns.named.test(k)) { |
|
69 |
+ value = build({}, k, value); |
|
31 | 70 |
} |
32 |
- } else { |
|
33 |
- result[element.name] = element.value; |
|
34 | 71 |
} |
35 |
- }; |
|
36 | 72 |
|
37 |
- $.each(this.serializeArray(), extend); |
|
38 |
- return result; |
|
73 |
+ return value; |
|
74 |
+ } |
|
75 |
+ |
|
76 |
+ function incrementPush(key) { |
|
77 |
+ if (pushes[key] === undefined) { |
|
78 |
+ pushes[key] = 0; |
|
79 |
+ } |
|
80 |
+ return pushes[key]++; |
|
81 |
+ } |
|
82 |
+ |
|
83 |
+ function encode(pair) { |
|
84 |
+ switch ($('[name="' + pair.name + '"]', $form).attr("type")) { |
|
85 |
+ case "checkbox": |
|
86 |
+ return pair.value === "on" ? true : pair.value; |
|
87 |
+ default: |
|
88 |
+ return pair.value; |
|
89 |
+ } |
|
90 |
+ } |
|
91 |
+ |
|
92 |
+ function addPair(pair) { |
|
93 |
+ if (!patterns.validate.test(pair.name)) return this; |
|
94 |
+ var obj = makeObject(pair.name, encode(pair)); |
|
95 |
+ data = helper.extend(true, data, obj); |
|
96 |
+ return this; |
|
97 |
+ } |
|
98 |
+ |
|
99 |
+ function addPairs(pairs) { |
|
100 |
+ if (!helper.isArray(pairs)) { |
|
101 |
+ throw new Error("formSerializer.addPairs expects an Array"); |
|
102 |
+ } |
|
103 |
+ for (var i=0, len=pairs.length; i<len; i++) { |
|
104 |
+ this.addPair(pairs[i]); |
|
105 |
+ } |
|
106 |
+ return this; |
|
107 |
+ } |
|
108 |
+ |
|
109 |
+ function serialize() { |
|
110 |
+ return data; |
|
111 |
+ } |
|
112 |
+ |
|
113 |
+ function serializeJSON() { |
|
114 |
+ return JSON.stringify(serialize()); |
|
115 |
+ } |
|
116 |
+ |
|
117 |
+ // public API |
|
118 |
+ this.addPair = addPair; |
|
119 |
+ this.addPairs = addPairs; |
|
120 |
+ this.serialize = serialize; |
|
121 |
+ this.serializeJSON = serializeJSON; |
|
122 |
+ } |
|
123 |
+ |
|
124 |
+ FormSerializer.patterns = patterns; |
|
125 |
+ |
|
126 |
+ FormSerializer.serializeObject = function serializeObject() { |
|
127 |
+ return new FormSerializer($, this). |
|
128 |
+ addPairs(this.serializeArray()). |
|
129 |
+ serialize(); |
|
130 |
+ }; |
|
131 |
+ |
|
132 |
+ FormSerializer.serializeJSON = function serializeJSON() { |
|
133 |
+ return new FormSerializer($, this). |
|
134 |
+ addPairs(this.serializeArray()). |
|
135 |
+ serializeJSON(); |
|
39 | 136 |
}; |
40 |
-})(jQuery); |
|
137 |
+ |
|
138 |
+ if (typeof $.fn !== "undefined") { |
|
139 |
+ $.fn.serializeObject = FormSerializer.serializeObject; |
|
140 |
+ $.fn.serializeJSON = FormSerializer.serializeJSON; |
|
141 |
+ } |
|
142 |
+ |
|
143 |
+ exports.FormSerializer = FormSerializer; |
|
144 |
+ |
|
145 |
+ return FormSerializer; |
|
146 |
+})); |