agent_spec.rb 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. require 'spec_helper'
  2. require 'models/concerns/working_helpers'
  3. describe Agent do
  4. it_behaves_like WorkingHelpers
  5. describe ".run_schedule" do
  6. before do
  7. Agents::WeatherAgent.count.should > 0
  8. Agents::WebsiteAgent.count.should > 0
  9. end
  10. it "runs agents with the given schedule" do
  11. weather_agent_ids = [agents(:bob_weather_agent), agents(:jane_weather_agent)].map(&:id)
  12. stub(Agents::WeatherAgent).async_check(anything) {|agent_id| weather_agent_ids.delete(agent_id) }
  13. stub(Agents::WebsiteAgent).async_check(agents(:bob_website_agent).id)
  14. Agent.run_schedule("midnight")
  15. weather_agent_ids.should be_empty
  16. end
  17. it "groups agents by type" do
  18. mock(Agents::WeatherAgent).bulk_check("midnight").once
  19. mock(Agents::WebsiteAgent).bulk_check("midnight").once
  20. Agent.run_schedule("midnight")
  21. end
  22. it "only runs agents with the given schedule" do
  23. do_not_allow(Agents::WebsiteAgent).async_check
  24. Agent.run_schedule("blah")
  25. end
  26. it "will not run the 'never' schedule" do
  27. agents(:bob_weather_agent).update_attribute 'schedule', 'never'
  28. do_not_allow(Agents::WebsiteAgent).async_check
  29. Agent.run_schedule("never")
  30. end
  31. end
  32. describe "credential" do
  33. it "should return the value of the credential when credential is present" do
  34. agents(:bob_weather_agent).credential("aws_secret").should == user_credentials(:bob_aws_secret).credential_value
  35. end
  36. it "should return nil when credential is not present" do
  37. agents(:bob_weather_agent).credential("non_existing_credential").should == nil
  38. end
  39. it "should memoize the load" do
  40. mock.any_instance_of(UserCredential).credential_value.twice { "foo" }
  41. agents(:bob_weather_agent).credential("aws_secret").should == "foo"
  42. agents(:bob_weather_agent).credential("aws_secret").should == "foo"
  43. agents(:bob_weather_agent).reload
  44. agents(:bob_weather_agent).credential("aws_secret").should == "foo"
  45. agents(:bob_weather_agent).credential("aws_secret").should == "foo"
  46. end
  47. end
  48. describe "changes to type" do
  49. it "validates types" do
  50. source = Agent.new
  51. source.type = "Agents::WeatherAgent"
  52. source.should have(0).errors_on(:type)
  53. source.type = "Agents::WebsiteAgent"
  54. source.should have(0).errors_on(:type)
  55. source.type = "Agents::Fake"
  56. source.should have(1).error_on(:type)
  57. end
  58. it "disallows changes to type once a record has been saved" do
  59. source = agents(:bob_website_agent)
  60. source.type = "Agents::WeatherAgent"
  61. source.should have(1).error_on(:type)
  62. end
  63. it "should know about available types" do
  64. Agent.types.should include(Agents::WeatherAgent, Agents::WebsiteAgent)
  65. end
  66. end
  67. describe "with an example Agent" do
  68. class Agents::SomethingSource < Agent
  69. default_schedule "2pm"
  70. def check
  71. create_event :payload => {}
  72. end
  73. def validate_options
  74. errors.add(:base, "bad is bad") if options[:bad]
  75. end
  76. end
  77. class Agents::CannotBeScheduled < Agent
  78. cannot_be_scheduled!
  79. def receive(events)
  80. events.each do |event|
  81. create_event :payload => { :events_received => 1 }
  82. end
  83. end
  84. end
  85. before do
  86. stub(Agents::SomethingSource).valid_type?("Agents::SomethingSource") { true }
  87. stub(Agents::CannotBeScheduled).valid_type?("Agents::CannotBeScheduled") { true }
  88. end
  89. describe ".default_schedule" do
  90. it "stores the default on the class" do
  91. Agents::SomethingSource.default_schedule.should == "2pm"
  92. Agents::SomethingSource.new.default_schedule.should == "2pm"
  93. end
  94. it "sets the default on new instances, allows setting new schedules, and prevents invalid schedules" do
  95. @checker = Agents::SomethingSource.new(:name => "something")
  96. @checker.user = users(:bob)
  97. @checker.schedule.should == "2pm"
  98. @checker.save!
  99. @checker.reload.schedule.should == "2pm"
  100. @checker.update_attribute :schedule, "5pm"
  101. @checker.reload.schedule.should == "5pm"
  102. @checker.reload.schedule.should == "5pm"
  103. @checker.schedule = "this_is_not_real"
  104. @checker.should have(1).errors_on(:schedule)
  105. end
  106. it "should have an empty schedule if it cannot_be_scheduled" do
  107. @checker = Agents::CannotBeScheduled.new(:name => "something")
  108. @checker.user = users(:bob)
  109. @checker.schedule.should be_nil
  110. @checker.should be_valid
  111. @checker.schedule = "5pm"
  112. @checker.save!
  113. @checker.schedule.should be_nil
  114. @checker.schedule = "5pm"
  115. @checker.should have(0).errors_on(:schedule)
  116. @checker.schedule.should be_nil
  117. end
  118. end
  119. describe "#create_event" do
  120. before do
  121. @checker = Agents::SomethingSource.new(:name => "something")
  122. @checker.user = users(:bob)
  123. @checker.save!
  124. end
  125. it "should use the checker's user" do
  126. @checker.check
  127. Event.last.user.should == @checker.user
  128. end
  129. it "should log an error if the Agent has been marked with 'cannot_create_events!'" do
  130. mock(@checker).can_create_events? { false }
  131. lambda {
  132. @checker.check
  133. }.should_not change { Event.count }
  134. @checker.logs.first.message.should =~ /cannot create events/i
  135. end
  136. end
  137. describe ".async_check" do
  138. before do
  139. @checker = Agents::SomethingSource.new(:name => "something")
  140. @checker.user = users(:bob)
  141. @checker.save!
  142. end
  143. it "records last_check_at and calls check on the given Agent" do
  144. mock(@checker).check.once {
  145. @checker.options[:new] = true
  146. }
  147. mock(Agent).find(@checker.id) { @checker }
  148. @checker.last_check_at.should be_nil
  149. Agents::SomethingSource.async_check(@checker.id)
  150. @checker.reload.last_check_at.should be_within(2).of(Time.now)
  151. @checker.reload.options[:new].should be_true # Show that we save options
  152. end
  153. it "should log exceptions" do
  154. mock(@checker).check.once {
  155. raise "foo"
  156. }
  157. mock(Agent).find(@checker.id) { @checker }
  158. lambda {
  159. Agents::SomethingSource.async_check(@checker.id)
  160. }.should raise_error
  161. log = @checker.logs.first
  162. log.message.should =~ /Exception/
  163. log.level.should == 4
  164. end
  165. end
  166. describe ".receive! and .async_receive" do
  167. before do
  168. stub_request(:any, /wunderground/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/weather.json")), :status => 200)
  169. stub.any_instance_of(Agents::WeatherAgent).is_tomorrow?(anything) { true }
  170. end
  171. it "should use available events" do
  172. mock.any_instance_of(Agents::TriggerAgent).receive(anything).once
  173. Agent.async_check(agents(:bob_weather_agent).id)
  174. Agent.receive!
  175. end
  176. it "should log exceptions" do
  177. mock.any_instance_of(Agents::TriggerAgent).receive(anything).once {
  178. raise "foo"
  179. }
  180. Agent.async_check(agents(:bob_weather_agent).id)
  181. lambda {
  182. Agent.async_receive(agents(:bob_rain_notifier_agent).id, [agents(:bob_weather_agent).events.last.id])
  183. }.should raise_error
  184. log = agents(:bob_rain_notifier_agent).logs.first
  185. log.message.should =~ /Exception/
  186. log.level.should == 4
  187. end
  188. it "should track when events have been seen and not received them again" do
  189. mock.any_instance_of(Agents::TriggerAgent).receive(anything).once
  190. Agent.async_check(agents(:bob_weather_agent).id)
  191. lambda {
  192. Agent.receive!
  193. }.should change { agents(:bob_rain_notifier_agent).reload.last_checked_event_id }
  194. lambda {
  195. Agent.receive!
  196. }.should_not change { agents(:bob_rain_notifier_agent).reload.last_checked_event_id }
  197. end
  198. it "should not run consumers that have nothing to do" do
  199. do_not_allow.any_instance_of(Agents::TriggerAgent).receive(anything)
  200. Agent.receive!
  201. end
  202. it "should group events" do
  203. mock.any_instance_of(Agents::TriggerAgent).receive(anything).twice { |events|
  204. events.map(&:user).map(&:username).uniq.length.should == 1
  205. }
  206. Agent.async_check(agents(:bob_weather_agent).id)
  207. Agent.async_check(agents(:jane_weather_agent).id)
  208. Agent.receive!
  209. end
  210. it "should ignore events that were created before a particular Link" do
  211. agent2 = Agents::SomethingSource.new(:name => "something")
  212. agent2.user = users(:bob)
  213. agent2.save!
  214. agent2.check
  215. mock.any_instance_of(Agents::TriggerAgent).receive(anything).twice
  216. agents(:bob_weather_agent).check # bob_weather_agent makes an event
  217. lambda {
  218. Agent.receive! # event gets propagated
  219. }.should change { agents(:bob_rain_notifier_agent).reload.last_checked_event_id }
  220. # This agent creates a few events before we link to it, but after our last check.
  221. agent2.check
  222. agent2.check
  223. # Now we link to it.
  224. agents(:bob_rain_notifier_agent).sources << agent2
  225. agent2.links_as_source.first.event_id_at_creation.should == agent2.events.reorder("events.id desc").first.id
  226. lambda {
  227. Agent.receive! # but we don't receive those events because they're too old
  228. }.should_not change { agents(:bob_rain_notifier_agent).reload.last_checked_event_id }
  229. # Now a new event is created by agent2
  230. agent2.check
  231. lambda {
  232. Agent.receive! # and we receive it
  233. }.should change { agents(:bob_rain_notifier_agent).reload.last_checked_event_id }
  234. end
  235. end
  236. describe "creating a new agent and then calling .receive!" do
  237. it "should not backfill events for a newly created agent" do
  238. Event.delete_all
  239. sender = Agents::SomethingSource.new(:name => "Sending Agent")
  240. sender.user = users(:bob)
  241. sender.save!
  242. sender.create_event :payload => {}
  243. sender.create_event :payload => {}
  244. sender.events.count.should == 2
  245. receiver = Agents::CannotBeScheduled.new(:name => "Receiving Agent")
  246. receiver.user = users(:bob)
  247. receiver.sources << sender
  248. receiver.save!
  249. receiver.events.count.should == 0
  250. Agent.receive!
  251. receiver.events.count.should == 0
  252. sender.create_event :payload => {}
  253. Agent.receive!
  254. receiver.events.count.should == 1
  255. end
  256. end
  257. describe "creating agents with propagate_immediately = true" do
  258. it "should schedule subagent events immediately" do
  259. Event.delete_all
  260. sender = Agents::SomethingSource.new(:name => "Sending Agent")
  261. sender.user = users(:bob)
  262. sender.save!
  263. receiver = Agents::CannotBeScheduled.new(
  264. :name => "Receiving Agent",
  265. )
  266. receiver.propagate_immediately = true
  267. receiver.user = users(:bob)
  268. receiver.sources << sender
  269. receiver.save!
  270. sender.create_event :payload => {"message" => "new payload"}
  271. sender.events.count.should == 1
  272. receiver.events.count.should == 1
  273. #should be true without calling Agent.receive!
  274. end
  275. it "should only schedule receiving agents that are set to propagate_immediately" do
  276. Event.delete_all
  277. sender = Agents::SomethingSource.new(:name => "Sending Agent")
  278. sender.user = users(:bob)
  279. sender.save!
  280. im_receiver = Agents::CannotBeScheduled.new(
  281. :name => "Immediate Receiving Agent",
  282. )
  283. im_receiver.propagate_immediately = true
  284. im_receiver.user = users(:bob)
  285. im_receiver.sources << sender
  286. im_receiver.save!
  287. slow_receiver = Agents::CannotBeScheduled.new(
  288. :name => "Slow Receiving Agent",
  289. )
  290. slow_receiver.user = users(:bob)
  291. slow_receiver.sources << sender
  292. slow_receiver.save!
  293. sender.create_event :payload => {"message" => "new payload"}
  294. sender.events.count.should == 1
  295. im_receiver.events.count.should == 1
  296. #we should get the quick one
  297. #but not the slow one
  298. slow_receiver.events.count.should == 0
  299. Agent.receive!
  300. #now we should have one in both
  301. im_receiver.events.count.should == 1
  302. slow_receiver.events.count.should == 1
  303. end
  304. end
  305. describe "validations" do
  306. it "calls validate_options" do
  307. agent = Agents::SomethingSource.new(:name => "something")
  308. agent.user = users(:bob)
  309. agent.options[:bad] = true
  310. agent.should have(1).error_on(:base)
  311. agent.options[:bad] = false
  312. agent.should have(0).errors_on(:base)
  313. end
  314. it "makes options symbol-indifferent before validating" do
  315. agent = Agents::SomethingSource.new(:name => "something")
  316. agent.user = users(:bob)
  317. agent.options["bad"] = true
  318. agent.should have(1).error_on(:base)
  319. agent.options["bad"] = false
  320. agent.should have(0).errors_on(:base)
  321. end
  322. it "makes memory symbol-indifferent before validating" do
  323. agent = Agents::SomethingSource.new(:name => "something")
  324. agent.user = users(:bob)
  325. agent.memory["bad"] = 2
  326. agent.save
  327. agent.memory[:bad].should == 2
  328. end
  329. it "should work when assigned a hash or JSON string" do
  330. agent = Agents::SomethingSource.new(:name => "something")
  331. agent.memory = {}
  332. agent.memory.should == {}
  333. agent.memory["foo"].should be_nil
  334. agent.memory = ""
  335. agent.memory["foo"].should be_nil
  336. agent.memory.should == {}
  337. agent.memory = '{"hi": "there"}'
  338. agent.memory.should == { "hi" => "there" }
  339. agent.memory = '{invalid}'
  340. agent.memory.should == { "hi" => "there" }
  341. agent.should have(1).errors_on(:memory)
  342. agent.memory = "{}"
  343. agent.memory["foo"].should be_nil
  344. agent.memory.should == {}
  345. agent.should have(0).errors_on(:memory)
  346. agent.options = "{}"
  347. agent.options["foo"].should be_nil
  348. agent.options.should == {}
  349. agent.should have(0).errors_on(:options)
  350. agent.options = '{"hi": 2}'
  351. agent.options["hi"].should == 2
  352. agent.should have(0).errors_on(:options)
  353. agent.options = '{"hi": wut}'
  354. agent.options["hi"].should == 2
  355. agent.should have(1).errors_on(:options)
  356. agent.errors_on(:options).should include("was assigned invalid JSON")
  357. agent.options = 5
  358. agent.options["hi"].should == 2
  359. agent.should have(1).errors_on(:options)
  360. agent.errors_on(:options).should include("cannot be set to an instance of Fixnum")
  361. end
  362. it "should not allow agents owned by other people" do
  363. agent = Agents::SomethingSource.new(:name => "something")
  364. agent.user = users(:bob)
  365. agent.source_ids = [agents(:bob_weather_agent).id]
  366. agent.should have(0).errors_on(:sources)
  367. agent.source_ids = [agents(:jane_weather_agent).id]
  368. agent.should have(1).errors_on(:sources)
  369. agent.user = users(:jane)
  370. agent.should have(0).errors_on(:sources)
  371. end
  372. it "validates keep_events_for" do
  373. agent = Agents::SomethingSource.new(:name => "something")
  374. agent.user = users(:bob)
  375. agent.should be_valid
  376. agent.keep_events_for = nil
  377. agent.should have(1).errors_on(:keep_events_for)
  378. agent.keep_events_for = 1000
  379. agent.should have(1).errors_on(:keep_events_for)
  380. agent.keep_events_for = ""
  381. agent.should have(1).errors_on(:keep_events_for)
  382. agent.keep_events_for = 5
  383. agent.should be_valid
  384. agent.keep_events_for = 0
  385. agent.should be_valid
  386. agent.keep_events_for = 365
  387. agent.should be_valid
  388. # Rails seems to call to_i on the input. This guards against future changes to that behavior.
  389. agent.keep_events_for = "drop table;"
  390. agent.keep_events_for.should == 0
  391. end
  392. end
  393. describe "cleaning up now-expired events" do
  394. before do
  395. @agent = Agents::SomethingSource.new(:name => "something")
  396. @agent.keep_events_for = 5
  397. @agent.user = users(:bob)
  398. @agent.save!
  399. @event = @agent.create_event :payload => { "hello" => "world" }
  400. @event.expires_at.to_i.should be_within(2).of(5.days.from_now.to_i)
  401. end
  402. describe "when keep_events_for has not changed" do
  403. it "does nothing" do
  404. mock(@agent).update_event_expirations!.times(0)
  405. @agent.options[:foo] = "bar1"
  406. @agent.save!
  407. @agent.options[:foo] = "bar1"
  408. @agent.keep_events_for = 5
  409. @agent.save!
  410. end
  411. end
  412. describe "when keep_events_for is changed" do
  413. it "updates events' expires_at" do
  414. lambda {
  415. @agent.options[:foo] = "bar1"
  416. @agent.keep_events_for = 3
  417. @agent.save!
  418. }.should change { @event.reload.expires_at }
  419. @event.expires_at.to_i.should be_within(2).of(3.days.from_now.to_i)
  420. end
  421. it "updates events relative to their created_at" do
  422. @event.update_attribute :created_at, 2.days.ago
  423. @event.reload.created_at.to_i.should be_within(2).of(2.days.ago.to_i)
  424. lambda {
  425. @agent.options[:foo] = "bar2"
  426. @agent.keep_events_for = 3
  427. @agent.save!
  428. }.should change { @event.reload.expires_at }
  429. @event.expires_at.to_i.should be_within(60 * 61).of(1.days.from_now.to_i) # The larger time is to deal with daylight savings
  430. end
  431. it "nulls out expires_at when keep_events_for is set to 0" do
  432. lambda {
  433. @agent.options[:foo] = "bar"
  434. @agent.keep_events_for = 0
  435. @agent.save!
  436. }.should change { @event.reload.expires_at }.to(nil)
  437. end
  438. end
  439. end
  440. describe "Agent.build_clone" do
  441. before do
  442. Event.delete_all
  443. @sender = Agents::SomethingSource.new(
  444. name: 'Agent (2)',
  445. options: { foo: 'bar2' },
  446. schedule: '5pm')
  447. @sender.user = users(:bob)
  448. @sender.save!
  449. @sender.create_event :payload => {}
  450. @sender.create_event :payload => {}
  451. @sender.events.count.should == 2
  452. @receiver = Agents::CannotBeScheduled.new(
  453. name: 'Agent',
  454. options: { foo: 'bar3' },
  455. keep_events_for: 3,
  456. propagate_immediately: true)
  457. @receiver.user = users(:bob)
  458. @receiver.sources << @sender
  459. @receiver.memory[:test] = 1
  460. @receiver.save!
  461. end
  462. it "should create a clone of a given agent for editing" do
  463. sender_clone = users(:bob).agents.build_clone(@sender)
  464. sender_clone.attributes.should == Agent.new.attributes.
  465. update(@sender.slice(:user_id, :type,
  466. :options, :schedule, :keep_events_for, :propagate_immediately)).
  467. update('name' => 'Agent (2) (2)', 'options' => { 'foo' => 'bar2' })
  468. sender_clone.source_ids.should == []
  469. receiver_clone = users(:bob).agents.build_clone(@receiver)
  470. receiver_clone.attributes.should == Agent.new.attributes.
  471. update(@receiver.slice(:user_id, :type,
  472. :options, :schedule, :keep_events_for, :propagate_immediately)).
  473. update('name' => 'Agent (3)', 'options' => { 'foo' => 'bar3' })
  474. receiver_clone.source_ids.should == [@sender.id]
  475. end
  476. end
  477. end
  478. describe ".trigger_web_request" do
  479. class Agents::WebRequestReceiver < Agent
  480. cannot_be_scheduled!
  481. end
  482. before do
  483. stub(Agents::WebRequestReceiver).valid_type?("Agents::WebRequestReceiver") { true }
  484. end
  485. context "when .receive_web_request is defined" do
  486. before do
  487. @agent = Agents::WebRequestReceiver.new(:name => "something")
  488. @agent.user = users(:bob)
  489. @agent.save!
  490. def @agent.receive_web_request(params, method, format)
  491. memory['last_request'] = [params, method, format]
  492. ['Ok!', 200]
  493. end
  494. end
  495. it "calls the .receive_web_request hook, updates last_web_request_at, and saves" do
  496. @agent.trigger_web_request({ :some_param => "some_value" }, "post", "text/html")
  497. @agent.reload.memory['last_request'].should == [ { "some_param" => "some_value" }, "post", "text/html" ]
  498. @agent.last_web_request_at.to_i.should be_within(1).of(Time.now.to_i)
  499. end
  500. end
  501. context "when .receive_webhook is defined" do
  502. before do
  503. @agent = Agents::WebRequestReceiver.new(:name => "something")
  504. @agent.user = users(:bob)
  505. @agent.save!
  506. def @agent.receive_webhook(params)
  507. memory['last_webhook_request'] = params
  508. ['Ok!', 200]
  509. end
  510. end
  511. it "outputs a deprecation warning and calls .receive_webhook with the params" do
  512. mock(Rails.logger).warn("DEPRECATED: The .receive_webhook method is deprecated, please switch your Agent to use .receive_web_request.")
  513. @agent.trigger_web_request({ :some_param => "some_value" }, "post", "text/html")
  514. @agent.reload.memory['last_webhook_request'].should == { "some_param" => "some_value" }
  515. @agent.last_web_request_at.to_i.should be_within(1).of(Time.now.to_i)
  516. end
  517. end
  518. end
  519. describe "scopes" do
  520. describe "of_type" do
  521. it "should accept classes" do
  522. agents = Agent.of_type(Agents::WebsiteAgent)
  523. agents.should include(agents(:bob_website_agent))
  524. agents.should include(agents(:jane_website_agent))
  525. agents.should_not include(agents(:bob_weather_agent))
  526. end
  527. it "should accept strings" do
  528. agents = Agent.of_type("Agents::WebsiteAgent")
  529. agents.should include(agents(:bob_website_agent))
  530. agents.should include(agents(:jane_website_agent))
  531. agents.should_not include(agents(:bob_weather_agent))
  532. end
  533. it "should accept instances of an Agent" do
  534. agents = Agent.of_type(agents(:bob_website_agent))
  535. agents.should include(agents(:bob_website_agent))
  536. agents.should include(agents(:jane_website_agent))
  537. agents.should_not include(agents(:bob_weather_agent))
  538. end
  539. end
  540. end
  541. describe "#create_event" do
  542. describe "when the agent has keep_events_for set" do
  543. before do
  544. agents(:jane_weather_agent).keep_events_for.should > 0
  545. end
  546. it "sets expires_at on created events" do
  547. event = agents(:jane_weather_agent).create_event :payload => { 'hi' => 'there' }
  548. event.expires_at.to_i.should be_within(5).of(agents(:jane_weather_agent).keep_events_for.days.from_now.to_i)
  549. end
  550. end
  551. describe "when the agent does not have keep_events_for set" do
  552. before do
  553. agents(:jane_website_agent).keep_events_for.should == 0
  554. end
  555. it "does not set expires_at on created events" do
  556. event = agents(:jane_website_agent).create_event :payload => { 'hi' => 'there' }
  557. event.expires_at.should be_nil
  558. end
  559. end
  560. end
  561. end