website_agent_spec.rb 7.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. require 'spec_helper'
  2. describe Agents::WebsiteAgent do
  3. describe "checking without basic auth" do
  4. before do
  5. stub_request(:any, /xkcd/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/xkcd.html")), :status => 200)
  6. @site = {
  7. 'name' => "XKCD",
  8. 'expected_update_period_in_days' => 2,
  9. 'type' => "html",
  10. 'url' => "http://xkcd.com",
  11. 'mode' => 'on_change',
  12. 'extract' => {
  13. 'url' => {'css' => "#comic img", 'attr' => "src"},
  14. 'title' => {'css' => "#comic img", 'attr' => "title"}
  15. }
  16. }
  17. @checker = Agents::WebsiteAgent.new(:name => "xkcd", :options => @site)
  18. @checker.user = users(:bob)
  19. @checker.save!
  20. end
  21. describe "#check" do
  22. it "should check for changes" do
  23. lambda { @checker.check }.should change { Event.count }.by(1)
  24. lambda { @checker.check }.should_not change { Event.count }
  25. end
  26. it "should always save events when in :all mode" do
  27. lambda {
  28. @site['mode'] = 'all'
  29. @checker.options = @site
  30. @checker.check
  31. @checker.check
  32. }.should change { Event.count }.by(2)
  33. end
  34. it "should log an error if the number of results for a set of extraction patterns differs" do
  35. @site['extract']['url']['css'] = "div"
  36. @checker.options = @site
  37. @checker.check
  38. @checker.logs.first.message.should =~ /Got an uneven number of matches/
  39. end
  40. end
  41. describe '#working?' do
  42. it 'checks if events have been received within the expected receive period' do
  43. stubbed_time = Time.now
  44. stub(Time).now { stubbed_time }
  45. @checker.should_not be_working # No events created
  46. @checker.check
  47. @checker.reload.should be_working # Just created events
  48. @checker.error "oh no!"
  49. @checker.reload.should_not be_working # There is a recent error
  50. stubbed_time = 20.minutes.from_now
  51. @checker.events.delete_all
  52. @checker.check
  53. @checker.reload.should be_working # There is a newer event now
  54. stubbed_time = 2.days.from_now
  55. @checker.reload.should_not be_working # Two days have passed without a new event having been created
  56. end
  57. end
  58. describe "parsing" do
  59. it "parses CSS" do
  60. @checker.check
  61. event = Event.last
  62. event.payload['url'].should == "http://imgs.xkcd.com/comics/evolving.png"
  63. event.payload['title'].should =~ /^Biologists play reverse/
  64. end
  65. it "should turn relative urls to absolute" do
  66. rel_site = {
  67. 'name' => "XKCD",
  68. 'expected_update_period_in_days' => 2,
  69. 'type' => "html",
  70. 'url' => "http://xkcd.com",
  71. 'mode' => :on_change,
  72. 'extract' => {
  73. 'url' => {'css' => "#topLeft a", 'attr' => "href"},
  74. 'title' => {'css' => "#topLeft a", 'text' => "true"}
  75. }
  76. }
  77. rel = Agents::WebsiteAgent.new(:name => "xkcd", :options => rel_site)
  78. rel.user = users(:bob)
  79. rel.save!
  80. rel.check
  81. event = Event.last
  82. event.payload['url'].should == "http://xkcd.com/about"
  83. end
  84. describe "JSON" do
  85. it "works with paths" do
  86. json = {
  87. 'response' => {
  88. 'version' => 2,
  89. 'title' => "hello!"
  90. }
  91. }
  92. stub_request(:any, /json-site/).to_return(:body => json.to_json, :status => 200)
  93. site = {
  94. 'name' => "Some JSON Response",
  95. 'expected_update_period_in_days' => 2,
  96. 'type' => "json",
  97. 'url' => "http://json-site.com",
  98. 'mode' => 'on_change',
  99. 'extract' => {
  100. 'version' => {'path' => "response.version"},
  101. 'title' => {'path' => "response.title"}
  102. }
  103. }
  104. checker = Agents::WebsiteAgent.new(:name => "Weather Site", :options => site)
  105. checker.user = users(:bob)
  106. checker.save!
  107. checker.check
  108. event = Event.last
  109. event.payload['version'].should == 2
  110. event.payload['title'].should == "hello!"
  111. end
  112. it "can handle arrays" do
  113. json = {
  114. 'response' => {
  115. 'data' => [
  116. {'title' => "first", 'version' => 2},
  117. {'title' => "second", 'version' => 2.5}
  118. ]
  119. }
  120. }
  121. stub_request(:any, /json-site/).to_return(:body => json.to_json, :status => 200)
  122. site = {
  123. 'name' => "Some JSON Response",
  124. 'expected_update_period_in_days' => 2,
  125. 'type' => "json",
  126. 'url' => "http://json-site.com",
  127. 'mode' => 'on_change',
  128. 'extract' => {
  129. :title => {'path' => "response.data[*].title"},
  130. :version => {'path' => "response.data[*].version"}
  131. }
  132. }
  133. checker = Agents::WebsiteAgent.new(:name => "Weather Site", :options => site)
  134. checker.user = users(:bob)
  135. checker.save!
  136. lambda {
  137. checker.check
  138. }.should change { Event.count }.by(2)
  139. event = Event.all[-1]
  140. event.payload['version'].should == 2.5
  141. event.payload['title'].should == "second"
  142. event = Event.all[-2]
  143. event.payload['version'].should == 2
  144. event.payload['title'].should == "first"
  145. end
  146. it "stores the whole object if :extract is not specified" do
  147. json = {
  148. 'response' => {
  149. 'version' => 2,
  150. 'title' => "hello!"
  151. }
  152. }
  153. stub_request(:any, /json-site/).to_return(:body => json.to_json, :status => 200)
  154. site = {
  155. 'name' => "Some JSON Response",
  156. 'expected_update_period_in_days' => 2,
  157. 'type' => "json",
  158. 'url' => "http://json-site.com",
  159. 'mode' => 'on_change'
  160. }
  161. checker = Agents::WebsiteAgent.new(:name => "Weather Site", :options => site)
  162. checker.user = users(:bob)
  163. checker.save!
  164. checker.check
  165. event = Event.last
  166. event.payload['response']['version'].should == 2
  167. event.payload['response']['title'].should == "hello!"
  168. end
  169. end
  170. end
  171. end
  172. describe "checking with http basic auth" do
  173. before do
  174. stub_request(:any, /user:pass/).to_return(:body => File.read(Rails.root.join("spec/data_fixtures/xkcd.html")), :status => 200)
  175. @site = {
  176. 'name' => "XKCD",
  177. 'expected_update_period_in_days' => 2,
  178. 'type' => "html",
  179. 'url' => "http://www.example.com",
  180. 'mode' => 'on_change',
  181. 'extract' => {
  182. 'url' => {'css' => "#comic img", 'attr' => "src"},
  183. 'title' => {'css' => "#comic img", 'attr' => "title"}
  184. },
  185. 'basic_auth' => "user:pass"
  186. }
  187. @checker = Agents::WebsiteAgent.new(:name => "auth", :options => @site)
  188. @checker.user = users(:bob)
  189. @checker.save!
  190. end
  191. describe "#check" do
  192. it "should check for changes" do
  193. lambda { @checker.check }.should change { Event.count }.by(1)
  194. lambda { @checker.check }.should_not change { Event.count }
  195. end
  196. end
  197. end
  198. end