diff --git a/app/models/jobs/gather_o_embed_data.rb b/app/models/jobs/gather_o_embed_data.rb index ed70e176e..fd07f7462 100644 --- a/app/models/jobs/gather_o_embed_data.rb +++ b/app/models/jobs/gather_o_embed_data.rb @@ -11,21 +11,28 @@ module Jobs include ActionView::Helpers::TextHelper include ActionView::Helpers::TagHelper + def isHttp?(url) + URI.parse(url).scheme.downcase == 'http' + end + def autolink(link, type) - return link if OEmbedCache.exists?(:url => link) + url = auto_link(link, :link => :urls).scan(/href=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?/).first.first + url = CGI::unescapeHTML(url) + + return url if OEmbedCache.exists?(:url => url) or not isHttp?(url) begin - res = ::OEmbed::Providers.get(link, {:maxwidth => 420, :maxheight => 420, :frame => 1, :iframe => 1}) + res = ::OEmbed::Providers.get(url, {:maxwidth => 420, :maxheight => 420, :frame => 1, :iframe => 1}) rescue Exception => e # noop else data = res.fields data['trusted_endpoint_url'] = res.provider.endpoint - cache = OEmbedCache.new(:url => link, :data => data) + cache = OEmbedCache.new(:url => url, :data => data) cache.save end - return link + return url end end diff --git a/features/oembed.feature b/features/oembed.feature new file mode 100644 index 000000000..6aefc2a18 --- /dev/null +++ b/features/oembed.feature @@ -0,0 +1,55 @@ +@javascript +Feature: oembed + In order to make videos easy accessible + As a user + I want the links in my posts be replaced by their oEmbed representation + + Background: + Given a user named "Alice Smith" with email "alice@alice.alice" + And I have several oEmbed data in cache + When I sign in as "alice@alice.alice" + And I am on the home page + + Scenario: Post a secure video link + Given I expand the publisher + When I fill in "status_message_fake_text" with "http://youtube.com/watch?v=M3r2XDceM6A&format=json" + And I press "Share" + + And I follow "Your Aspects" + Then I should see a video player + + Scenario: Post an unsecure video link + Given I expand the publisher + When I fill in "status_message_fake_text" with "http://mytube.com/watch?v=M3r2XDceM6A&format=json" + And I press "Share" + + And I follow "Your Aspects" + Then I should not see a video player + And I should see "http://mytube.com/watch?v=M3r2XDceM6A&format=json" + + Scenario: Post an unsecure rich-typed link + Given I expand the publisher + When I fill in "status_message_fake_text" with "http://myrichtube.com/watch?v=M3r2XDceM6A&format=json" + And I press "Share" + + And I follow "Your Aspects" + Then I should not see a video player + And I should see "http://myrichtube.com/watch?v=M3r2XDceM6A&format=json" + + Scenario: Post a photo link + Given I expand the publisher + When I fill in "status_message_fake_text" with "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg" + And I press "Share" + + And I follow "Your Aspects" + Then I should see a "img" within ".stream_element" + + Scenario: Post an unsupported text link + Given I expand the publisher + When I fill in "status_message_fake_text" with "http://www.we-do-not-support-oembed.com/index.html" + And I press "Share" + + And I follow "Your Aspects" + Then I should see "http://www.we-do-not-support-oembed.com/index.html" within ".stream_element" + + diff --git a/features/step_definitions/oembed.rb b/features/step_definitions/oembed.rb new file mode 100644 index 000000000..ade28cc3c --- /dev/null +++ b/features/step_definitions/oembed.rb @@ -0,0 +1,118 @@ +Given /^I have several oEmbed data in cache$/ do + scenarios = { + "photo" => { + "oembed_data" => { + "trusted_endpoint_url" => "__!SPOOFED!__", + "version" => "1.0", + "type" => "photo", + "title" => "ZB8T0193", + "width" => "240", + "height" => "160", + "url" => "http://farm4.static.flickr.com/3123/2341623661_7c99f48bbf_m.jpg" + }, + "link_url" => 'http://www.flickr.com/photos/bees/2341623661', + "oembed_get_request" => "http://www.flickr.com/services/oembed/?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&url=http://www.flickr.com/photos/bees/2341623661", + }, + + "unsupported" => { + "oembed_data" => {}, + "oembed_get_request" => 'http://www.we-do-not-support-oembed.com/index.html', + "link_url" => 'http://www.we-do-not-support-oembed.com/index.html', + "discovery_data" => 'no LINK tag!', + }, + + "secure_video" => { + "oembed_data" => { + "version" => "1.0", + "type" => "video", + "width" => 425, + "height" => 344, + "title" => "Amazing Nintendo Facts", + "html" => " + + + + + ", + }, + "link_url" => "http://youtube.com/watch?v=M3r2XDceM6A&format=json", + "oembed_get_request" => "http://www.youtube.com/oembed?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&url=http://youtube.com/watch?v=M3r2XDceM6A", + }, + + "unsecure_video" => { + "oembed_data" => { + "version" => "1.0", + "type" => "video", + "title" => "This is a video from an unsecure source", + "html" => " + + + + + ", + }, + "link_url" => "http://myrichtube.com/watch?v=M3r2XDceM6A&format=json", + "discovery_data" => '', + "oembed_get_request" => "http://www.mytube.com/oembed?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&url=http://mytube.com/watch?v=M3r2XDceM6A", + }, + + "secure_rich" => { + "oembed_data" => { + "version" => "1.0", + "type" => "rich", + "width" => 425, + "height" => 344, + "title" => "Amazing Nintendo Facts", + "html" => " + + + + + ", + }, + "link_url" => "http://yourichtube.com/watch?v=M3r2XDceM6A&format=json", + "oembed_get_request" => "http://www.youtube.com/oembed?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&url=http://youtube.com/watch?v=M3r2XDceM6A", + }, + + "unsecure_rich" => { + "oembed_data" => { + "version" => "1.0", + "type" => "rich", + "title" => "This is a video from an unsecure source", + "html" => " + + + + + ", + }, + "link_url" => "http://mytube.com/watch?v=M3r2XDceM6A&format=json", + "discovery_data" => '', + "oembed_get_request" => "http://www.mytube.com/oembed?format=json&frame=1&iframe=1&maxheight=420&maxwidth=420&url=http://mytube.com/watch?v=M3r2XDceM6A", + }, + } + scenarios.each do |type, data| + unless type=='unsupported' + url = data['oembed_get_request'].split('?')[0] + store_data = data['oembed_data'].merge('trusted_endpoint_url' => url) + OEmbedCache.new(:url => data['link_url'], :data => store_data.to_json); + end + end +end + +Then /^I should see a video player$/ do + page.has_css?('object') +end + +Then /^I should not see a video player$/ do + page.has_no_css?('object') +end + diff --git a/spec/helpers/markdownify_helper_spec.rb b/spec/helpers/markdownify_helper_spec.rb index af88b27ba..ca1641b96 100644 --- a/spec/helpers/markdownify_helper_spec.rb +++ b/spec/helpers/markdownify_helper_spec.rb @@ -162,8 +162,9 @@ describe MarkdownifyHelper do scenarios.each do |type, data| specify 'for type "'+type+'"' do - stub_request(:get, data['oembed_get_request']).to_return(:status => 200, :body => data['oembed_data'].to_json.to_s) + url = stub_request(:get, data['link_url']).to_return(:status => 200, :body => data['discovery_data']) if data.has_key?('discovery_data') + stub_request(:get, data['oembed_get_request']).to_return(:status => 200, :body => data['oembed_data'].to_json.to_s) message = "Look at this! "+data['link_url'] Jobs::GatherOEmbedData.perform(message)