agents_controller_spec.rb 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. require 'rails_helper'
  2. describe AgentsController do
  3. def valid_attributes(options = {})
  4. {
  5. :type => "Agents::WebsiteAgent",
  6. :name => "Something",
  7. :options => agents(:bob_website_agent).options,
  8. :source_ids => [agents(:bob_weather_agent).id, ""]
  9. }.merge(options)
  10. end
  11. describe "GET index" do
  12. it "only returns Agents for the current user" do
  13. sign_in users(:bob)
  14. get :index
  15. expect(assigns(:agents).all? {|i| expect(i.user).to eq(users(:bob)) }).to be_truthy
  16. end
  17. it "should not show disabled agents if the cookie is set" do
  18. @request.cookies["huginn_view_only_enabled_agents"] = "true"
  19. sign_in users(:bob)
  20. get :index
  21. expect(assigns(:agents).map(&:disabled).uniq).to eq([false])
  22. end
  23. end
  24. describe "POST handle_details_post" do
  25. it "passes control to handle_details_post on the agent" do
  26. sign_in users(:bob)
  27. post :handle_details_post, params: {:id => agents(:bob_manual_event_agent).to_param, :payload => { :foo => "bar" }.to_json}
  28. expect(JSON.parse(response.body)).to eq({ "success" => true })
  29. expect(agents(:bob_manual_event_agent).events.last.payload).to eq({ 'foo' => "bar" })
  30. end
  31. it "can only be accessed by the Agent's owner" do
  32. sign_in users(:jane)
  33. expect {
  34. post :handle_details_post, params: {:id => agents(:bob_manual_event_agent).to_param, :payload => { :foo => :bar }.to_json}
  35. }.to raise_error(ActiveRecord::RecordNotFound)
  36. end
  37. end
  38. describe "POST run" do
  39. it "triggers Agent.async_check with the Agent's ID" do
  40. sign_in users(:bob)
  41. mock(Agent).async_check(agents(:bob_manual_event_agent).id)
  42. post :run, params: {:id => agents(:bob_manual_event_agent).to_param}
  43. end
  44. it "can only be accessed by the Agent's owner" do
  45. sign_in users(:jane)
  46. expect {
  47. post :run, params: {:id => agents(:bob_manual_event_agent).to_param}
  48. }.to raise_error(ActiveRecord::RecordNotFound)
  49. end
  50. end
  51. describe "POST remove_events" do
  52. it "deletes all events created by the given Agent" do
  53. sign_in users(:bob)
  54. agent_event = events(:bob_website_agent_event).id
  55. other_event = events(:jane_website_agent_event).id
  56. post :remove_events, params: {:id => agents(:bob_website_agent).to_param}
  57. expect(Event.where(:id => agent_event).count).to eq(0)
  58. expect(Event.where(:id => other_event).count).to eq(1)
  59. end
  60. it "can only be accessed by the Agent's owner" do
  61. sign_in users(:jane)
  62. expect {
  63. post :remove_events, params: {:id => agents(:bob_website_agent).to_param}
  64. }.to raise_error(ActiveRecord::RecordNotFound)
  65. end
  66. end
  67. describe "PUT toggle_visibility" do
  68. it "should set the cookie" do
  69. sign_in users(:jane)
  70. put :toggle_visibility
  71. expect(response.cookies["huginn_view_only_enabled_agents"]).to eq("true")
  72. end
  73. it "should delete the cookie" do
  74. @request.cookies["huginn_view_only_enabled_agents"] = "true"
  75. sign_in users(:jane)
  76. put :toggle_visibility
  77. expect(response.cookies["huginn_view_only_enabled_agents"]).to be_nil
  78. end
  79. end
  80. describe "POST propagate" do
  81. before(:each) do
  82. sign_in users(:bob)
  83. end
  84. it "runs event propagation for all Agents" do
  85. mock.proxy(Agent).receive!
  86. post :propagate
  87. end
  88. it "does not run the propagation when a job is already enqueued" do
  89. mock(AgentPropagateJob).can_enqueue? { false }
  90. post :propagate
  91. expect(flash[:notice]).to eq('Event propagation is already scheduled to run.')
  92. end
  93. end
  94. describe "GET show" do
  95. it "only shows Agents for the current user" do
  96. sign_in users(:bob)
  97. get :show, params: {:id => agents(:bob_website_agent).to_param}
  98. expect(assigns(:agent)).to eq(agents(:bob_website_agent))
  99. expect {
  100. get :show, params: {:id => agents(:jane_website_agent).to_param}
  101. }.to raise_error(ActiveRecord::RecordNotFound)
  102. end
  103. end
  104. describe "GET new" do
  105. describe "with :id" do
  106. it "opens a clone of a given Agent" do
  107. sign_in users(:bob)
  108. get :new, params: {:id => agents(:bob_website_agent).to_param}
  109. expect(assigns(:agent).attributes).to eq(users(:bob).agents.build_clone(agents(:bob_website_agent)).attributes)
  110. end
  111. it "only allows the current user to clone his own Agent" do
  112. sign_in users(:bob)
  113. expect {
  114. get :new, params: {:id => agents(:jane_website_agent).to_param}
  115. }.to raise_error(ActiveRecord::RecordNotFound)
  116. end
  117. end
  118. describe "with a scenario_id" do
  119. it 'populates the assigned agent with the scenario' do
  120. sign_in users(:bob)
  121. get :new, params: {:scenario_id => scenarios(:bob_weather).id}
  122. expect(assigns(:agent).scenario_ids).to eq([scenarios(:bob_weather).id])
  123. end
  124. it "does not see other user's scenarios" do
  125. sign_in users(:bob)
  126. get :new, params: {:scenario_id => scenarios(:jane_weather).id}
  127. expect(assigns(:agent).scenario_ids).to eq([])
  128. end
  129. end
  130. end
  131. describe "GET edit" do
  132. it "only shows Agents for the current user" do
  133. sign_in users(:bob)
  134. get :edit, params: {:id => agents(:bob_website_agent).to_param}
  135. expect(assigns(:agent)).to eq(agents(:bob_website_agent))
  136. expect {
  137. get :edit, params: {:id => agents(:jane_website_agent).to_param}
  138. }.to raise_error(ActiveRecord::RecordNotFound)
  139. end
  140. end
  141. describe "POST create" do
  142. it "errors on bad types" do
  143. sign_in users(:bob)
  144. expect {
  145. post :create, params: {:agent => valid_attributes(:type => "Agents::ThisIsFake")}
  146. }.not_to change { users(:bob).agents.count }
  147. expect(assigns(:agent)).to be_a(Agent)
  148. expect(assigns(:agent)).to have(1).error_on(:type)
  149. sign_in users(:bob)
  150. expect {
  151. post :create, params: {:agent => valid_attributes(:type => "Object")}
  152. }.not_to change { users(:bob).agents.count }
  153. expect(assigns(:agent)).to be_a(Agent)
  154. expect(assigns(:agent)).to have(1).error_on(:type)
  155. sign_in users(:bob)
  156. expect {
  157. post :create, params: {:agent => valid_attributes(:type => "Agent")}
  158. }.not_to change { users(:bob).agents.count }
  159. expect(assigns(:agent)).to be_a(Agent)
  160. expect(assigns(:agent)).to have(1).error_on(:type)
  161. expect {
  162. post :create, params: {:agent => valid_attributes(:type => "User")}
  163. }.not_to change { users(:bob).agents.count }
  164. expect(assigns(:agent)).to be_a(Agent)
  165. expect(assigns(:agent)).to have(1).error_on(:type)
  166. end
  167. it "creates Agents for the current user" do
  168. sign_in users(:bob)
  169. expect {
  170. expect {
  171. post :create, params: {:agent => valid_attributes}
  172. }.to change { users(:bob).agents.count }.by(1)
  173. }.to change { Link.count }.by(1)
  174. expect(assigns(:agent)).to be_a(Agents::WebsiteAgent)
  175. end
  176. it "creates Agents and accepts specifing a target agent" do
  177. sign_in users(:bob)
  178. attributes = valid_attributes(service_id: 1)
  179. attributes[:receiver_ids] = attributes[:source_ids]
  180. expect {
  181. expect {
  182. post :create, params: {:agent => attributes}
  183. }.to change { users(:bob).agents.count }.by(1)
  184. }.to change { Link.count }.by(2)
  185. expect(assigns(:agent)).to be_a(Agents::WebsiteAgent)
  186. end
  187. it "shows errors" do
  188. sign_in users(:bob)
  189. expect {
  190. post :create, params: {:agent => valid_attributes(:name => "")}
  191. }.not_to change { users(:bob).agents.count }
  192. expect(assigns(:agent)).to have(1).errors_on(:name)
  193. expect(response).to render_template("new")
  194. end
  195. it "will not accept Agent sources owned by other users" do
  196. sign_in users(:bob)
  197. expect {
  198. expect {
  199. post :create, params: {:agent => valid_attributes(:source_ids => [agents(:jane_weather_agent).id])}
  200. }.not_to change { users(:bob).agents.count }
  201. }.not_to change { Link.count }
  202. end
  203. end
  204. describe "PUT update" do
  205. it "does not allow changing types" do
  206. sign_in users(:bob)
  207. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:type => "Agents::WeatherAgent")}
  208. expect(assigns(:agent)).to have(1).errors_on(:type)
  209. expect(response).to render_template("edit")
  210. end
  211. it "updates attributes on Agents for the current user" do
  212. sign_in users(:bob)
  213. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name")}
  214. expect(response).to redirect_to(agents_path)
  215. expect(agents(:bob_website_agent).reload.name).to eq("New name")
  216. expect {
  217. post :update, params: {:id => agents(:jane_website_agent).to_param, :agent => valid_attributes(:name => "New name")}
  218. }.to raise_error(ActiveRecord::RecordNotFound)
  219. end
  220. it "accepts JSON requests" do
  221. sign_in users(:bob)
  222. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name")}, :format => :json
  223. expect(agents(:bob_website_agent).reload.name).to eq("New name")
  224. expect(JSON.parse(response.body)['name']).to eq("New name")
  225. expect(response).to be_successful
  226. end
  227. it "will not accept Agent sources owned by other users" do
  228. sign_in users(:bob)
  229. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:source_ids => [agents(:jane_weather_agent).id])}
  230. expect(assigns(:agent)).to have(1).errors_on(:sources)
  231. end
  232. it "will not accept Scenarios owned by other users" do
  233. sign_in users(:bob)
  234. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:scenario_ids => [scenarios(:jane_weather).id])}
  235. expect(assigns(:agent)).to have(1).errors_on(:scenarios)
  236. end
  237. it "shows errors" do
  238. sign_in users(:bob)
  239. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "")}
  240. expect(assigns(:agent)).to have(1).errors_on(:name)
  241. expect(response).to render_template("edit")
  242. end
  243. it 'does not allow to modify the agents user_id' do
  244. sign_in users(:bob)
  245. expect {
  246. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:user_id => users(:jane).id)}
  247. }.to raise_error(ActionController::UnpermittedParameters)
  248. end
  249. describe "redirecting back" do
  250. before do
  251. sign_in users(:bob)
  252. end
  253. it "can redirect back to the show path" do
  254. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name"), :return => "show"}
  255. expect(response).to redirect_to(agent_path(agents(:bob_website_agent)))
  256. end
  257. it "redirect back to the index path by default" do
  258. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name")}
  259. expect(response).to redirect_to(agents_path)
  260. end
  261. it "accepts return paths to scenarios" do
  262. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name"), :return => "/scenarios/2"}
  263. expect(response).to redirect_to("/scenarios/2")
  264. end
  265. it "sanitizes return paths" do
  266. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name"), :return => "/scenar"}
  267. expect(response).to redirect_to(agents_path)
  268. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name"), :return => "http://google.com"}
  269. expect(response).to redirect_to(agents_path)
  270. post :update, params: {:id => agents(:bob_website_agent).to_param, :agent => valid_attributes(:name => "New name"), :return => "javascript:alert(1)"}
  271. expect(response).to redirect_to(agents_path)
  272. end
  273. end
  274. it "updates last_checked_event_id when drop_pending_events is given" do
  275. sign_in users(:bob)
  276. agent = agents(:bob_website_agent)
  277. agent.disabled = true
  278. agent.last_checked_event_id = nil
  279. agent.save!
  280. post :update, params: {id: agents(:bob_website_agent).to_param, agent: { disabled: 'false', drop_pending_events: 'true' }}
  281. agent.reload
  282. expect(agent.disabled).to eq(false)
  283. expect(agent.last_checked_event_id).to eq(Event.maximum(:id))
  284. end
  285. end
  286. describe "PUT leave_scenario" do
  287. it "removes an Agent from the given Scenario for the current user" do
  288. sign_in users(:bob)
  289. expect(agents(:bob_weather_agent).scenarios).to include(scenarios(:bob_weather))
  290. put :leave_scenario, params: {:id => agents(:bob_weather_agent).to_param, :scenario_id => scenarios(:bob_weather).to_param}
  291. expect(agents(:bob_weather_agent).scenarios).not_to include(scenarios(:bob_weather))
  292. expect(Scenario.where(:id => scenarios(:bob_weather).id)).to exist
  293. expect {
  294. put :leave_scenario, params: {:id => agents(:jane_weather_agent).to_param, :scenario_id => scenarios(:jane_weather).to_param}
  295. }.to raise_error(ActiveRecord::RecordNotFound)
  296. end
  297. end
  298. describe "DELETE destroy" do
  299. it "destroys only Agents owned by the current user" do
  300. sign_in users(:bob)
  301. expect {
  302. delete :destroy, params: {:id => agents(:bob_website_agent).to_param}
  303. }.to change(Agent, :count).by(-1)
  304. expect {
  305. delete :destroy, params: {:id => agents(:jane_website_agent).to_param}
  306. }.to raise_error(ActiveRecord::RecordNotFound)
  307. end
  308. it "redirects correctly when the Agent is deleted from the Agent itself" do
  309. sign_in users(:bob)
  310. delete :destroy, params: {:id => agents(:bob_website_agent).to_param}
  311. expect(response).to redirect_to agents_path
  312. end
  313. it "redirects correctly when the Agent is deleted from a Scenario" do
  314. sign_in users(:bob)
  315. delete :destroy, params: {:id => agents(:bob_weather_agent).to_param, :return => scenario_path(scenarios(:bob_weather)).to_param}
  316. expect(response).to redirect_to scenario_path(scenarios(:bob_weather))
  317. end
  318. end
  319. describe "#form_configurable actions" do
  320. before(:each) do
  321. @params = {attribute: 'auth_token', agent: valid_attributes(:type => "Agents::HipchatAgent", options: {auth_token: '12345'})}
  322. sign_in users(:bob)
  323. end
  324. describe "POST validate" do
  325. it "returns with status 200 when called with a valid option" do
  326. any_instance_of(Agents::HipchatAgent) do |klass|
  327. stub(klass).validate_option { true }
  328. end
  329. post :validate, params: @params
  330. expect(response.status).to eq 200
  331. end
  332. it "returns with status 403 when called with an invalid option" do
  333. any_instance_of(Agents::HipchatAgent) do |klass|
  334. stub(klass).validate_option { false }
  335. end
  336. post :validate, params: @params
  337. expect(response.status).to eq 403
  338. end
  339. end
  340. describe "POST complete" do
  341. it "callsAgent#complete_option and renders json" do
  342. any_instance_of(Agents::HipchatAgent) do |klass|
  343. stub(klass).complete_option { [{name: 'test', value: 1}] }
  344. end
  345. post :complete, params: @params
  346. expect(response.status).to eq 200
  347. expect(response.header['Content-Type']).to include('application/json')
  348. end
  349. end
  350. end
  351. describe "DELETE memory" do
  352. it "clears memory of the agent" do
  353. agent = agents(:bob_website_agent)
  354. agent.update!(memory: { "test" => 42 })
  355. sign_in users(:bob)
  356. delete :destroy_memory, params: {id: agent.to_param}
  357. expect(agent.reload.memory).to eq({})
  358. end
  359. it "does not clear memory of an agent not owned by the current user" do
  360. agent = agents(:jane_website_agent)
  361. agent.update!(memory: { "test" => 42 })
  362. sign_in users(:bob)
  363. expect {
  364. delete :destroy_memory, params: {id: agent.to_param}
  365. }.to raise_error(ActiveRecord::RecordNotFound)
  366. expect(agent.reload.memory).to eq({ "test" => 42})
  367. end
  368. end
  369. describe 'DELETE undefined' do
  370. it 'removes an undefined agent from the database' do
  371. sign_in users(:bob)
  372. agent = agents(:bob_website_agent)
  373. agent.update_attribute(:type, 'Agents::UndefinedAgent')
  374. agent2 = agents(:jane_website_agent)
  375. agent2.update_attribute(:type, 'Agents::UndefinedAgent')
  376. expect {
  377. delete :destroy_undefined
  378. }.to change { Agent.count }.by(-1)
  379. end
  380. end
  381. end