diff --git a/Gemfile b/Gemfile index 0f5979e16..81a64fabb 100644 --- a/Gemfile +++ b/Gemfile @@ -176,9 +176,10 @@ end group :test do # RSpec (unit tests, some integration tests) - gem 'fixture_builder', '0.3.6' - gem 'fuubar', '1.1.1' - gem 'rspec-instafail', '0.2.4', :require => false + gem 'fixture_builder', '0.3.6' + gem 'fuubar', '1.1.1' + gem 'rspec-instafail', '0.2.4', :require => false + gem 'test_after_commit', '0.2.0' # Cucumber (integration tests) diff --git a/Gemfile.lock b/Gemfile.lock index 49589170f..2117eff1b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -389,6 +389,7 @@ GEM railties (~> 3.0) subexec (0.2.3) temple (0.6.6) + test_after_commit (0.2.0) thor (0.18.1) tilt (1.4.1) timecop (0.6.1) @@ -495,6 +496,7 @@ DEPENDENCIES slim (= 1.3.9) spork (= 1.0.0rc3) strong_parameters + test_after_commit (= 0.2.0) timecop (= 0.6.1) twitter (= 4.8.1) typhoeus (= 0.6.3) diff --git a/spec/factories.rb b/spec/factories.rb index fb86ad3b9..4967416f6 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -185,6 +185,14 @@ FactoryGirl.define do data {{'data' => 'foo'}} end + factory(:open_graph_cache) do + url "http://example.com/articles/123" + image "http://example.com/images/123.jpg" + title "Some article" + ob_type "article" + description "This is the article lead" + end + factory(:tag_following) do association(:tag, :factory => :tag) association(:user, :factory => :user) diff --git a/spec/helpers/open_graph_helper_spec.rb b/spec/helpers/open_graph_helper_spec.rb new file mode 100644 index 000000000..f6b72f1fa --- /dev/null +++ b/spec/helpers/open_graph_helper_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe OpenGraphHelper do + describe 'og_html' do + scenarios = { + "article" => { + "url" => "http://opengraph-enabled-site.com/articles/1332-scientists-discover-new-planet", + "image" => "http://opengraph-enabled-site.com/images/1332-lead.jpg", + "title" => "Scientists discover new planet", + "description" => "A new planet was found yesterday" + }, + } + + scenarios.each do |type, data| + specify 'for type "'+type+'"' do + cache = OpenGraphCache.new(:url => data['url']) + cache.ob_type = type + cache.image = data['image'] + cache.title = data['title'] + cache.description = data['description'] + + formatted = og_html(cache) + + formatted.should =~ /#{data['url']}/ + formatted.should =~ /#{data['title']}/ + formatted.should =~ /#{data['image']}/ + formatted.should =~ /#{data['description']}/ + end + end + end +end diff --git a/spec/javascripts/app/views/open_graph_view_spec.js b/spec/javascripts/app/views/open_graph_view_spec.js new file mode 100644 index 000000000..d17c345ba --- /dev/null +++ b/spec/javascripts/app/views/open_graph_view_spec.js @@ -0,0 +1,30 @@ +describe("app.views.OpenGraph", function() { + var open_graph_cache = { + "url": "http://example.com/articles/123", + "title": "Example title", + "description": "Test description", + "image": "http://example.com/thumb.jpg", + "ob_type": "article" + }; + + beforeEach(function(){ + this.statusMessage = factory.statusMessage({ + "open_graph_cache": open_graph_cache + }); + + this.view = new app.views.OpenGraph({model : this.statusMessage}) + }); + + describe("rendering", function(){ + it("shows the preview based on the opengraph data", function(){ + this.view.render(); + var html = this.view.$el.html(); + + expect(html).toContain(open_graph_cache.url); + expect(html).toContain(open_graph_cache.title); + expect(html).toContain(open_graph_cache.description); + expect(html).toContain(open_graph_cache.image); + }); + }); + +}); diff --git a/spec/javascripts/app/views/post/small_frame_view_spec.js b/spec/javascripts/app/views/post/small_frame_view_spec.js index c4e022cb1..62e2b4a62 100644 --- a/spec/javascripts/app/views/post/small_frame_view_spec.js +++ b/spec/javascripts/app/views/post/small_frame_view_spec.js @@ -1,4 +1,18 @@ describe("app.views.Post.SmallFrame", function(){ + var open_graph_cache = { + "url": "http://example.com/articles/123", + "title": "Example title", + "description": "Test description", + "image": "http://example.com/thumb.jpg", + "ob_type": "article" + }; + + var o_embed_cache = { + "data":{ + "html":"this is a crazy oemebed lol" + } + }; + beforeEach(function(){ this.model = factory.post({ photos : [ @@ -11,12 +25,8 @@ describe("app.views.Post.SmallFrame", function(){ }), factory.photoAttrs({sizes : {large : "http://whatthefuckiselizabethstarkupto.com/none_knows.gif"}}) //SIC ], - - "o_embed_cache":{ - "data":{ - "html":"this is a crazy oemebed lol" - } - } + o_embed_cache: o_embed_cache, + open_graph_cache: open_graph_cache }) this.view = new app.views.Post.SmallFrame({model : this.model}) @@ -26,14 +36,37 @@ describe("app.views.Post.SmallFrame", function(){ expect(this.view.oEmbedView().model).toBe(this.model) }) - describe("rendering", function(){ + it("passes the model down to the opengraph view", function(){ + expect(this.view.openGraphView().model).toBe(this.model) + }) + + describe("rendering with oembed and opengraph", function(){ beforeEach(function(){ this.view.render() }); it("has the oembed", function(){ //integration test - expect($.trim(this.view.$(".embed-frame").text())).toContain("this is a crazy oemebed lol") + expect($.trim(this.view.$(".embed-frame").text())).toContain(o_embed_cache.data.html) }) + + it("doesn't have opengraph preview", function(){ + expect($.trim(this.view.$(".embed-frame").text())).not.toContain(open_graph_cache.title) + }) + }) + + describe("rendering with opengraph only", function(){ + beforeEach(function(){ + this.view = new app.views.Post.SmallFrame({ + model : factory.post({ + open_graph_cache: open_graph_cache + }) + }) + this.view.render() + }); + + it("displays opengraph preview", function(){ + expect($.trim(this.view.$(".open-graph-frame").text())).toContain(open_graph_cache.title) + }); }) describe("redirecting to a post", function(){ diff --git a/spec/javascripts/app/views/stream_post_spec.js b/spec/javascripts/app/views/stream_post_spec.js index 1f908b59c..dd782ba6a 100644 --- a/spec/javascripts/app/views/stream_post_spec.js +++ b/spec/javascripts/app/views/stream_post_spec.js @@ -4,6 +4,20 @@ describe("app.views.StreamPost", function(){ }) describe("#render", function(){ + var o_embed_cache = { + "data" : { + "html" : "some html" + } + }; + + var open_graph_cache = { + "url": "http://example.com/articles/123", + "title": "Example title", + "description": "Test description", + "image": "http://example.com/thumb.jpg", + "ob_type": "article" + }; + beforeEach(function(){ loginAs({name: "alice", avatar : {small : "http://avatar.com/photo.jpg"}}); @@ -59,14 +73,28 @@ describe("app.views.StreamPost", function(){ context("embed_html", function(){ it("provides oembed html from the model response", function(){ - this.statusMessage.set({"o_embed_cache" : { - "data" : { - "html" : "some html" - } - }}) + this.statusMessage.set({"o_embed_cache" : o_embed_cache}) var view = new app.views.StreamPost({model : this.statusMessage}).render(); - expect(view.$el.html()).toContain("some html") + expect(view.$el.html()).toContain(o_embed_cache.data.html) + }) + }) + + context("og_html", function(){ + it("provides opengraph preview based on the model reponse", function(){ + this.statusMessage.set({"open_graph_cache" : open_graph_cache}); + + var view = new app.views.StreamPost({model : this.statusMessage}).render(); + expect(view.$el.html()).toContain(open_graph_cache.title) + }); + it("does not provide opengraph preview, when oembed is available", function(){ + this.statusMessage.set({ + "o_embed_cache" : o_embed_cache, + "open_graph_cache" : open_graph_cache + }); + + var view = new app.views.StreamPost({model : this.statusMessage}).render(); + expect(view.$el.html()).not.toContain(open_graph_cache.title) }) }) diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index 48adcd0cf..a3c8692ac 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -61,6 +61,7 @@ factory = { "guid" : this.guid(), "image_url" : null, "o_embed_cache" : null, + "open_graph_cache": null, "photos" : [], "text" : "jasmine is bomb", "id" : this.id.next(), diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index e80c23096..0395cffcd 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -388,4 +388,25 @@ STR end end end + + describe 'opengraph' do + before do + @youtube_url = "https://www.youtube.com/watch?v=3PtFwlKfvHI" + @message_text = "#{@youtube_url} is so cool. so is this link -> https://joindiaspora.com" + end + + it 'should queue a GatherOpenGraphData if it includes a link' do + sm = FactoryGirl.build(:status_message, :text => @message_text) + Workers::GatherOpenGraphData.should_receive(:perform_async).with(instance_of(Fixnum), instance_of(String)) + sm.save + end + + describe '#contains_open_graph_url_in_text?' do + it 'returns the opengraph urls found in the raw message' do + sm = FactoryGirl.build(:status_message, :text => @message_text) + sm.contains_open_graph_url_in_text?.should_not be_nil + sm.open_graph_url.should == @youtube_url + end + end + end end diff --git a/spec/workers/gather_open_graph_data_spec.rb b/spec/workers/gather_open_graph_data_spec.rb new file mode 100644 index 000000000..66914e005 --- /dev/null +++ b/spec/workers/gather_open_graph_data_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' +describe Workers::GatherOpenGraphData do + before do + @ogsite_title = 'Homepage' + @ogsite_type = 'website' + @ogsite_image = '/img/something.png' + @ogsite_url = 'http://www.we-support-open-graph.com' + @ogsite_description = 'Homepage' + + @ogsite_body = + "