123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399 |
- require 'spec_helper'
- describe Agents::DataOutputAgent do
- let(:agent) do
- _agent = Agents::DataOutputAgent.new(:name => 'My Data Output Agent')
- _agent.options = _agent.default_options.merge('secrets' => ['secret1', 'secret2'], 'events_to_show' => 3)
- _agent.options['template']['item']['pubDate'] = "{{date}}"
- _agent.user = users(:bob)
- _agent.sources << agents(:bob_website_agent)
- _agent.save!
- _agent
- end
- describe "#working?" do
- it "checks if events have been received within expected receive period" do
- expect(agent).not_to be_working
- Agents::DataOutputAgent.async_receive agent.id, [events(:bob_website_agent_event).id]
- expect(agent.reload).to be_working
- two_days_from_now = 2.days.from_now
- stub(Time).now { two_days_from_now }
- expect(agent.reload).not_to be_working
- end
- end
- describe "validation" do
- before do
- expect(agent).to be_valid
- end
- it "should validate presence and length of secrets" do
- agent.options[:secrets] = ""
- expect(agent).not_to be_valid
- agent.options[:secrets] = "foo"
- expect(agent).not_to be_valid
- agent.options[:secrets] = "foo/bar"
- expect(agent).not_to be_valid
- agent.options[:secrets] = "foo.xml"
- expect(agent).not_to be_valid
- agent.options[:secrets] = false
- expect(agent).not_to be_valid
- agent.options[:secrets] = []
- expect(agent).not_to be_valid
- agent.options[:secrets] = ["foo.xml"]
- expect(agent).not_to be_valid
- agent.options[:secrets] = ["hello", true]
- expect(agent).not_to be_valid
- agent.options[:secrets] = ["hello"]
- expect(agent).to be_valid
- agent.options[:secrets] = ["hello", "world"]
- expect(agent).to be_valid
- end
- it "should validate presence of expected_receive_period_in_days" do
- agent.options[:expected_receive_period_in_days] = ""
- expect(agent).not_to be_valid
- agent.options[:expected_receive_period_in_days] = 0
- expect(agent).not_to be_valid
- agent.options[:expected_receive_period_in_days] = -1
- expect(agent).not_to be_valid
- end
- it "should validate presence of template and template.item" do
- agent.options[:template] = ""
- expect(agent).not_to be_valid
- agent.options[:template] = {}
- expect(agent).not_to be_valid
- agent.options[:template] = { 'item' => 'foo' }
- expect(agent).not_to be_valid
- agent.options[:template] = { 'item' => { 'title' => 'hi' } }
- expect(agent).to be_valid
- end
- end
- describe "#receive_web_request" do
- before do
- current_time = Time.now
- stub(Time).now { current_time }
- agents(:bob_website_agent).events.destroy_all
- end
- it "requires a valid secret" do
- content, status, content_type = agent.receive_web_request({ 'secret' => 'fake' }, 'get', 'text/xml')
- expect(status).to eq(401)
- expect(content).to eq("Not Authorized")
- content, status, content_type = agent.receive_web_request({ 'secret' => 'fake' }, 'get', 'application/json')
- expect(status).to eq(401)
- expect(content).to eq({ :error => "Not Authorized" })
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'application/json')
- expect(status).to eq(200)
- end
- describe "outputting events as RSS and JSON" do
- let!(:event1) do
- agents(:bob_website_agent).create_event :payload => {
- "site_title" => "XKCD",
- "url" => "http://imgs.xkcd.com/comics/evolving.png",
- "title" => "Evolving",
- "hovertext" => "Biologists play reverse Pokemon, trying to avoid putting any one team member on the front lines long enough for the experience to cause evolution."
- }
- end
- let!(:event2) do
- agents(:bob_website_agent).create_event :payload => {
- "site_title" => "XKCD",
- "url" => "http://imgs.xkcd.com/comics/evolving2.png",
- "title" => "Evolving again",
- "date" => '',
- "hovertext" => "Something else"
- }
- end
- let!(:event3) do
- agents(:bob_website_agent).create_event :payload => {
- "site_title" => "XKCD",
- "url" => "http://imgs.xkcd.com/comics/evolving0.png",
- "title" => "Evolving yet again with a past date",
- "date" => '2014/05/05',
- "hovertext" => "Something else"
- }
- end
- it "can output RSS" do
- stub(agent).feed_link { "https://yoursite.com" }
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
- expect(status).to eq(200)
- expect(content_type).to eq('text/xml')
- expect(content.gsub(/\s+/, '')).to eq Utils.unindent(<<-XML).gsub(/\s+/, '')
- <?xml version="1.0" encoding="UTF-8" ?>
- <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <atom:link href="https://yoursite.com/users/#{agent.user.id}/web_requests/#{agent.id}/secret1.xml" rel="self" type="application/rss+xml"/>
- <atom:icon>https://yoursite.com/favicon.ico</atom:icon>
- <title>XKCD comics as a feed</title>
- <description>This is a feed of recent XKCD comics, generated by Huginn</description>
- <link>https://yoursite.com</link>
- <lastBuildDate>
- <pubDate>
- <ttl>60</ttl>
- <item>
- <title>Evolving yet again with a past date</title>
- <description>Secret hovertext: Something else</description>
- <link>http://imgs.xkcd.com/comics/evolving0.png</link>
- <pubDate>
- <guid isPermaLink="false">
- </item>
- <item>
- <title>Evolving again</title>
- <description>Secret hovertext: Something else</description>
- <link>http://imgs.xkcd.com/comics/evolving2.png</link>
- <pubDate>
- <guid isPermaLink="false">
- </item>
- <item>
- <title>Evolving</title>
- <description>Secret hovertext: Biologists play reverse Pokemon, trying to avoid putting any one team member on the front lines long enough for the experience to cause evolution.</description>
- <link>http://imgs.xkcd.com/comics/evolving.png</link>
- <pubDate>
- <guid isPermaLink="false">
- </item>
- </channel>
- </rss>
- XML
- end
- it "can output JSON" do
- agent.options['template']['item']['foo'] = "hi"
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
- expect(status).to eq(200)
- expect(content).to eq({
- 'title' => 'XKCD comics as a feed',
- 'description' => 'This is a feed of recent XKCD comics, generated by Huginn',
- 'pubDate' => Time.now,
- 'items' => [
- {
- 'title' => 'Evolving yet again with a past date',
- 'description' => 'Secret hovertext: Something else',
- 'link' => 'http://imgs.xkcd.com/comics/evolving0.png',
- 'guid' => {"contents" => event3.id, "isPermaLink" => "false"},
- 'pubDate' => Time.zone.parse(event3.payload['date']).rfc2822,
- 'foo' => 'hi'
- },
- {
- 'title' => 'Evolving again',
- 'description' => 'Secret hovertext: Something else',
- 'link' => 'http://imgs.xkcd.com/comics/evolving2.png',
- 'guid' => {"contents" => event2.id, "isPermaLink" => "false"},
- 'pubDate' => event2.created_at.rfc2822,
- 'foo' => 'hi'
- },
- {
- 'title' => 'Evolving',
- 'description' => 'Secret hovertext: Biologists play reverse Pokemon, trying to avoid putting any one team member on the front lines long enough for the experience to cause evolution.',
- 'link' => 'http://imgs.xkcd.com/comics/evolving.png',
- 'guid' => {"contents" => event1.id, "isPermaLink" => "false"},
- 'pubDate' => event1.created_at.rfc2822,
- 'foo' => 'hi'
- }
- ]
- })
- end
- describe 'ordering' do
- before do
- agent.options['events_order'] = ['{{title}}']
- end
- it 'can reorder the events_to_show last events based on a Liquid expression' do
- asc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
- expect(asc_content['items'].map {|i| i["title"] }).to eq(["Evolving", "Evolving again", "Evolving yet again with a past date"])
- agent.options['events_order'] = [['{{title}}', 'string', true]]
- desc_content, _status, _content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
- expect(desc_content['items']).to eq(asc_content['items'].reverse)
- end
- end
- describe "interpolating \"events\"" do
- before do
- agent.options['template']['title'] = "XKCD comics as a feed{% if events.first.site_title %} ({{events.first.site_title}}){% endif %}"
- agent.save!
- end
- it "can output RSS" do
- stub(agent).feed_link { "https://yoursite.com" }
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
- expect(status).to eq(200)
- expect(content_type).to eq('text/xml')
- expect(Nokogiri(content).at('/rss/channel/title/text()').text).to eq('XKCD comics as a feed (XKCD)')
- end
- it "can output JSON" do
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
- expect(status).to eq(200)
- expect(content['title']).to eq('XKCD comics as a feed (XKCD)')
- end
- end
- describe "with a specified icon" do
- before do
- agent.options['template']['icon'] = 'https://somesite.com/icon.png'
- agent.save!
- end
- it "can output RSS" do
- stub(agent).feed_link { "https://yoursite.com" }
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
- expect(status).to eq(200)
- expect(content_type).to eq('text/xml')
- expect(Nokogiri(content).at('/rss/channel/atom:icon/text()').text).to eq('https://somesite.com/icon.png')
- end
- end
- end
- describe "outputting nesting" do
- before do
- agent.options['template']['item']['enclosure'] = {
- "_attributes" => {
- "type" => "audio/mpeg",
- "url" => "{{media_url}}"
- }
- }
- agent.options['template']['item']['foo'] = {
- "_attributes" => {
- "attr" => "attr-value-{{foo}}"
- },
- "_contents" => "Foo: {{foo}}"
- }
- agent.options['template']['item']['nested'] = {
- "_attributes" => {
- "key" => "value"
- },
- "_contents" => {
- "title" => "some title"
- }
- }
- agent.options['template']['item']['simpleNested'] = {
- "title" => "some title",
- "complex" => {
- "_attributes" => {
- "key" => "value"
- },
- "_contents" => {
- "first" => {
- "_attributes" => {
- "a" => "b"
- },
- "_contents" => {
- "second" => "value"
- }
- }
- }
- }
- }
- agent.save!
- end
- let!(:event) do
- agents(:bob_website_agent).create_event :payload => {
- "url" => "http://imgs.xkcd.com/comics/evolving.png",
- "title" => "Evolving",
- "hovertext" => "Biologists play reverse Pokemon, trying to avoid putting any one team member on the front lines long enough for the experience to cause evolution.",
- "media_url" => "http://google.com/audio.mpeg",
- "foo" => 1
- }
- end
- it "can output JSON" do
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret2' }, 'get', 'application/json')
- expect(status).to eq(200)
- expect(content['items'].first).to eq(
- {
- 'title' => 'Evolving',
- 'description' => 'Secret hovertext: Biologists play reverse Pokemon, trying to avoid putting any one team member on the front lines long enough for the experience to cause evolution.',
- 'link' => 'http://imgs.xkcd.com/comics/evolving.png',
- 'guid' => {"contents" => event.id, "isPermaLink" => "false"},
- 'pubDate' => event.created_at.rfc2822,
- 'enclosure' => {
- "type" => "audio/mpeg",
- "url" => "http://google.com/audio.mpeg"
- },
- 'foo' => {
- 'attr' => 'attr-value-1',
- 'contents' => 'Foo: 1'
- },
- 'nested' => {
- "key" => "value",
- "title" => "some title"
- },
- 'simpleNested' => {
- "title" => "some title",
- "complex" => {
- "key"=>"value",
- "first" => {
- "a" => "b",
- "second"=>"value"
- }
- }
- }
- }
- )
- end
- it "can output RSS" do
- stub(agent).feed_link { "https://yoursite.com" }
- content, status, content_type = agent.receive_web_request({ 'secret' => 'secret1' }, 'get', 'text/xml')
- expect(status).to eq(200)
- expect(content_type).to eq('text/xml')
- expect(content.gsub(/\s+/, '')).to eq Utils.unindent(<<-XML).gsub(/\s+/, '')
- <?xml version="1.0" encoding="UTF-8" ?>
- <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <atom:link href="https://yoursite.com/users/#{agent.user.id}/web_requests/#{agent.id}/secret1.xml" rel="self" type="application/rss+xml"/>
- <atom:icon>https://yoursite.com/favicon.ico</atom:icon>
- <title>XKCD comics as a feed</title>
- <description>This is a feed of recent XKCD comics, generated by Huginn</description>
- <link>https://yoursite.com</link>
- <lastBuildDate>#{Time.now.rfc2822}</lastBuildDate>
- <pubDate>#{Time.now.rfc2822}</pubDate>
- <ttl>60</ttl>
- <item>
- <title>Evolving</title>
- <description>Secret hovertext: Biologists play reverse Pokemon, trying to avoid putting any one team member on the front lines long enough for the experience to cause evolution.</description>
- <link>http://imgs.xkcd.com/comics/evolving.png</link>
- <pubDate>#{event.created_at.rfc2822}</pubDate>
- <enclosure type="audio/mpeg" url="http://google.com/audio.mpeg" />
- <foo attr="attr-value-1">Foo: 1</foo>
- <nested key="value"><title>some title</title></nested>
- <simpleNested>
- <title>some title</title>
- <complex key="value">
- <first a="b">
- <second>value</second>
- </first>
- </complex>
- </simpleNested>
- <guid isPermaLink="false">#{event.id}</guid>
- </item>
- </channel>
- </rss>
- XML
- end
- end
- end
- end
|