diff --git a/lib/twitter/media/video.rb b/lib/twitter/media/video.rb new file mode 100644 index 000000000..3a67114ee --- /dev/null +++ b/lib/twitter/media/video.rb @@ -0,0 +1,31 @@ +require 'twitter/identity' +require 'twitter/media/video_info' + +module Twitter + module Media + class Video < Twitter::Identity + # @return [Array] + attr_reader :indices + display_uri_attr_reader + uri_attr_reader :expanded_uri, :media_uri, :media_uri_https, :uri + + # Returns an array of photo sizes + # + # @return [Array] + def sizes + @attrs.fetch(:sizes, []).each_with_object({}) do |(key, value), object| + object[key] = Size.new(value) + end + end + memoize :sizes + + # Returns video info + # + # @return [Twitter::Media::VideoInfo] + def video_info + VideoInfo.new(@attrs[:video_info]) unless @attrs[:video_info].nil? + end + memoize :video_info + end + end +end diff --git a/lib/twitter/media/video_info.rb b/lib/twitter/media/video_info.rb new file mode 100644 index 000000000..41116cb0a --- /dev/null +++ b/lib/twitter/media/video_info.rb @@ -0,0 +1,23 @@ +require 'twitter/variant' + +module Twitter + module Media + class VideoInfo < Twitter::Base + # @return [Array] + def variants + @attrs.fetch(:variants, []).map do |variant| + Variant.new(variant) + end + end + memoize :variants + end + end +end diff --git a/lib/twitter/media_factory.rb b/lib/twitter/media_factory.rb index 31cf8ddbe..eaf773659 100644 --- a/lib/twitter/media_factory.rb +++ b/lib/twitter/media_factory.rb @@ -1,5 +1,6 @@ require 'twitter/factory' require 'twitter/media/photo' +require 'twitter/media/video' module Twitter class MediaFactory < Twitter::Factory diff --git a/lib/twitter/variant.rb b/lib/twitter/variant.rb new file mode 100644 index 000000000..2bf365aa5 --- /dev/null +++ b/lib/twitter/variant.rb @@ -0,0 +1,12 @@ +require 'twitter/base' + +module Twitter + class Variant < Twitter::Base + # @return [Integer] + attr_reader :bitrate + + # @return [String] + attr_reader :content_type + uri_attr_reader :uri + end +end diff --git a/spec/helper.rb b/spec/helper.rb index 8f64a6188..0564aa6cc 100644 --- a/spec/helper.rb +++ b/spec/helper.rb @@ -15,6 +15,8 @@ require 'timecop' require 'webmock/rspec' +require_relative 'support/media_object_examples' + WebMock.disable_net_connect!(allow: 'coveralls.io') RSpec.configure do |config| diff --git a/spec/support/media_object_examples.rb b/spec/support/media_object_examples.rb new file mode 100644 index 000000000..517735c7d --- /dev/null +++ b/spec/support/media_object_examples.rb @@ -0,0 +1,146 @@ +shared_examples_for 'a Twitter::Media object' do + describe '#==' do + it 'returns true when objects IDs are the same' do + media = described_class.new(id: 1) + other = described_class.new(id: 1) + expect(media == other).to be true + end + it 'returns false when objects IDs are different' do + media = described_class.new(id: 1) + other = described_class.new(id: 2) + expect(media == other).to be false + end + it 'returns false when classes are different' do + media = described_class.new(id: 1) + other = Twitter::Identity.new(id: 1) + expect(media == other).to be false + end + end + + describe '#sizes' do + it 'returns a hash of Sizes when sizes is set' do + sizes = described_class.new(id: 110_102_452_988_157_952, sizes: {small: {h: 226, w: 340, resize: 'fit'}, large: {h: 466, w: 700, resize: 'fit'}, medium: {h: 399, w: 600, resize: 'fit'}, thumb: {h: 150, w: 150, resize: 'crop'}}).sizes + expect(sizes).to be_a Hash + expect(sizes[:small]).to be_a Twitter::Size + end + it 'is empty when sizes is not set' do + sizes = described_class.new(id: 110_102_452_988_157_952).sizes + expect(sizes).to be_empty + end + end + + describe '#display_uri' do + it 'returns a String when the display_url is set' do + photo = Twitter::Media::Photo.new(id: 1, display_url: 'example.com/expanded...') + expect(photo.display_uri).to be_a String + expect(photo.display_uri).to eq('example.com/expanded...') + end + it 'returns nil when the display_url is not set' do + photo = Twitter::Media::Photo.new(id: 1) + expect(photo.display_uri).to be_nil + end + end + + describe '#display_uri?' do + it 'returns true when the display_url is set' do + photo = Twitter::Media::Photo.new(id: 1, display_url: 'example.com/expanded...') + expect(photo.display_uri?).to be true + end + it 'returns false when the display_url is not set' do + photo = Twitter::Media::Photo.new(id: 1) + expect(photo.display_uri?).to be false + end + end + + describe '#expanded_uri' do + it 'returns a URI when the expanded_url is set' do + media = described_class.new(id: 1, expanded_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.expanded_uri).to be_an Addressable::URI + expect(media.expanded_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + end + it 'returns nil when the expanded_url is not set' do + media = described_class.new(id: 1) + expect(media.expanded_uri).to be_nil + end + end + + describe '#expanded_uri?' do + it 'returns true when the expanded_url is set' do + media = described_class.new(id: 1, expanded_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.expanded_uri?).to be true + end + it 'returns false when the expanded_url is not set' do + media = described_class.new(id: 1) + expect(media.expanded_uri?).to be false + end + end + + describe '#media_uri' do + it 'returns a URI when the media_url is set' do + media = described_class.new(id: 1, media_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.media_uri).to be_an Addressable::URI + expect(media.media_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + end + it 'returns nil when the media_url is not set' do + media = described_class.new(id: 1) + expect(media.media_uri).to be_nil + end + end + + describe '#media_uri?' do + it 'returns true when the media_url is set' do + media = described_class.new(id: 1, media_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.media_uri?).to be true + end + it 'returns false when the media_url is not set' do + media = described_class.new(id: 1) + expect(media.media_uri?).to be false + end + end + + describe '#media_uri_https' do + it 'returns a URI when the media_url_https is set' do + media = described_class.new(id: 1, media_url_https: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.media_uri_https).to be_an Addressable::URI + expect(media.media_uri_https.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + end + it 'returns nil when the media_url_https is not set' do + media = described_class.new(id: 1) + expect(media.media_uri_https).to be_nil + end + end + + describe '#media_uri_https?' do + it 'returns true when the media_url_https is set' do + media = described_class.new(id: 1, media_url_https: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.media_uri_https?).to be true + end + it 'returns false when the media_url_https is not set' do + media = described_class.new(id: 1) + expect(media.media_uri_https?).to be false + end + end + + describe '#uri' do + it 'returns a URI when the url is set' do + media = described_class.new(id: 1, url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.uri).to be_an Addressable::URI + expect(media.uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + end + it 'returns nil when the url is not set' do + media = described_class.new(id: 1) + expect(media.uri).to be_nil + end + end + + describe '#uri?' do + it 'returns true when the url is set' do + media = described_class.new(id: 1, url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') + expect(media.uri?).to be true + end + it 'returns false when the url is not set' do + media = described_class.new(id: 1) + expect(media.uri?).to be false + end + end +end diff --git a/spec/twitter/media/photo_spec.rb b/spec/twitter/media/photo_spec.rb index 1944ab942..4bcd611da 100644 --- a/spec/twitter/media/photo_spec.rb +++ b/spec/twitter/media/photo_spec.rb @@ -2,148 +2,5 @@ require 'helper' describe Twitter::Media::Photo do - describe '#==' do - it 'returns true when objects IDs are the same' do - photo = Twitter::Media::Photo.new(id: 1) - other = Twitter::Media::Photo.new(id: 1) - expect(photo == other).to be true - end - it 'returns false when objects IDs are different' do - photo = Twitter::Media::Photo.new(id: 1) - other = Twitter::Media::Photo.new(id: 2) - expect(photo == other).to be false - end - it 'returns false when classes are different' do - photo = Twitter::Media::Photo.new(id: 1) - other = Twitter::Identity.new(id: 1) - expect(photo == other).to be false - end - end - - describe '#sizes' do - it 'returns a hash of Sizes when sizes is set' do - sizes = Twitter::Media::Photo.new(id: 110_102_452_988_157_952, sizes: {small: {h: 226, w: 340, resize: 'fit'}, large: {h: 466, w: 700, resize: 'fit'}, medium: {h: 399, w: 600, resize: 'fit'}, thumb: {h: 150, w: 150, resize: 'crop'}}).sizes - expect(sizes).to be_a Hash - expect(sizes[:small]).to be_a Twitter::Size - end - it 'is empty when sizes is not set' do - sizes = Twitter::Media::Photo.new(id: 110_102_452_988_157_952).sizes - expect(sizes).to be_empty - end - end - - describe '#display_uri' do - it 'returns a String when the display_url is set' do - photo = Twitter::Media::Photo.new(id: 1, display_url: 'example.com/expanded...') - expect(photo.display_uri).to be_a String - expect(photo.display_uri).to eq('example.com/expanded...') - end - it 'returns nil when the display_url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.display_uri).to be_nil - end - end - - describe '#display_uri?' do - it 'returns true when the display_url is set' do - photo = Twitter::Media::Photo.new(id: 1, display_url: 'example.com/expanded...') - expect(photo.display_uri?).to be true - end - it 'returns false when the display_url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.display_uri?).to be false - end - end - - describe '#expanded_uri' do - it 'returns a URI when the expanded_url is set' do - photo = Twitter::Media::Photo.new(id: 1, expanded_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.expanded_uri).to be_an Addressable::URI - expect(photo.expanded_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - end - it 'returns nil when the expanded_url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.expanded_uri).to be_nil - end - end - - describe '#expanded_uri?' do - it 'returns true when the expanded_url is set' do - photo = Twitter::Media::Photo.new(id: 1, expanded_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.expanded_uri?).to be true - end - it 'returns false when the expanded_url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.expanded_uri?).to be false - end - end - - describe '#media_uri' do - it 'returns a URI when the media_url is set' do - photo = Twitter::Media::Photo.new(id: 1, media_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.media_uri).to be_an Addressable::URI - expect(photo.media_uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - end - it 'returns nil when the media_url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.media_uri).to be_nil - end - end - - describe '#media_uri?' do - it 'returns true when the media_url is set' do - photo = Twitter::Media::Photo.new(id: 1, media_url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.media_uri?).to be true - end - it 'returns false when the media_url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.media_uri?).to be false - end - end - - describe '#media_uri_https' do - it 'returns a URI when the media_url_https is set' do - photo = Twitter::Media::Photo.new(id: 1, media_url_https: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.media_uri_https).to be_an Addressable::URI - expect(photo.media_uri_https.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - end - it 'returns nil when the media_url_https is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.media_uri_https).to be_nil - end - end - - describe '#media_uri_https?' do - it 'returns true when the media_url_https is set' do - photo = Twitter::Media::Photo.new(id: 1, media_url_https: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.media_uri_https?).to be true - end - it 'returns false when the media_url_https is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.media_uri_https?).to be false - end - end - - describe '#uri' do - it 'returns a URI when the url is set' do - photo = Twitter::Media::Photo.new(id: 1, url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.uri).to be_an Addressable::URI - expect(photo.uri.to_s).to eq('http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - end - it 'returns nil when the url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.uri).to be_nil - end - end - - describe '#uri?' do - it 'returns true when the url is set' do - photo = Twitter::Media::Photo.new(id: 1, url: 'http://pbs.twimg.com/media/BQD6MPOCEAAbCH0.png') - expect(photo.uri?).to be true - end - it 'returns false when the url is not set' do - photo = Twitter::Media::Photo.new(id: 1) - expect(photo.uri?).to be false - end - end + it_behaves_like 'a Twitter::Media object' end diff --git a/spec/twitter/media/video_info_spec.rb b/spec/twitter/media/video_info_spec.rb new file mode 100644 index 000000000..1b0e2656e --- /dev/null +++ b/spec/twitter/media/video_info_spec.rb @@ -0,0 +1,39 @@ +require 'helper' + +describe Twitter::Media::VideoInfo do + describe '#aspect_ratio' do + it 'returns a String when the aspect_ratio is set' do + info = Twitter::Media::VideoInfo.new(aspect_ratio: [16, 9]) + expect(info.aspect_ratio).to be_an Array + expect(info.aspect_ratio).to eq([16, 9]) + end + it 'returns nil when the aspect_ratio is not set' do + info = Twitter::Media::VideoInfo.new({}) + expect(info.aspect_ratio).to be_nil + end + end + + describe '#duration_millis' do + it 'returns a Integer when the duration_millis is set' do + info = Twitter::Media::VideoInfo.new(duration_millis: 30_033) + expect(info.duration_millis).to be_a Integer + expect(info.duration_millis).to eq(30_033) + end + it 'returns nil when the duration_millis is not set' do + info = Twitter::Media::VideoInfo.new({}) + expect(info.duration_millis).to be_nil + end + end + + describe '#variants' do + it 'returns a hash of Variants when variants is set' do + variants = Twitter::Media::VideoInfo.new(variants: [{bitrate: 2_176_000, content_type: 'video/mp4', url: 'http://video.twimg.com/c4E56sl91ZB7cpYi.mp4'}]).variants + expect(variants).to be_an Array + expect(variants.first).to be_a Twitter::Variant + end + it 'is empty when variants is not set' do + variants = Twitter::Media::VideoInfo.new({}).variants + expect(variants).to be_empty + end + end +end diff --git a/spec/twitter/media/video_spec.rb b/spec/twitter/media/video_spec.rb new file mode 100644 index 000000000..d1837b3bf --- /dev/null +++ b/spec/twitter/media/video_spec.rb @@ -0,0 +1,16 @@ +require 'helper' + +describe Twitter::Media::Video do + it_behaves_like 'a Twitter::Media object' + + describe '#video_info' do + it 'returns a Twitter::Media::VideoInfo when the video is set' do + video = Twitter::Media::Video.new(id: 1, video_info: {}) + expect(video.video_info).to be_a Twitter::Media::VideoInfo + end + it 'returns nil when the display_url is not set' do + video = Twitter::Media::Video.new(id: 1, video_info: nil) + expect(video.video_info).to be_nil + end + end +end diff --git a/spec/twitter/media_factory_spec.rb b/spec/twitter/media_factory_spec.rb index 1c8c1a1f6..57122cb9e 100644 --- a/spec/twitter/media_factory_spec.rb +++ b/spec/twitter/media_factory_spec.rb @@ -6,6 +6,10 @@ media = Twitter::MediaFactory.new(id: 1, type: 'photo') expect(media).to be_a Twitter::Media::Photo end + it 'generates a Photo' do + media = Twitter::MediaFactory.new(id: 1, type: 'video') + expect(media).to be_a Twitter::Media::Video + end it 'raises an IndexError when type is not specified' do expect { Twitter::MediaFactory.new }.to raise_error(IndexError) end diff --git a/spec/twitter/variant_spec.rb b/spec/twitter/variant_spec.rb new file mode 100644 index 000000000..adadb45f1 --- /dev/null +++ b/spec/twitter/variant_spec.rb @@ -0,0 +1,26 @@ +require 'helper' + +describe Twitter::Variant do + describe '#uri' do + it 'returns a URI when the url is set' do + variant = Twitter::Variant.new(id: 1, url: 'https://video.twimg.com/media/BQD6MPOCEAAbCH0.mp4') + expect(variant.uri).to be_an Addressable::URI + expect(variant.uri.to_s).to eq('https://video.twimg.com/media/BQD6MPOCEAAbCH0.mp4') + end + it 'returns nil when the url is not set' do + variant = Twitter::Variant.new({}) + expect(variant.uri).to be_nil + end + end + + describe '#uri?' do + it 'returns true when the url is set' do + variant = Twitter::Variant.new(id: 1, url: 'https://video.twimg.com/media/BQD6MPOCEAAbCH0.mp4') + expect(variant.uri?).to be true + end + it 'returns false when the url is not set' do + variant = Twitter::Variant.new({}) + expect(variant.uri?).to be false + end + end +end