ruby-oembed 0.14.1 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.rdoc +13 -1
  4. data/lib/oembed.rb +1 -0
  5. data/lib/oembed/provider.rb +54 -5
  6. data/lib/oembed/providers.rb +39 -300
  7. data/lib/oembed/providers/aggregators/embedly_urls.yml +167 -6
  8. data/lib/oembed/providers/builtin_providers.rb +292 -0
  9. data/lib/oembed/providers/facebook_post.rb +27 -17
  10. data/lib/oembed/providers/facebook_video.rb +22 -10
  11. data/lib/oembed/providers/instagram.rb +37 -20
  12. data/lib/oembed/providers/tik_tok.rb +11 -0
  13. data/lib/oembed/version.rb +2 -2
  14. data/spec/cassettes/OEmbed_Provider.yml +117 -16
  15. data/spec/cassettes/OEmbed_Providers_CodePen.yml +177 -0
  16. data/spec/cassettes/OEmbed_Providers_FacebookPost.yml +539 -0
  17. data/spec/cassettes/OEmbed_Providers_FacebookVideo.yml +267 -0
  18. data/spec/cassettes/OEmbed_Providers_Instagram.yml +1473 -0
  19. data/spec/cassettes/OEmbed_Providers_Slideshare.yml +420 -834
  20. data/spec/cassettes/OEmbed_Providers_TikTok.yml +293 -0
  21. data/spec/cassettes/OEmbed_Providers_Twitter.yml +84 -357
  22. data/spec/cassettes/OEmbed_Providers_Youtube.yml +188 -26
  23. data/spec/provider_spec.rb +315 -138
  24. data/spec/providers/code_pen_spec.rb +21 -0
  25. data/spec/providers/facebook_post_spec.rb +54 -0
  26. data/spec/providers/facebook_video_spec.rb +48 -0
  27. data/spec/providers/instagram_spec.rb +48 -0
  28. data/spec/providers/slideshare_spec.rb +2 -9
  29. data/spec/providers/tik_tok_spec.rb +26 -0
  30. data/spec/providers/twitter_spec.rb +3 -10
  31. data/spec/providers/youtube_spec.rb +3 -9
  32. data/spec/providers_spec.rb +151 -16
  33. data/spec/response_spec.rb +2 -2
  34. data/spec/spec_helper.rb +19 -1
  35. data/spec/support/shared_examples_for_providers.rb +32 -20
  36. metadata +25 -5
  37. data/spec/providers/facebook_spec.rb +0 -50
@@ -0,0 +1,21 @@
1
+ require File.join(File.dirname(__FILE__), '../spec_helper')
2
+
3
+ describe 'OEmbed::Providers::CodePen' do
4
+ use_custom_vcr_casette('OEmbed_Providers_CodePen')
5
+ include OEmbedSpecHelper
6
+
7
+ let(:provider) { OEmbed::Providers::CodePen }
8
+
9
+ expected_valid_urls = %w(
10
+ https://codepen.io/maximakymenko/pen/mdbpeXm
11
+ )
12
+ expected_invalid_urls = %w(
13
+ https://codepen.com/maximakymenko/pen/mdbpeXm
14
+ )
15
+
16
+ it_should_behave_like(
17
+ "an OEmbed::Providers instance",
18
+ expected_valid_urls,
19
+ expected_invalid_urls
20
+ )
21
+ end
@@ -0,0 +1,54 @@
1
+ require File.join(File.dirname(__FILE__), '../spec_helper')
2
+
3
+ describe 'OEmbed::Providers::FacebookPost' do
4
+ use_custom_vcr_casette('OEmbed_Providers_FacebookPost')
5
+ include OEmbedSpecHelper
6
+
7
+ let(:provider) { OEmbed::Providers::FacebookPost }
8
+
9
+ expected_valid_urls = [
10
+ # A public "post" by a "page"
11
+ 'https://www.facebook.com/rubyonrailstogo/posts/3610333842332884',
12
+ # A public "note"
13
+ 'https://www.facebook.com/notes/facebook-app/welcome-to-the-facebook-blog/2207517130/',
14
+ # A specific photo
15
+ 'https://www.facebook.com/tumocenter/photos/bc.AbpR7-R7Lu6GodUph_UNg1Ttn-k7Ni-M8X89Io4cWsYkK0OPde6MTVKHSiTNDEanWYkwQGyu-YwpNnS4MXUqeYen_ovuiBPQixaA-tjNBcVUFAMWPaxX-NU1mm2ovExEORQOdohcH339Xmxch3kbSPcJ/1084373708267461/',
16
+ # A photo in slideshow view
17
+ 'https://www.facebook.com/photo/?fbid=3348617585198325&set=gm.1675022489341591',
18
+ ]
19
+ expected_invalid_urls = %w(
20
+ https://www.instagram.com/p/B9bOM-6Ax_d/?igshid=1mn51zsvrhoiq
21
+ https://www.facebook.com/381763475170840/videos/474308113397163/
22
+ https://www.facebook.com/groups/rordevelopers/permalink/1675022489341591/
23
+ https://www.facebook.com/business/news/tips-small-business-digital-tools-in-crisis-and-recovery-report-deloitte/
24
+ )
25
+
26
+ describe 'behaving like an OEmbed::Provider instance' do
27
+ it_should_behave_like(
28
+ "an OEmbed::Providers instance",
29
+ expected_valid_urls,
30
+ expected_invalid_urls
31
+ )
32
+ end
33
+
34
+ describe 'DEPRECATED: behaves like a custom OEmbed::Provider class for v0.14.0 backwards compatibility' do
35
+ around(:each) { |example|
36
+ # Always restore the provider's access_token to its previous value
37
+ # so that if the OEMBED_FACEBOOK_TOKEN env var is set, it's used correctly.
38
+ orig_access_token = provider.access_token
39
+ example.run
40
+ provider.access_token = orig_access_token
41
+ }
42
+ let(:access_token) { 'A_FAKE_TOKEN_FOR_TESTS' }
43
+ let(:provider_instance) { provider.new(access_token: access_token) }
44
+ let(:embed_url) { expected_valid_urls.first }
45
+
46
+ it 'sets the access_token' do
47
+ expect(provider_instance.access_token).to eq(access_token)
48
+ end
49
+
50
+ it 'recognizes embed URLs' do
51
+ expect(provider_instance).to include(embed_url)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,48 @@
1
+ require File.join(File.dirname(__FILE__), '../spec_helper')
2
+
3
+ describe 'OEmbed::Providers::FacebookVideo' do
4
+ use_custom_vcr_casette('OEmbed_Providers_FacebookVideo')
5
+ include OEmbedSpecHelper
6
+
7
+ let(:provider) { OEmbed::Providers::FacebookVideo }
8
+
9
+ expected_valid_urls = %w(
10
+ https://www.facebook.com/381763475170840/videos/474308113397163/
11
+ https://www.facebook.com/osherove/videos/10157895173751223/
12
+ )
13
+ expected_invalid_urls = %w(
14
+ https://www.instagram.com/p/B9bOM-6Ax_d/?igshid=1mn51zsvrhoiq
15
+ https://www.facebook.com/rubyonrailstogo/posts/3610333842332884
16
+ https://www.facebook.com/groups/rordevelopers/permalink/1675022489341591/
17
+ https://www.facebook.com/business/news/tips-small-business-digital-tools-in-crisis-and-recovery-report-deloitte/
18
+ )
19
+
20
+ describe 'behaving like an OEmbed::Provider instance' do
21
+ it_should_behave_like(
22
+ "an OEmbed::Providers instance",
23
+ expected_valid_urls,
24
+ expected_invalid_urls
25
+ )
26
+ end
27
+
28
+ describe 'DEPRECATED: behaves like a custom OEmbed::Provider class for v0.14.0 backwards compatibility' do
29
+ around(:each) { |example|
30
+ # Always restore the provider's access_token to its previous value
31
+ # so that if the OEMBED_FACEBOOK_TOKEN env var is set, it's used correctly.
32
+ orig_access_token = provider.access_token
33
+ example.run
34
+ provider.access_token = orig_access_token
35
+ }
36
+ let(:access_token) { 'A_FAKE_TOKEN_FOR_TESTS' }
37
+ let(:provider_instance) { provider.new(access_token: access_token) }
38
+ let(:embed_url) { expected_valid_urls.first }
39
+
40
+ it 'sets the access_token' do
41
+ expect(provider_instance.access_token).to eq(access_token)
42
+ end
43
+
44
+ it 'recognizes embed URLs' do
45
+ expect(provider_instance).to include(embed_url)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,48 @@
1
+ require File.join(File.dirname(__FILE__), '../spec_helper')
2
+
3
+ describe 'OEmbed::Providers::Instagram' do
4
+ use_custom_vcr_casette('OEmbed_Providers_Instagram')
5
+ include OEmbedSpecHelper
6
+
7
+ let(:provider) { OEmbed::Providers::Instagram }
8
+
9
+ expected_valid_urls = %w(
10
+ https://www.instagram.com/p/B9bOM-6Ax_d/?igshid=1mn51zsvrhoiq
11
+ https://instagram.com/p/B9bOM-6Ax_d/?igshid=1mn51zsvrhoiq
12
+ http://instagr.am/p/B9bOM-6Ax_d/?igshid=1mn51zsvrhoiq
13
+ https://www.instagram.com/tv/CCX-gcHArcJ/?igshid=1i0rst4jaz0j
14
+ https://www.instagram.com/reel/CIyNZQhH4DQ/?igshid=40rns9jda1ow
15
+ )
16
+ expected_invalid_urls = %w(
17
+ https://www.instagram.com/u/CCX-gcHArcJ/?igshid=1i0rst4jaz0j
18
+ )
19
+
20
+ describe 'behaving like an OEmbed::Provider instance' do
21
+ it_should_behave_like(
22
+ "an OEmbed::Providers instance",
23
+ expected_valid_urls,
24
+ expected_invalid_urls
25
+ )
26
+ end
27
+
28
+ describe 'DEPRECATED: behaves like a custom OEmbed::Provider class for v0.14.0 backwards compatibility' do
29
+ around(:each) { |example|
30
+ # Always restore the provider's access_token to its previous value
31
+ # so that if the OEMBED_FACEBOOK_TOKEN env var is set, it's used correctly.
32
+ orig_access_token = provider.access_token
33
+ example.run
34
+ provider.access_token = orig_access_token
35
+ }
36
+ let(:access_token) { 'A_FAKE_TOKEN_FOR_TESTS' }
37
+ let(:provider_instance) { provider.new(access_token: access_token) }
38
+ let(:embed_url) { expected_valid_urls.first }
39
+
40
+ it 'sets the access_token' do
41
+ expect(provider_instance.access_token).to eq(access_token)
42
+ end
43
+
44
+ it 'recognizes embed URLs' do
45
+ expect(provider_instance).to include(embed_url)
46
+ end
47
+ end
48
+ end
@@ -1,17 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), '../spec_helper')
2
- require 'support/shared_examples_for_providers'
3
2
 
4
3
  describe 'OEmbed::Providers::Slideshare' do
5
- before(:all) do
6
- VCR.insert_cassette('OEmbed_Providers_Slideshare')
7
- end
8
- after(:all) do
9
- VCR.eject_cassette
10
- end
11
-
4
+ use_custom_vcr_casette('OEmbed_Providers_Slideshare')
12
5
  include OEmbedSpecHelper
13
6
 
14
- let(:provider_class) { OEmbed::Providers::Slideshare }
7
+ let(:provider) { OEmbed::Providers::Slideshare }
15
8
 
16
9
  expected_valid_urls = (
17
10
  %w(https:// http://).map do |protocol|
@@ -0,0 +1,26 @@
1
+ require File.join(File.dirname(__FILE__), '../spec_helper')
2
+
3
+ describe 'OEmbed::Providers::TikTok' do
4
+ use_custom_vcr_casette('OEmbed_Providers_TikTok')
5
+ include OEmbedSpecHelper
6
+
7
+ let(:provider) { OEmbed::Providers::TikTok }
8
+
9
+ expected_valid_urls = [
10
+ # Specific videos
11
+ 'https://www.tiktok.com/@sowylie/video/6903556111169899781',
12
+ 'https://www.tiktok.com/@cassidoo/video/6841722789502749957',
13
+ ]
14
+ expected_invalid_urls = [
15
+ # An author's page
16
+ 'https://www.tiktok.com/@sowylie',
17
+ # The safety page/docs
18
+ 'https://www.tiktok.com/safety?lang=en',
19
+ ]
20
+
21
+ it_should_behave_like(
22
+ "an OEmbed::Providers instance",
23
+ expected_valid_urls,
24
+ expected_invalid_urls
25
+ )
26
+ end
@@ -1,17 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), '../spec_helper')
2
- require 'support/shared_examples_for_providers'
3
2
 
4
3
  describe 'OEmbed::Providers::Twitter' do
5
- before(:all) do
6
- VCR.insert_cassette('OEmbed_Providers_Twitter')
7
- end
8
- after(:all) do
9
- VCR.eject_cassette
10
- end
11
-
4
+ use_custom_vcr_casette('OEmbed_Providers_Twitter')
12
5
  include OEmbedSpecHelper
13
6
 
14
- let(:provider_class) { OEmbed::Providers::Twitter }
7
+ let(:provider) { OEmbed::Providers::Twitter }
15
8
 
16
9
  expected_valid_urls = %w(
17
10
  https://twitter.com/RailsGirlsSoC/status/702136612822634496
@@ -34,7 +27,7 @@ describe 'OEmbed::Providers::Twitter' do
34
27
  describe ".get" do
35
28
  it "should encounter a 400 error" do
36
29
  expect {
37
- provider_class.get(valid_url, :format=>:xml)
30
+ provider.get(valid_url, format: :xml)
38
31
  }.to raise_error(OEmbed::UnknownResponse, /\b400\b/)
39
32
  end
40
33
  end
@@ -1,16 +1,10 @@
1
1
  require File.join(File.dirname(__FILE__), '../spec_helper')
2
2
 
3
3
  describe 'OEmbed::Providers::Youtube' do
4
- before(:all) do
5
- VCR.insert_cassette('OEmbed_Providers_Youtube')
6
- end
7
- after(:all) do
8
- VCR.eject_cassette
9
- end
10
-
4
+ use_custom_vcr_casette('OEmbed_Providers_Youtube')
11
5
  include OEmbedSpecHelper
12
6
 
13
- let(:provider_class) { OEmbed::Providers::Youtube }
7
+ let(:provider) { OEmbed::Providers::Youtube }
14
8
 
15
9
  expected_valid_urls = %w(
16
10
  https://www.youtube.com/watch?v=pO5L6vXtxsI
@@ -34,7 +28,7 @@ describe 'OEmbed::Providers::Youtube' do
34
28
 
35
29
  it "should throw an UnknownResponse error" do
36
30
  expect {
37
- provider_class.get(invalid_url)
31
+ provider.get(invalid_url)
38
32
  }.to raise_error(OEmbed::UnknownResponse, /403/)
39
33
  end
40
34
  end
@@ -17,7 +17,7 @@ describe OEmbed::Providers do
17
17
  end
18
18
 
19
19
  describe ".register" do
20
- it "should register providers" do
20
+ it "should register multiple providers at once" do
21
21
  expect(OEmbed::Providers.urls).to be_empty
22
22
 
23
23
  OEmbed::Providers.register(@flickr, @qik)
@@ -35,11 +35,20 @@ describe OEmbed::Providers do
35
35
  end
36
36
  end
37
37
 
38
- it "should find by URLs" do
39
- OEmbed::Providers.register(@flickr, @qik) # tested in "should register providers"
38
+ it "should register providers with missing required_query_params" do
39
+ expect(OEmbed::Providers.urls).to be_empty
40
40
 
41
- expect(OEmbed::Providers.find(example_url(:flickr))).to eq(@flickr)
42
- expect(OEmbed::Providers.find(example_url(:qik))).to eq(@qik)
41
+ provider = OEmbed::Provider.new("http://foo.com/oembed", required_query_params: { send_with_query: nil })
42
+ provider << 'http://media.foo.com/*'
43
+
44
+ OEmbed::Providers.register(provider)
45
+
46
+ expect(OEmbed::Providers.urls.keys).to eq(provider.urls)
47
+
48
+ provider.urls.each do |regexp|
49
+ expect(OEmbed::Providers.urls).to have_key(regexp)
50
+ expect(OEmbed::Providers.urls[regexp]).to include(provider)
51
+ end
43
52
  end
44
53
  end
45
54
 
@@ -122,6 +131,134 @@ describe OEmbed::Providers do
122
131
  # and_return(valid_response(:object))
123
132
  #end
124
133
 
134
+ describe "#find" do
135
+ let(:url_scheme) { 'http://media.foo.com/*' }
136
+ let(:providerA) {
137
+ p = OEmbed::Provider.new("http://a.foo.com/oembed")
138
+ p << url_scheme
139
+ p
140
+ }
141
+ let(:providerB) {
142
+ p = OEmbed::Provider.new("http://b.foo.com/oembed")
143
+ p << url_scheme
144
+ p
145
+ }
146
+
147
+ let(:url_to_find) { 'http://media.foo.com/which-one?' }
148
+ subject { OEmbed::Providers.find(url_to_find) }
149
+
150
+ context "when there registered providers are distinct" do
151
+ before { OEmbed::Providers.register(@flickr, @qik, providerA) }
152
+
153
+ it "should find providerA" do
154
+ should eq(providerA)
155
+ end
156
+
157
+ it "should find by any of the registered providers by URL" do
158
+ expect(OEmbed::Providers.find(example_url(:flickr))).to eq(@flickr)
159
+ expect(OEmbed::Providers.find(example_url(:qik))).to eq(@qik)
160
+ end
161
+ end
162
+
163
+ context "when the registered provider has missing required_query_params" do
164
+ let(:providerA) {
165
+ p = OEmbed::Provider.new("http://a.foo.com/oembed", required_query_params: { send_with_query: false })
166
+ p << url_scheme
167
+ p
168
+ }
169
+ before { OEmbed::Providers.register(providerA) }
170
+
171
+ it "should NOT find the provider" do
172
+ should be_nil
173
+ end
174
+
175
+ context "but then later has the required_query_param set" do
176
+ it "should find providerA" do
177
+ providerA.send_with_query = 'a non-blank val'
178
+
179
+ should eq(providerA)
180
+ end
181
+ end
182
+ end
183
+
184
+ context "when multiple providers match the same URL" do
185
+ it "should find one match" do
186
+ OEmbed::Providers.register(providerA, providerB)
187
+
188
+ should eq(providerA).or eq(providerB)
189
+ end
190
+
191
+ context "when providerA has missing required_query_params" do
192
+ let(:providerA) {
193
+ p = OEmbed::Provider.new("http://a.foo.com/oembed", required_query_params: { send_with_query: false })
194
+ p << url_scheme
195
+ p
196
+ }
197
+
198
+ it "should find the provider with satisfied required_query_params" do
199
+ OEmbed::Providers.register(providerA, providerB)
200
+
201
+ should eq(providerB)
202
+ end
203
+
204
+ it "should find the provider with satisfied required_query_params, regardless of register order" do
205
+ OEmbed::Providers.register(providerB, providerA)
206
+
207
+ should eq(providerB)
208
+ end
209
+ end
210
+
211
+ context "when providerA has satisfied required_query_params" do
212
+ let(:providerA) {
213
+ p = OEmbed::Provider.new("http://a.foo.com/oembed", required_query_params: { send_with_query: false })
214
+ p.send_with_query = 'a non-blank value'
215
+ p << url_scheme
216
+ p
217
+ }
218
+
219
+ it "should find one match" do
220
+ OEmbed::Providers.register(providerA, providerB)
221
+
222
+ should eq(providerA).or eq(providerB)
223
+ end
224
+
225
+ it "should find one match, regardless of register order" do
226
+ OEmbed::Providers.register(providerB, providerA)
227
+
228
+ should eq(providerA).or eq(providerB)
229
+ end
230
+ end
231
+
232
+ context "but with slightly different URL schemes" do
233
+ let(:url_to_find) { 'http://media.foo.com/video/which-one?' }
234
+ let(:broad_url_scheme) { 'http://media.foo.com/*' }
235
+ let(:specific_url_scheme) { 'http://media.foo.com/video/*' }
236
+ let(:providerA) {
237
+ p = OEmbed::Provider.new("http://a.foo.com/oembed")
238
+ p << broad_url_scheme
239
+ p
240
+ }
241
+ let(:providerB) {
242
+ p = OEmbed::Provider.new("http://a.foo.com/oembed")
243
+ p << specific_url_scheme
244
+ p
245
+ }
246
+
247
+ it "should find one match" do
248
+ OEmbed::Providers.register(providerA, providerB)
249
+
250
+ should eq(providerA).or eq(providerB)
251
+ end
252
+
253
+ it "should find one match, regardless of register order" do
254
+ OEmbed::Providers.register(providerB, providerA)
255
+
256
+ should eq(providerA).or eq(providerB)
257
+ end
258
+ end
259
+ end
260
+ end
261
+
125
262
  describe "#raw and #get" do
126
263
  it "should bridge #get and #raw to the right provider" do
127
264
  OEmbed::Providers.register_all
@@ -213,13 +350,16 @@ describe OEmbed::Providers do
213
350
  describe 'register_access_token_providers' do
214
351
  describe 'tokens[:facebook]' do
215
352
  let(:access_token) { 'my-fake-access-token' }
353
+ let(:provider) { OEmbed::Providers::FacebookPost }
216
354
  let(:embed_url) { 'https://www.facebook.com/exampleuser/posts/1234567890' }
217
355
 
218
356
  around(:each) do |each|
219
357
  previous_value = ENV['OEMBED_FACEBOOK_TOKEN']
220
358
  ENV['OEMBED_FACEBOOK_TOKEN'] = nil
359
+ provider.access_token = nil
221
360
  each.run
222
361
  ENV['OEMBED_FACEBOOK_TOKEN'] = previous_value
362
+ provider.access_token = previous_value
223
363
  OEmbed::Providers.unregister_all
224
364
  end
225
365
 
@@ -230,7 +370,8 @@ describe OEmbed::Providers do
230
370
  OEmbed::Providers.register_all
231
371
  end
232
372
 
233
- it { is_expected.to_not be_a(OEmbed::Providers::FacebookPost) }
373
+ it { is_expected.to_not eql(provider) }
374
+ it { is_expected.to eq(nil) }
234
375
  end
235
376
 
236
377
  context 'when access token is provided to register_all' do
@@ -238,22 +379,16 @@ describe OEmbed::Providers do
238
379
  OEmbed::Providers.register_all(access_tokens: { facebook: access_token })
239
380
  end
240
381
 
241
- it { is_expected.to be_a(OEmbed::Providers::FacebookPost) }
382
+ it { is_expected.to eql(provider) }
242
383
  end
243
384
 
244
- context 'when access token is set as an environment variable' do
385
+ context 'when access token is set ahead of time' do
245
386
  before do
246
- ENV['OEMBED_FACEBOOK_TOKEN'] = access_token
387
+ provider.access_token = access_token
247
388
  OEmbed::Providers.register_all
248
389
  end
249
390
 
250
- it { is_expected.to be_a(OEmbed::Providers::FacebookPost) }
251
- end
252
-
253
- context 'without access token' do
254
- before { OEmbed::Providers.register_all }
255
-
256
- it { is_expected.to eq(nil) }
391
+ it { is_expected.to eql(provider) }
257
392
  end
258
393
  end
259
394
  end