agents_controller_spec.rb 15 KB

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