worth_watching 0.1.5 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +23 -36
- data/lib/worth_watching.rb +18 -1
- data/lib/worth_watching/aggregator.rb +10 -186
- data/lib/worth_watching/errors.rb +2 -0
- data/lib/worth_watching/imdb/rating_fetcher.rb +38 -0
- data/lib/worth_watching/metacritic/rating_fetcher.rb +28 -0
- data/lib/worth_watching/movie.rb +17 -32
- data/lib/worth_watching/reviews_fetcher.rb +16 -0
- data/lib/worth_watching/rotten_tomatoes/movie_info_fetcher.rb +23 -0
- data/lib/worth_watching/rotten_tomatoes/movie_list_fetcher.rb +51 -0
- data/lib/worth_watching/rotten_tomatoes/movie_parser.rb +47 -0
- data/lib/worth_watching/rotten_tomatoes/review_parser.rb +22 -0
- data/lib/worth_watching/rotten_tomatoes/reviews_fetcher.rb +19 -0
- data/lib/worth_watching/rotten_tomatoes/rotten_tomatoes.rb +5 -0
- data/lib/worth_watching/rotten_tomatoes/searcher.rb +37 -0
- data/lib/worth_watching/tmdb/poster_fetcher.rb +26 -0
- data/lib/worth_watching/version.rb +1 -1
- data/lib/worth_watching/written_review.rb +15 -15
- data/spec/{unit/aggregator_spec.rb → integration/aggregating_a_movie_spec.rb} +18 -45
- data/spec/{test_helper.rb → spec_helper.rb} +0 -0
- data/spec/support/json_responses/a_movie_with_little_info_rt.json +1 -0
- data/spec/unit/imdb/rating_fetcher_spec.rb +31 -0
- data/spec/unit/movie_spec.rb +16 -37
- data/spec/unit/rotten_tomatoes/movie_info_fetcher_spec.rb +63 -0
- data/spec/unit/rotten_tomatoes/movie_list_fetcher_spec.rb +38 -0
- data/spec/unit/rotten_tomatoes/movie_parser_spec.rb +80 -0
- data/spec/unit/rotten_tomatoes/review_parser_spec.rb +47 -0
- data/spec/unit/rotten_tomatoes/reviews_fetcher_spec.rb +18 -0
- data/spec/unit/rotten_tomatoes/searcher_spec.rb +49 -0
- data/spec/unit/tmdb/poster_fetcher_spec.rb +15 -0
- data/spec/unit/written_review_spec.rb +16 -35
- data/worth_watching.gemspec +1 -0
- metadata +51 -7
@@ -0,0 +1,16 @@
|
|
1
|
+
module WorthWatching
|
2
|
+
|
3
|
+
# General class to fetch movie reviews for a given movie
|
4
|
+
# Currently only supports RottenTomatoes as the source
|
5
|
+
class ReviewsFetcher
|
6
|
+
attr_accessor :rt_api_key
|
7
|
+
|
8
|
+
def initialize(rt_api_key)
|
9
|
+
@rt_api_key = rt_api_key
|
10
|
+
end
|
11
|
+
|
12
|
+
def fetch(rt_id)
|
13
|
+
RottenTomatoes::ReviewsFetcher.fetch(rt_id, rt_api_key)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module WorthWatching
|
5
|
+
module RottenTomatoes
|
6
|
+
class MovieInfoFetcher
|
7
|
+
attr_accessor :rt_api_key
|
8
|
+
|
9
|
+
def initialize(rt_api_key)
|
10
|
+
@rt_api_key = rt_api_key
|
11
|
+
end
|
12
|
+
|
13
|
+
# Fetches movie info of a single movie using the Rotten Tomatoes API,
|
14
|
+
# and returns a Movie object
|
15
|
+
def fetch_info(rt_id)
|
16
|
+
uri = "#{RottenTomatoes::RT_API_BASE_URL}/movies/#{rt_id}.json?apikey=#{rt_api_key}"
|
17
|
+
movie_hash = JSON.parse(Typhoeus.get(uri).body)
|
18
|
+
|
19
|
+
RottenTomatoes::MovieParser.parse(movie_hash)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module WorthWatching
|
5
|
+
module RottenTomatoes
|
6
|
+
class MovieListFetcher
|
7
|
+
attr_accessor :rt_api_key
|
8
|
+
|
9
|
+
def initialize(rt_api_key)
|
10
|
+
@rt_api_key = rt_api_key
|
11
|
+
end
|
12
|
+
|
13
|
+
# Retrieve a list of basic movie information
|
14
|
+
#
|
15
|
+
# @param list_name [Symbol] type of list to retrieve, options:
|
16
|
+
# :box_office, :in_theaters, :opening, :upcoming, :top_rentals,
|
17
|
+
# :current_releases, :new_releases, :upcoming_dvd
|
18
|
+
# @param country [Symbol] Country code for region-specific results (ISO 3166-1 alpha-2)
|
19
|
+
# @param result_limit [Symbol] no. of results to return, up to 16
|
20
|
+
# @return [Array] an array of results, each representing a movie in the list
|
21
|
+
def fetch_list(list_name, country, result_limit)
|
22
|
+
case list_name
|
23
|
+
# Build the appropriate URI based on the list name.
|
24
|
+
# Some endpoints use 'limit' to specify max results to return, some use 'page_limit'.
|
25
|
+
# Pass both to make the code simpler
|
26
|
+
when :box_office, :in_theaters, :opening, :upcoming
|
27
|
+
uri = "#{RottenTomatoes::RT_API_BASE_URL}/lists/movies/#{list_name.to_s}.json?limit=#{result_limit}"\
|
28
|
+
"&page_limit=#{result_limit}&page=1&country=#{country.to_s}&apikey=#{@rt_api_key}"
|
29
|
+
when :top_rentals, :current_releases, :new_releases, :upcoming_dvd
|
30
|
+
|
31
|
+
# The API endpoint uses 'upcoming' for both DVD and cinema releases
|
32
|
+
# Need to avoid this clash by using ':upcoming_dvd' as possible method param,
|
33
|
+
# but change back when building the URI
|
34
|
+
list_name = :upcoming if list_name == :upcoming_dvd
|
35
|
+
uri = "#{RottenTomatoes::RT_API_BASE_URL}/lists/dvds/#{list_name.to_s}.json?limit=#{result_limit}"\
|
36
|
+
"&page_limit=#{result_limit}&page=1&country=#{country.to_s}&apikey=#{@rt_api_key}"
|
37
|
+
end
|
38
|
+
|
39
|
+
response = JSON.parse(Typhoeus.get(uri).body)
|
40
|
+
|
41
|
+
response["movies"].map do |movie_hash|
|
42
|
+
{ title: movie_hash["title"],
|
43
|
+
rt_id: movie_hash["id"],
|
44
|
+
year: movie_hash["year"].to_s,
|
45
|
+
rt_rating: movie_hash["ratings"]["critics_score"]
|
46
|
+
}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module WorthWatching
|
2
|
+
module RottenTomatoes
|
3
|
+
class MovieParser
|
4
|
+
|
5
|
+
# Parses a single movie JSON response from the Rotten Tomatoes API, returning
|
6
|
+
# a Movie object containing the movie's details
|
7
|
+
def self.parse(json_response)
|
8
|
+
movie_args = {}
|
9
|
+
|
10
|
+
movie_args[:title] = json_response['title']
|
11
|
+
movie_args[:plot] = json_response['synopsis']
|
12
|
+
movie_args[:director] = json_response['abridged_directors'][0]['name'] if json_response.has_key?('abridged_directors')
|
13
|
+
movie_args[:genre] = json_response['genres'][0] if json_response.has_key?('genres')
|
14
|
+
|
15
|
+
movie_args[:rt_rating] = json_response['ratings']['critics_score']
|
16
|
+
movie_args[:rt_url] = json_response['links']['alternate']
|
17
|
+
|
18
|
+
movie_args[:cast] = build_cast_list(json_response['abridged_cast'])
|
19
|
+
|
20
|
+
imdb_id = json_response['alternate_ids']['imdb'] if json_response.has_key?('alternate_ids')
|
21
|
+
movie_args[:imdb_id] = imdb_id
|
22
|
+
|
23
|
+
movie_args[:imdb_url] = "http://www.imdb.com/title/tt#{imdb_id}/"
|
24
|
+
movie_args[:release_date] = Date.parse(json_response['release_dates']['theater'])
|
25
|
+
movie_args[:rt_id] = json_response['id'].to_s
|
26
|
+
|
27
|
+
Movie.new(movie_args)
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
# Builds a cast list string from an array of actor names (up to 4 actors)
|
33
|
+
#
|
34
|
+
# @param cast [Array] the array of actor names
|
35
|
+
# @return [String] a string of actor names separated by commas
|
36
|
+
def self.build_cast_list(cast)
|
37
|
+
cast_list = cast[0..3].inject("") do |cast_list_string, actor, i|
|
38
|
+
cast_list_string << "#{actor["name"]}, "
|
39
|
+
end
|
40
|
+
|
41
|
+
# Remove the trailing comma
|
42
|
+
cast_list.sub(/, \z/, "")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module WorthWatching
|
2
|
+
module RottenTomatoes
|
3
|
+
class ReviewParser
|
4
|
+
|
5
|
+
# Parses a JSON response of movie reviews from the Rotten Tomatoes API, returning
|
6
|
+
# an array WrittenReview objects
|
7
|
+
def self.parse(json_response)
|
8
|
+
json_response["reviews"].map do |review_hash|
|
9
|
+
author = review_hash["critic"]
|
10
|
+
date = Date.parse(review_hash["date"])
|
11
|
+
rating = review_hash["freshness"]
|
12
|
+
source = review_hash["publication"]
|
13
|
+
quote = review_hash["quote"]
|
14
|
+
link = review_hash["links"]["review"]
|
15
|
+
original_score = review_hash["original_score"] || "N/A"
|
16
|
+
|
17
|
+
WrittenReview.new(author, date, rating, source, quote, link, original_score)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module WorthWatching
|
5
|
+
module RottenTomatoes
|
6
|
+
class ReviewsFetcher
|
7
|
+
|
8
|
+
# Fetches reviews using the Rotten Tomatoes API,
|
9
|
+
# and returns an array of WrittenReview objects
|
10
|
+
def self.fetch(rt_id, rt_api_key)
|
11
|
+
uri = "#{RottenTomatoes::RT_API_BASE_URL}/movies/#{rt_id}/reviews.json?review_type=top_critic"\
|
12
|
+
"&page_limit=5&page=1&country=uk&apikey=#{rt_api_key}"
|
13
|
+
reviews_response = JSON.parse(Typhoeus.get(uri).body)
|
14
|
+
|
15
|
+
ReviewParser.parse(reviews_response)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
require 'cgi'
|
4
|
+
|
5
|
+
module WorthWatching
|
6
|
+
module RottenTomatoes
|
7
|
+
class Searcher
|
8
|
+
|
9
|
+
def initialize(rt_api_key)
|
10
|
+
@rt_api_key = rt_api_key
|
11
|
+
end
|
12
|
+
|
13
|
+
# Search for movies using a query string. Returns a max of 4 results
|
14
|
+
#
|
15
|
+
# @param movie_title [String] the title of the movie to search for
|
16
|
+
# @param result_limit [Integer] the max number of results to return
|
17
|
+
# @return [Array, false] an array containing hashes represting each movie in the search results, or
|
18
|
+
# false if no results are found.
|
19
|
+
def search_by_title(movie_title, result_limit)
|
20
|
+
uri = "#{RottenTomatoes::RT_API_BASE_URL}/movies.json?apikey=#{@rt_api_key}&q=#{CGI::escape(movie_title)}&page_limit=#{result_limit}"
|
21
|
+
|
22
|
+
response = JSON.parse(Typhoeus.get(uri).body)
|
23
|
+
|
24
|
+
if response["total"] == 0
|
25
|
+
return false
|
26
|
+
else
|
27
|
+
# Build the array of movie serach results. Have to use a regexp to extract the Rotten Tomatoes
|
28
|
+
# ID from the movie link since the API does not return it directly.
|
29
|
+
return response["movies"].inject([]) do |movie_list, movie|
|
30
|
+
movie_list << { :title => movie["title"], :rt_id => movie["links"]["self"].match(/\/[0-9]+\./).to_s.gsub(/[\/\.]/, ""), :year => movie["year"].to_s }
|
31
|
+
movie_list
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'typhoeus'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module WorthWatching
|
5
|
+
module TMDB
|
6
|
+
TMDB_API_BASE_URL = 'http://api.themoviedb.org/3'
|
7
|
+
class PosterFetcher
|
8
|
+
attr_accessor :tmdb_api_key
|
9
|
+
|
10
|
+
def initialize(tmdb_api_key)
|
11
|
+
@tmdb_api_key = tmdb_api_key
|
12
|
+
end
|
13
|
+
|
14
|
+
def fetch(imdb_id)
|
15
|
+
uri = "#{TMDB::TMDB_API_BASE_URL}/movie/tt#{imdb_id}?api_key=#{tmdb_api_key}"
|
16
|
+
movie_info = JSON.parse(Typhoeus.get(uri).body)
|
17
|
+
|
18
|
+
if movie_info.has_key?("poster_path")
|
19
|
+
"http://cf2.imgobject.com/t/p/original" + movie_info["poster_path"]
|
20
|
+
else
|
21
|
+
"No poster available"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -4,14 +4,14 @@ module WorthWatching
|
|
4
4
|
class WrittenReview
|
5
5
|
attr_accessor :author, :date, :rating, :source, :quote, :link, :original_score
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@author =
|
9
|
-
@date =
|
10
|
-
@rating =
|
11
|
-
@source =
|
12
|
-
@quote =
|
13
|
-
@link =
|
14
|
-
@original_score =
|
7
|
+
def initialize(author, date, rating, source, quote, link, original_score)
|
8
|
+
@author = author
|
9
|
+
@date = date
|
10
|
+
@rating = rating
|
11
|
+
@source = source
|
12
|
+
@quote = quote
|
13
|
+
@link = link
|
14
|
+
@original_score = original_score
|
15
15
|
end
|
16
16
|
|
17
17
|
def to_s
|
@@ -19,13 +19,13 @@ module WorthWatching
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def to_hash
|
22
|
-
{ author:
|
23
|
-
date:
|
24
|
-
rating:
|
25
|
-
source:
|
26
|
-
quote:
|
27
|
-
link:
|
28
|
-
original_score:
|
22
|
+
{ author: author,
|
23
|
+
date: date,
|
24
|
+
rating: rating,
|
25
|
+
source: source,
|
26
|
+
quote: quote,
|
27
|
+
link: link,
|
28
|
+
original_score: original_score
|
29
29
|
}
|
30
30
|
end
|
31
31
|
end
|
@@ -1,23 +1,27 @@
|
|
1
|
-
require '
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
|
-
describe
|
4
|
-
|
5
|
-
let(:aggregator) {WorthWatching::Aggregator.new("rt_api_key", "tmdb_api_key")}
|
3
|
+
describe "Aggregating a movie" do
|
4
|
+
let(:aggregator) { WorthWatching::Aggregator.new("rt_api_key", "tmdb_api_key") }
|
6
5
|
|
7
6
|
describe 'retrieving individual movie info' do
|
8
7
|
before do
|
8
|
+
# Single movie RottenTomatoes
|
9
9
|
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/toy_story_rt.json")
|
10
10
|
stub_request(:get, /api\.rottentomatoes\.com\/api\/public\/v1\.0\/movies\/770672122\.json\?apikey\=.*/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
11
11
|
|
12
|
+
# Single movie OMDB
|
12
13
|
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/toy_story_omdb.json")
|
13
14
|
stub_request(:get, "http://www.omdbapi.com/?i=tt0435761").to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
14
15
|
|
16
|
+
# Single movie TMDB
|
15
17
|
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/toy_story_tmdb.json")
|
16
18
|
stub_request(:get, /api\.themoviedb\.org\/3\/movie\/tt0435761\?api_key\=.*/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
17
19
|
|
20
|
+
# RottenTomatoes reviews
|
18
21
|
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/toy_story_reviews_rt.json")
|
19
22
|
stub_request(:get, /api\.rottentomatoes\.com\/api\/public\/v1\.0\/movies\/770672122\/reviews\.json\?apikey\=.*&country=uk&page=1&page_limit=5&review_type=top_critic/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
20
23
|
|
24
|
+
# Single movie MetaCritic
|
21
25
|
json_response = File.read(File.dirname(__FILE__) + "/../support/html_responses/toy_story_mc.html")
|
22
26
|
stub_request(:get, "http://www.metacritic.com/search/movie/Toy+Story+3/results").to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["text/html; charset=utf-8"]})
|
23
27
|
end
|
@@ -35,7 +39,7 @@ describe 'WorthWatching::Aggregator' do
|
|
35
39
|
end
|
36
40
|
|
37
41
|
it "should have IMDB rating of 8.5" do
|
38
|
-
expect(movie.imdb_rating).to eq(
|
42
|
+
expect(movie.imdb_rating).to eq(8.5)
|
39
43
|
end
|
40
44
|
|
41
45
|
it "should have IMDB url 'http://www.imdb.com/title/tt0435761/'" do
|
@@ -43,7 +47,7 @@ describe 'WorthWatching::Aggregator' do
|
|
43
47
|
end
|
44
48
|
|
45
49
|
it "should have metacritic rating of 92" do
|
46
|
-
expect(movie.metacritic_rating).to eq(
|
50
|
+
expect(movie.metacritic_rating).to eq(92)
|
47
51
|
end
|
48
52
|
|
49
53
|
it "should have metacritic url 'http://www.metacritic.com/movie/toy-story-3'" do
|
@@ -87,7 +91,7 @@ describe 'WorthWatching::Aggregator' do
|
|
87
91
|
end
|
88
92
|
end
|
89
93
|
|
90
|
-
context "when the OMDB API has
|
94
|
+
context "when the OMDB API has no IMDb rating info for a movie" do
|
91
95
|
before do
|
92
96
|
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/captain_america_rt.json")
|
93
97
|
stub_request(:get, /api\.rottentomatoes\.com\/api\/public\/v1\.0\/movies\/771312513\.json\?apikey\=.*/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
@@ -115,47 +119,16 @@ describe 'WorthWatching::Aggregator' do
|
|
115
119
|
end
|
116
120
|
end
|
117
121
|
|
118
|
-
|
122
|
+
context "when the Rotten Tomatoes API does not return the IMDb ID of the movie" do
|
119
123
|
before do
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/3_movie_search_result.json")
|
124
|
-
stub_request(:get, /api\.rottentomatoes\.com\/api\/public\/v1\.0\/movies\.json\?apikey=.*&page_limit=4&q=toy%20story/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
125
|
-
|
126
|
-
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/0_movie_search_result.json")
|
127
|
-
stub_request(:get, /api\.rottentomatoes\.com\/api\/public\/v1\.0\/movies\.json\?apikey=.*&page_limit=4&q=amoviethatdoesnotexist/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
124
|
+
# Single movie RottenTomatoes, with insufficient data
|
125
|
+
json_response = File.read(File.dirname(__FILE__) + "/../support/json_responses/a_movie_with_little_info_rt.json")
|
126
|
+
stub_request(:get, /api\.rottentomatoes\.com\/api\/public\/v1\.0\/movies\/11111111\.json\?apikey\=.*/).to_return(:status => 200, :body => json_response,:headers => {"content-type"=>["application/json; charset=utf-8"]})
|
128
127
|
end
|
129
128
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
it "is an array of movies" do
|
134
|
-
|
135
|
-
expect(results).to be_an_instance_of(Array)
|
136
|
-
end
|
137
|
-
|
138
|
-
it "has the title of the movie result" do
|
139
|
-
expect(results.first[:title]).to eq("Finding Nemo")
|
140
|
-
end
|
141
|
-
|
142
|
-
it "has the Rotten Tomatoes ID of the movie result" do
|
143
|
-
expect(results.first[:rt_id]).to eq("9377")
|
144
|
-
end
|
145
|
-
|
146
|
-
it "has the release year of the movie result" do
|
147
|
-
expect(results.first[:year]).to eq("2003")
|
148
|
-
end
|
149
|
-
end
|
150
|
-
end
|
151
|
-
|
152
|
-
context "when results do not exist for the given query string" do
|
153
|
-
describe "the search results" do
|
154
|
-
it "returns false" do
|
155
|
-
results = aggregator.search_by_title("amoviethatdoesnotexist", 4)
|
156
|
-
expect(results).to be_false
|
157
|
-
end
|
158
|
-
end
|
129
|
+
it "raises an exception" do
|
130
|
+
expect { aggregator.aggregate_movie("11111111") }.to raise_exception(InsufficientDataError,
|
131
|
+
"No IMDb ID present, can't aggregate")
|
159
132
|
end
|
160
133
|
end
|
161
134
|
end
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
{"id":111111,"title":"A Movie From The Future","year":2020,"mpaa_rating":"G","runtime":103,"critics_consensus":"Deftly blending comedy, adventure, and honest emotion, Toy Story 3 is a rare second sequel that really works.","release_dates":{"theater":"2010-06-18","dvd":"2010-11-02"},"ratings":{"critics_rating":"Certified Fresh","critics_score":99,"audience_rating":"Upright","audience_score":89},"synopsis":"Pixar returns to their first success with Toy Story 3. The movie begins with Andy leaving for college and donating his beloved toys -- including Woody (Tom Hanks) and Buzz (Tim Allen) -- to a daycare. While the crew meets new friends, including Ken (Michael Keaton), they soon grow to hate their new surroundings and plan an escape. The film was directed by Lee Unkrich from a script co-authored by Little Miss Sunshine scribe Michael Arndt. ~ Perry Seibert, Rovi","posters":{"thumbnail":"http://content6.flixster.com/movie/11/13/43/11134356_mob.jpg","profile":"http://content6.flixster.com/movie/11/13/43/11134356_pro.jpg","detailed":"http://content6.flixster.com/movie/11/13/43/11134356_det.jpg","original":"http://content6.flixster.com/movie/11/13/43/11134356_ori.jpg"},"abridged_cast":[{"name":"Tom Hanks","id":"162655641","characters":["Woody"]},{"name":"Tim Allen","id":"162655909","characters":["Buzz Lightyear"]},{"name":"Joan Cusack","id":"162655020","characters":["Jessie the Cowgirl"]},{"name":"Ned Beatty","id":"162672460","characters":["Lots-o'-Huggin' Bear","Lotso"]},{"name":"Don Rickles","id":"341817905","characters":["Mr. Potato Head"]}],"studio":"Walt Disney Pictures","links":{"self":"http://api.rottentomatoes.com/api/public/v1.0/movies/770672122.json","alternate":"http://www.rottentomatoes.com/m/toy_story_3/","cast":"http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/cast.json","clips":"http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/clips.json","reviews":"http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/reviews.json","similar":"http://api.rottentomatoes.com/api/public/v1.0/movies/770672122/similar.json"}}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "WorthWatching::IMDB::RatingFetcher" do
|
4
|
+
before do
|
5
|
+
# Single movie OMDB (Toy Story 3)
|
6
|
+
json_response = File.read(File.dirname(__FILE__) + "/../../support/json_responses/toy_story_omdb.json")
|
7
|
+
stub_request(:get, "http://www.omdbapi.com/?i=tt0435761").to_return(:status => 200, :body => json_response)
|
8
|
+
|
9
|
+
# Single movie OMDB (Captain America)
|
10
|
+
json_response = File.read(File.dirname(__FILE__) + "/../../support/json_responses/captain_america_omdb.json")
|
11
|
+
stub_request(:get, "http://www.omdbapi.com/?i=tt1843866").to_return(:status => 200, :body => json_response)
|
12
|
+
|
13
|
+
# IMDb movie webpage (Captain America)
|
14
|
+
json_response = File.read(File.dirname(__FILE__) + "/../../support/html_responses/captain_america_imdb.html")
|
15
|
+
stub_request(:get, "http://m.imdb.com/title/tt1843866/").to_return(:status => 200, :body => json_response)
|
16
|
+
end
|
17
|
+
|
18
|
+
context "when the rating is available using the OMDB API" do
|
19
|
+
it "returns the correct IMDb rating via the OMDB API" do
|
20
|
+
rating = WorthWatching::IMDB::RatingFetcher.fetch("0435761")
|
21
|
+
expect(rating).to eq(8.5)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when the rating is not available using the OMDB API" do
|
26
|
+
it "returns the correct IMDb rating by screenscraping its IMDb webpage" do
|
27
|
+
rating = WorthWatching::IMDB::RatingFetcher.fetch("1843866")
|
28
|
+
expect(rating).to eq(8.3)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|