From 4ab48cc6292c5d55acc2d2207f6b2d942bcc0586 Mon Sep 17 00:00:00 2001 From: Daniel Vandersluis Date: Fri, 9 Apr 2021 16:39:21 -0400 Subject: [PATCH] Add support for new Collections endpoints. --- CHANGES.md | 11 ++++ lib/pexels.rb | 4 ++ lib/pexels/client/collections.rb | 29 +++++++++++ lib/pexels/collection.rb | 25 +++++++++ lib/pexels/collection_media_set.rb | 31 ++++++++++++ lib/pexels/collection_set.rb | 11 ++++ lib/pexels/version.rb | 2 +- test/collection_test.rb | 81 ++++++++++++++++++++++++++++++ 8 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 CHANGES.md create mode 100644 lib/pexels/client/collections.rb create mode 100644 lib/pexels/collection.rb create mode 100644 lib/pexels/collection_media_set.rb create mode 100644 lib/pexels/collection_set.rb create mode 100644 test/collection_test.rb diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..222089c --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,11 @@ +# Change log + +## 0.1.0 +* Add support for returning collections belonging to the API user. +* Add support for returning media from a collection. + +## 0.0.4 +* Add `find` as an alias for `photos[]` and `videos[]`. + +## 0.0.3 +* Initial release. diff --git a/lib/pexels.rb b/lib/pexels.rb index 7f3e68d..5c1f97c 100644 --- a/lib/pexels.rb +++ b/lib/pexels.rb @@ -23,15 +23,19 @@ def local_headers end require_relative 'pexels/client' +require_relative 'pexels/client/collections' require_relative 'pexels/client/photos' require_relative 'pexels/client/videos' require_relative 'pexels/version' require_relative 'pexels/errors' +require_relative 'pexels/collection' require_relative 'pexels/photo' require_relative 'pexels/video' require_relative 'pexels/video/file' require_relative 'pexels/video/picture' require_relative 'pexels/user' require_relative 'pexels/paginated_response' +require_relative 'pexels/collection_set' +require_relative 'pexels/collection_media_set' require_relative 'pexels/photo_set' require_relative 'pexels/video_set' diff --git a/lib/pexels/client/collections.rb b/lib/pexels/client/collections.rb new file mode 100644 index 0000000..fd425d4 --- /dev/null +++ b/lib/pexels/client/collections.rb @@ -0,0 +1,29 @@ +class Pexels::Client::Collections + def initialize(client) + @client = client + end + + def all(per_page: 15, page: 1) + response = @client.request( + '/collections', + params: { + per_page: per_page, + page: page + }) + + Pexels::CollectionSet.new(response) + end + + def [](id, type: nil, per_page: 15, page: 1) + response = @client.request( + "/collections/#{id}", + params: { + per_page: per_page, + page: page, + type: type + }) + + Pexels::CollectionMediaSet.new(response) + end + alias_method :find, :[] +end diff --git a/lib/pexels/collection.rb b/lib/pexels/collection.rb new file mode 100644 index 0000000..7bfeb42 --- /dev/null +++ b/lib/pexels/collection.rb @@ -0,0 +1,25 @@ +module Pexels + class Collection + attr_reader :id, + :title, + :description, + :private, + :media_count, + :photos_count, + :videos_count + + + def initialize(attrs) + @id = attrs.fetch('id') + @title = attrs.fetch('title') + @description = attrs.fetch('description') + @private = attrs.fetch('private') + @media_count = attrs.fetch('media_count') + @photos_count = attrs.fetch('photos_count') + @videos_count = attrs.fetch('videos_count') + + rescue KeyError => exception + raise Pexels::MalformedAPIResponseError.new(exception) + end + end +end diff --git a/lib/pexels/collection_media_set.rb b/lib/pexels/collection_media_set.rb new file mode 100644 index 0000000..b9c12c6 --- /dev/null +++ b/lib/pexels/collection_media_set.rb @@ -0,0 +1,31 @@ +module Pexels + class CollectionMediaSet < PaginatedResponse + alias_method :media, :data + public :media + + attr_reader :id + + def initialize(attrs) + super + @id = attrs.fetch('id') + @data = attrs.fetch('media', []).map do |attrs| + if attrs['type'] == 'Photo' + Pexels::Photo.new(attrs) + elsif attrs['type'] == 'Video' + Pexels::Video.new(attrs) + end + end + + rescue KeyError => exception + raise Pexels::MalformedAPIResponseError.new(exception) + end + + def photos + @photos ||= media.select { |m| m.is_a?(Pexels::Photo) } + end + + def videos + @videos ||= media.select { |m| m.is_a?(Pexels::Video) } + end + end +end diff --git a/lib/pexels/collection_set.rb b/lib/pexels/collection_set.rb new file mode 100644 index 0000000..831085a --- /dev/null +++ b/lib/pexels/collection_set.rb @@ -0,0 +1,11 @@ +module Pexels + class CollectionSet < PaginatedResponse + alias_method :collections, :data + public :collections + + def initialize(attrs) + super + @data = attrs.fetch('collections', []).map { |attrs| Pexels::Collection.new(attrs) } + end + end +end diff --git a/lib/pexels/version.rb b/lib/pexels/version.rb index 9429330..3b1f8ec 100644 --- a/lib/pexels/version.rb +++ b/lib/pexels/version.rb @@ -1,3 +1,3 @@ module Pexels - VERSION = '0.0.4' + VERSION = '0.1.0' end diff --git a/test/collection_test.rb b/test/collection_test.rb new file mode 100644 index 0000000..a2c25b7 --- /dev/null +++ b/test/collection_test.rb @@ -0,0 +1,81 @@ +require 'minitest/autorun' +require 'pexels' + +class TestCollections < Minitest::Test + + def setup + @client = Pexels::Client.new(ENV.fetch('PEXELS_API_KEY')) + @collection = @client.collections.all(per_page: 1).first + end + + def test_all + search_result = @client.collections.all + + assert search_result.is_a? Pexels::CollectionSet + assert_equal search_result.per_page, 15 + assert_equal search_result.page, 1 + + assert search_result.collections.is_a? Array + assert search_result.collections.any? + assert search_result.first.is_a? Pexels::Collection + + search_result_with_params = @client.collections.all(per_page: 1, page: 2) + assert_equal search_result_with_params.per_page, 1 + assert_equal search_result_with_params.page, 2 + assert_equal search_result_with_params.collections.length, 1 + end + + def test_get_collection_media + collection = @client.collections[@collection.id] + assert collection.is_a? Pexels::CollectionMediaSet + assert_equal collection.id, @collection.id + + assert collection.media.is_a? Array + assert collection.media.any? + + assert_includes([Pexels::Photo, Pexels::Video], collection.media.first.class) + + refute_includes([Pexels::Video], collection.photos.map(&:class)) + refute_includes([Pexels::Photo], collection.videos.map(&:class)) + end + + def test_get_collection_photos + collection = @client.collections[@collection.id, type: 'photos'] + assert collection.is_a? Pexels::CollectionMediaSet + assert collection.media.is_a? Array + assert collection.media.all? { |m| m.is_a?(Pexels::Photo) } + end + + def test_get_collection_videos + collection = @client.collections[@collection.id, type: 'videos'] + assert collection.is_a? Pexels::CollectionMediaSet + assert collection.media.is_a? Array + assert collection.media.all? { |m| m.is_a?(Pexels::Video) } + end + + def test_get_collection_invalid_type + collection = @client.collections[@collection.id, type: 'foo'] + assert collection.is_a? Pexels::CollectionMediaSet + assert collection.media.is_a? Array + assert collection.any? + end + + def test_get_collection_pagination + collection = @client.collections[@collection.id, per_page: 1, page: 1] + assert collection.is_a? Pexels::CollectionMediaSet + assert collection.media.is_a? Array + assert collection.media.any? + + assert_equal collection.per_page, 1 + assert_equal collection.page, 1 + assert_equal collection.media.length, 1 + end + + def test_invalid_get_collection + @client.collections['this-is-not-a-valid-id'] + raise 'This should not happen' + rescue StandardError => exception + assert exception.is_a? Pexels::APIError + assert_equal exception.message, 'Not Found' + end +end