diff --git a/.gitignore b/.gitignore
index 03f3ce7..30e1656 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,9 @@
# Ignore bundler config.
/.bundle
+
+
+
# Ignore all logfiles and tempfiles.
/log/*
!/log/.keep
@@ -26,7 +29,7 @@
/tmp/
# Used by dotenv library to load environment variables.
-# .env
+.env
## Specific to RubyMotion:
.dat*
diff --git a/Gemfile b/Gemfile
index 288bb87..fabb8fa 100644
--- a/Gemfile
+++ b/Gemfile
@@ -3,16 +3,17 @@ ruby '2.3.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '4.2.6'
-# Use postgresql as the database for Active Record
-gem 'pg', '~> 0.15'
-# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
-# Use Uglifier as compressor for JavaScript assets
+gem 'pg', '~> 0.15'
gem 'uglifier', '>= 1.3.0'
# Use CoffeeScript for .coffee assets and views
gem 'coffee-rails', '~> 4.1.0'
# See https://github.com/rails/execjs#readme for more supported runtimes
# gem 'therubyracer', platforms: :ruby
+gem 'rspotify'
+gem 'yelp'
+gem 'httparty'
+gem 'omniauth-oauth2', '~> 1.3.1'
# Use jquery as the JavaScript library
gem 'jquery-rails'
@@ -21,25 +22,30 @@ gem 'jbuilder', '~> 2.0'
# bundle exec rake doc:rails generates the API under doc/api.
gem 'sdoc', '~> 0.4.0', group: :doc
-# Use ActiveModel has_secure_password
-# gem 'bcrypt', '~> 3.1.7'
-
-# Use Unicorn as the app server
-# gem 'unicorn'
-
-# Use Capistrano for deployment
-# gem 'capistrano-rails', group: :development
+gem 'turbolinks'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'
+ gem 'pry-rails'
+ gem 'dotenv-rails'
+ gem 'simplecov'
+ gem 'minitest-vcr'
+ gem 'minitest-reporters'
+ gem 'webmock'
end
group :development do
# Access an IRB console on exception pages or by using <%= console %> in views
gem 'web-console', '~> 2.0'
+ gem "better_errors"
+ gem "binding_of_caller"
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
+
+ group :production do
+ gem 'rails_12factor'
+ end
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 6ff0f39..285feae 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -36,11 +36,18 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
+ addressable (2.4.0)
+ ansi (1.5.0)
arel (6.0.3)
+ better_errors (2.1.1)
+ coderay (>= 1.0.0)
+ erubis (>= 2.6.6)
+ rack (>= 0.9.0)
binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1)
builder (3.2.2)
byebug (8.2.5)
+ coderay (1.1.1)
coffee-rails (4.1.1)
coffee-script (>= 2.2.0)
railties (>= 4.0.0, < 5.1.x)
@@ -49,11 +56,27 @@ GEM
execjs
coffee-script-source (1.10.0)
concurrent-ruby (1.0.2)
+ crack (0.4.3)
+ safe_yaml (~> 1.0.0)
debug_inspector (0.0.2)
+ docile (1.1.5)
+ dotenv (2.1.1)
+ dotenv-rails (2.1.1)
+ dotenv (= 2.1.1)
+ railties (>= 4.0, < 5.1)
erubis (2.7.0)
execjs (2.6.0)
+ faraday (0.9.2)
+ multipart-post (>= 1.2, < 3)
+ faraday_middleware (0.10.0)
+ faraday (>= 0.7.4, < 0.10)
globalid (0.3.6)
activesupport (>= 4.1.0)
+ hashdiff (0.3.0)
+ hashie (3.4.4)
+ httparty (0.13.7)
+ json (~> 1.8)
+ multi_xml (>= 0.5.2)
i18n (0.7.0)
jbuilder (2.4.1)
activesupport (>= 3.0.0, < 5.1)
@@ -63,19 +86,53 @@ GEM
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
json (1.8.3)
+ jwt (1.5.1)
loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.4)
mime-types (>= 1.16, < 4)
+ method_source (0.8.2)
mime-types (3.0)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0221)
mini_portile2 (2.0.0)
+ minispec-metadata (2.0.0)
+ minitest
minitest (5.8.4)
+ minitest-reporters (1.1.9)
+ ansi
+ builder
+ minitest (>= 5.0)
+ ruby-progressbar
+ minitest-vcr (1.4.0)
+ minispec-metadata (~> 2.0)
+ minitest (>= 4.7.5)
+ vcr (>= 2.9)
multi_json (1.12.0)
+ multi_xml (0.5.5)
+ multipart-post (2.0.0)
+ netrc (0.7.9)
nokogiri (1.6.7.2)
mini_portile2 (~> 2.0.0.rc2)
+ oauth2 (1.1.0)
+ faraday (>= 0.8, < 0.10)
+ jwt (~> 1.0, < 1.5.2)
+ multi_json (~> 1.3)
+ multi_xml (~> 0.5)
+ rack (>= 1.2, < 3)
+ omniauth (1.3.1)
+ hashie (>= 1.2, < 4)
+ rack (>= 1.0, < 3)
+ omniauth-oauth2 (1.3.1)
+ oauth2 (~> 1.0)
+ omniauth (~> 1.2)
pg (0.18.4)
+ pry (0.10.3)
+ coderay (~> 1.1.0)
+ method_source (~> 0.8.1)
+ slop (~> 3.4)
+ pry-rails (0.3.4)
+ pry (>= 0.9.10)
rack (1.6.4)
rack-test (0.6.3)
rack (>= 1.0)
@@ -98,6 +155,11 @@ GEM
rails-deprecated_sanitizer (>= 1.0.1)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
+ rails_12factor (0.0.3)
+ rails_serve_static_assets
+ rails_stdout_logging
+ rails_serve_static_assets (0.0.5)
+ rails_stdout_logging (0.0.5)
railties (4.2.6)
actionpack (= 4.2.6)
activesupport (= 4.2.6)
@@ -106,6 +168,13 @@ GEM
rake (11.1.2)
rdoc (4.2.2)
json (~> 1.4)
+ rest_client (1.8.3)
+ netrc (~> 0.7.7)
+ rspotify (1.10.0)
+ omniauth-oauth2 (~> 1.1)
+ rest_client (~> 1.8)
+ ruby-progressbar (1.8.1)
+ safe_yaml (1.0.4)
sass (3.4.22)
sass-rails (5.0.4)
railties (>= 4.0.0, < 5.0)
@@ -116,6 +185,13 @@ GEM
sdoc (0.4.1)
json (~> 1.7, >= 1.7.7)
rdoc (~> 4.0)
+ simple_oauth (0.3.1)
+ simplecov (0.11.2)
+ docile (~> 1.1.0)
+ json (~> 1.8)
+ simplecov-html (~> 0.10.0)
+ simplecov-html (0.10.0)
+ slop (3.6.0)
spring (1.7.1)
sprockets (3.6.0)
concurrent-ruby (~> 1.0)
@@ -127,31 +203,59 @@ GEM
thor (0.19.1)
thread_safe (0.3.5)
tilt (2.0.2)
+ turbolinks (2.5.3)
+ coffee-rails
tzinfo (1.2.2)
thread_safe (~> 0.1)
uglifier (3.0.0)
execjs (>= 0.3.0, < 3)
+ vcr (3.0.3)
web-console (2.3.0)
activemodel (>= 4.0)
binding_of_caller (>= 0.7.2)
railties (>= 4.0)
sprockets-rails (>= 2.0, < 4.0)
+ webmock (2.0.3)
+ addressable (>= 2.3.6)
+ crack (>= 0.3.2)
+ hashdiff
+ yelp (2.1.2)
+ faraday (~> 0.8, >= 0.8.0)
+ faraday_middleware (~> 0.8, >= 0.8.0)
+ simple_oauth (~> 0.3.1)
PLATFORMS
ruby
DEPENDENCIES
+ better_errors
+ binding_of_caller
byebug
coffee-rails (~> 4.1.0)
+ dotenv-rails
+ httparty
jbuilder (~> 2.0)
jquery-rails
+ minitest-reporters
+ minitest-vcr
+ omniauth-oauth2 (~> 1.3.1)
pg (~> 0.15)
+ pry-rails
rails (= 4.2.6)
+ rails_12factor
+ rspotify
sass-rails (~> 5.0)
sdoc (~> 0.4.0)
+ simplecov
spring
+ turbolinks
uglifier (>= 1.3.0)
web-console (~> 2.0)
+ webmock
+ yelp
+
+RUBY VERSION
+ ruby 2.3.1p112
BUNDLED WITH
- 1.12.3
+ 1.12.4
diff --git a/app/assets/images/Spotify_Icon_RGB_Green.png b/app/assets/images/Spotify_Icon_RGB_Green.png
new file mode 100644
index 0000000..26410e2
Binary files /dev/null and b/app/assets/images/Spotify_Icon_RGB_Green.png differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 646c5ab..573d980 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -13,3 +13,8 @@
//= require jquery
//= require jquery_ujs
//= require_tree .
+$(function() {
+ $('a').click(function() {
+ $(this).find('i').toggleClass('fa fa-heart-o fa fa-heart');
+ });
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/home.coffee b/app/assets/javascripts/home.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/home.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/javascripts/sessions.coffee b/app/assets/javascripts/sessions.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/sessions.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/javascripts/suggestions.coffee b/app/assets/javascripts/suggestions.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/suggestions.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/javascripts/users.coffee b/app/assets/javascripts/users.coffee
new file mode 100644
index 0000000..24f83d1
--- /dev/null
+++ b/app/assets/javascripts/users.coffee
@@ -0,0 +1,3 @@
+# Place all the behaviors and hooks related to the matching controller here.
+# All this logic will automatically be available in application.js.
+# You can use CoffeeScript in this file: http://coffeescript.org/
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
index f9cd5b3..963c220 100644
--- a/app/assets/stylesheets/application.css
+++ b/app/assets/stylesheets/application.css
@@ -1,15 +1,26 @@
-/*
- * This is a manifest file that'll be compiled into application.css, which will include all the files
- * listed below.
- *
- * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
- * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
- *
- * You're free to add application-wide styles to this file and they'll appear at the bottom of the
- * compiled file so the styles you add here take precedence over styles defined in any styles
- * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
- * file per style scope.
- *
- *= require_tree .
- *= require_self
- */
+
+/* ALL PAGES */
+
+.spotify-banner {
+ text-align: right;
+}
+.spotify-banner img {
+
+ width: 75px;
+
+ }
+
+/* SUGGESTION PARTIAL */
+ .album-art {
+ width: 100px;
+ height: 100px;
+ }
+
+.fa {
+ font-size: 2rem !important;
+ color: red;
+}
+
+.fa-heart:hover {
+ cursor: pointer;
+ }
diff --git a/app/assets/stylesheets/home.scss b/app/assets/stylesheets/home.scss
new file mode 100644
index 0000000..f0ddc68
--- /dev/null
+++ b/app/assets/stylesheets/home.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the home controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/sessions.scss b/app/assets/stylesheets/sessions.scss
new file mode 100644
index 0000000..7bef9cf
--- /dev/null
+++ b/app/assets/stylesheets/sessions.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the sessions controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/suggestions.scss b/app/assets/stylesheets/suggestions.scss
new file mode 100644
index 0000000..c0d3b8d
--- /dev/null
+++ b/app/assets/stylesheets/suggestions.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the suggestions controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/users.scss b/app/assets/stylesheets/users.scss
new file mode 100644
index 0000000..1efc835
--- /dev/null
+++ b/app/assets/stylesheets/users.scss
@@ -0,0 +1,3 @@
+// Place all the styles related to the users controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d83690e..916de0c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,4 +2,23 @@ class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
+
+ helper_method :current_user, :user_favorited?, :current_page
+
+
+ def current_user
+ @user ||= User.find_by(id: session[:user_id])
+ end
+
+ def require_login
+ if current_user.nil?
+ flash[:error] = "You must be logged in to view this section"
+ redirect_to root_path
+ end
+ end
+
+ def user_favorited?(suggestion_id)
+ user_favorites = TunesTakeoutWrapper.get_favorites(current_user.uid)
+ user_favorites.include? suggestion_id
+ end
end
diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb
new file mode 100644
index 0000000..1212ca6
--- /dev/null
+++ b/app/controllers/home_controller.rb
@@ -0,0 +1,6 @@
+class HomeController < ApplicationController
+ def index
+ @user = current_user
+ end
+end
+
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
new file mode 100644
index 0000000..24270b8
--- /dev/null
+++ b/app/controllers/sessions_controller.rb
@@ -0,0 +1,18 @@
+class SessionsController < ApplicationController
+ def create
+ auth_hash = request.env['omniauth.auth']
+ @user = User.find_or_create_from_omniauth(auth_hash)
+
+ if @user
+ session[:user_id] = @user.id
+ redirect_to root_path
+ else
+ redirect_to root_path, notice: "Failed to save"
+ end
+ end
+
+ def destroy
+ session.delete :user_id
+ redirect_to root_path
+ end
+end
diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb
new file mode 100644
index 0000000..003b9ac
--- /dev/null
+++ b/app/controllers/suggestions_controller.rb
@@ -0,0 +1,62 @@
+class SuggestionsController < ApplicationController
+ skip_before_action :require_login, only: :index
+
+ def index
+ if @suggestions.nil?
+ redirect_to root_path, notice: "Sorry, nothing was found for #{params["query"]}!"
+ else
+ render :index
+ end
+ end
+
+ def create
+ @tunes_takeout = TunesTakeoutWrapper.search(params["query"])
+ @pairing_suggestions = gather_suggestions
+ render :index
+ end
+
+ def favorites
+ # get the favorites
+ @tunes_takeout = TunesTakeoutWrapper.top_favorites
+
+ @top_favorites = @tunes_takeout.suggestions
+ @list = []
+ #look up each favorite
+ @top_favorites.each do |id|
+ @list << TunesTakeoutWrapper.each_favorite(id)
+ end
+ @music_suggestions = Music.suggested_music(@list)
+ @food_suggestions = Food.suggested_food(@list)
+ @pairing_suggestions = []
+ @list.length.times do |index|
+ @pairing_suggestions << [@music_suggestions[index], @food_suggestions[index], @top_favorites[index]]
+ end
+ end
+
+ private
+
+ def gather_suggestions
+ @suggestions = @tunes_takeout.suggestions
+
+ @ids = []
+ @suggestions.each do |suggestion|
+ @ids << suggestion["id"]
+ end
+
+ @music_suggestions = Music.suggested_music(@suggestions)
+ @food_suggestions = Food.suggested_food(@suggestions)
+
+ pairing_suggestions = []
+
+ @ids.length.times do |index|
+ pairing_suggestions << [@music_suggestions[index], @food_suggestions[index], @ids[index]]
+ end
+
+ return pairing_suggestions
+ end
+end
+
+
+# Opportunity to dry up code between create and favorites methods
+# I will try and get to this after I finish testing
+
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
new file mode 100644
index 0000000..8d43424
--- /dev/null
+++ b/app/controllers/users_controller.rb
@@ -0,0 +1,32 @@
+class UsersController < ApplicationController
+ def favorites
+ @tunes_takeout = TunesTakeoutWrapper.get_favorites(current_user.uid)
+ @list = []
+ @tunes_takeout.each do |id|
+ @list << TunesTakeoutWrapper.each_favorite(id)
+ end
+
+ @music_suggestions = Music.suggested_music(@list)
+ @food_suggestions = Food.suggested_food(@list)
+ @pairing_suggestions = []
+ @list.length.times do |index|
+ @pairing_suggestions << [@music_suggestions[index], @food_suggestions[index], @list[index]]
+ end
+ end
+
+ def favorite
+ id = params.values.to_a
+ suggestion_id = id[2]["id"]
+ user_id = current_user.uid
+ response = TunesTakeoutWrapper.favorite(user_id, suggestion_id)
+ redirect_to my_favorites_path
+ end
+
+ def unfavorite
+ id = params.values.to_a
+ suggestion_id = id[3]["id"]
+ user_id = current_user.uid
+ response = TunesTakeoutWrapper.unfavorite(user_id, suggestion_id)
+ redirect_to my_favorites_path
+ end
+end
\ No newline at end of file
diff --git a/app/helpers/home_helper.rb b/app/helpers/home_helper.rb
new file mode 100644
index 0000000..23de56a
--- /dev/null
+++ b/app/helpers/home_helper.rb
@@ -0,0 +1,2 @@
+module HomeHelper
+end
diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb
new file mode 100644
index 0000000..309f8b2
--- /dev/null
+++ b/app/helpers/sessions_helper.rb
@@ -0,0 +1,2 @@
+module SessionsHelper
+end
diff --git a/app/helpers/suggestions_helper.rb b/app/helpers/suggestions_helper.rb
new file mode 100644
index 0000000..0e358dd
--- /dev/null
+++ b/app/helpers/suggestions_helper.rb
@@ -0,0 +1,2 @@
+module SuggestionsHelper
+end
diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
new file mode 100644
index 0000000..2310a24
--- /dev/null
+++ b/app/helpers/users_helper.rb
@@ -0,0 +1,2 @@
+module UsersHelper
+end
diff --git a/app/models/food.rb b/app/models/food.rb
new file mode 100644
index 0000000..3f5d55d
--- /dev/null
+++ b/app/models/food.rb
@@ -0,0 +1,29 @@
+class Food < ActiveRecord::Base
+ attr_reader :id, :name, :link, :phone, :address, :image, :rating
+
+ def initialize(yelp_object)
+ @id = yelp_object.id
+ @name = yelp_object.name
+ @link = yelp_object.url
+ @image = yelp_object.image_url
+ @rating = {
+ stars: yelp_object.rating,
+ stars_image: yelp_object.rating_img_url
+ }
+ end
+
+
+ def self.suggested_food(tunes_takeout_suggestion)
+ tunes_takeout_suggestion.collect { |suggestion|
+ self.search(suggestion["food_id"])
+ }
+ end
+
+
+ def self.search(food_id)
+ # parameterize fixes accented business names
+ @food = Yelp.client.business(food_id.parameterize).business
+ self.new(@food)
+ end
+
+end
diff --git a/app/models/music.rb b/app/models/music.rb
new file mode 100644
index 0000000..71e05b2
--- /dev/null
+++ b/app/models/music.rb
@@ -0,0 +1,49 @@
+class Music < ActiveRecord::Base
+ attr_reader :id, :name, :type, :link, :image, :embed
+
+ def initialize(spotify_object)
+ @id = spotify_object.id
+ @name = spotify_object.name
+ @link = spotify_object.external_urls["spotify"]
+ @type = spotify_object.type
+ @embed = spotify_object.uri
+ unless @type == "track" || spotify_object.images.empty?
+ @image = check_for_images(spotify_object.images)
+ @image = @image["url"]
+ else
+ @image = nil
+ end
+ end
+
+ def self.suggested_music(tunes_takeout_suggestion)
+ tunes_takeout_suggestion.collect { |suggestion|
+ self.search(suggestion["music_id"],
+ suggestion["music_type"])
+ }
+ end
+
+ def self.search(music_id, music_type)
+ case music_type
+ when "artist"
+ @music = RSpotify::Artist.find(music_id)
+ when "album"
+ @music = RSpotify::Album.find(music_id)
+ when "track"
+ @music = RSpotify::Track.find(music_id)
+ else
+ @music = nil
+ end
+ self.new(@music)
+ end
+
+ def check_for_images(image_array)
+ image_array.find {|image| image["url"] != nil }
+ end
+end
+
+# artist
+# @image = spotify_object.artist.images[0]["url"]
+# album
+# @image = spotify_object.album.images[0]["url"]
+# track
+# @image = spotify_object.images[0]["url"]
\ No newline at end of file
diff --git a/app/models/user.rb b/app/models/user.rb
new file mode 100644
index 0000000..669b4af
--- /dev/null
+++ b/app/models/user.rb
@@ -0,0 +1,31 @@
+class User < ActiveRecord::Base
+ validates :provider, presence: true
+ validates :uid, presence: true
+ validate :provider_must_be_spotify
+
+ def provider_must_be_spotify
+ if provider != "spotify"
+ errors.add(:provider, "provider must be spotify")
+ end
+ end
+
+
+ def self.find_or_create_from_omniauth(auth_hash)
+ user = self.find_by(uid: auth_hash["info"]["id"], provider: auth_hash["provider"])
+ if !user.nil?
+ return user
+ else
+ user = User.new
+ user.uid = auth_hash["info"]['id']
+ user.provider = auth_hash['provider']
+ user.display_name = auth_hash["info"]["display_name"]
+ user.photo_url = auth_hash["info"]['images'][0]['url']
+
+ if user.save
+ return user
+ else
+ return nil
+ end
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb
new file mode 100644
index 0000000..df8c2dd
--- /dev/null
+++ b/app/views/home/index.html.erb
@@ -0,0 +1,10 @@
+
+ Welcome to Tunes and Takeout!
+
+<% if current_user %>
+ <%= form_tag :suggestions, {controller: 'suggestions', action: 'create'} do |f| %>
+ <%= label_tag :query %>
+ <%= text_field_tag :query %>
+ <%= submit_tag("Search") %>
+ <% end %>
+<% end %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 509d1a2..daa88da 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -1,14 +1,33 @@
- TunesTakeout
- <%= stylesheet_link_tag 'application', media: 'all' %>
- <%= javascript_include_tag 'application' %>
+ Tunes and Takeout
+
+
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
+ <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= csrf_meta_tags %>
-<%= yield %>
+
+
+ <%= link_to("#{ current_user.display_name }", "https://play.spotify.com/user/#{current_user.uid}") if current_user %>
+ <%= link_to(image_tag(current_user.photo_url), "https://play.spotify.com/user/#{current_user.uid}") if current_user %>
+ <%= link_to "Listen to Spotify Online!", "https://play.spotify.com/browse" if current_user %>
+ <%= image_tag "Spotify_Icon_RGB_Green.png" %>
+
+
+
+ <%= link_to "Home", root_path %>
+ <%= link_to "My Favorites", my_favorites_path(current_user.uid) if current_user %>
+ <%= link_to "Top Favorites", favorites_path %>
+ <%= link_to "Log In", "/auth/spotify" unless current_user %>
+ <%= link_to "Log Out", logout_path, method: :delete if current_user%>
+
+
+ <%= yield %>
+
diff --git a/app/views/sessions/index.html.erb b/app/views/sessions/index.html.erb
new file mode 100644
index 0000000..e69de29
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb
new file mode 100644
index 0000000..97fb51d
--- /dev/null
+++ b/app/views/sessions/new.html.erb
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/app/views/suggestions/_suggestion.html.erb b/app/views/suggestions/_suggestion.html.erb
new file mode 100644
index 0000000..4507651
--- /dev/null
+++ b/app/views/suggestions/_suggestion.html.erb
@@ -0,0 +1,49 @@
+
+
+
+
+ Artist
+ Type
+ Album Art
+ Restaurant
+ Delicious Imagery
+ Rating
+ Favorite This!
+
+
+
+ <% @pairing_suggestions.each do |music, food, id| %>
+
+ <%= link_to(music.name, "#{music.link}") %>
+ <%= music.type %>
+ <%= image_tag("#{music.image}", :class => 'album-art')%>
+ <%= link_to(food.name, "#{food.link}") %>
+ <%= image_tag("#{food.image}")%>
+
+ <%= food.rating[:stars] %>
+ <%= image_tag("#{food.rating[:stars_image]}") %>
+
+
+ <% if current_user %>
+ <% if user_favorited?(id) %>
+ <%= form_tag my_favorites_path(current_user.uid), controller: "users", method: "delete" do %>
+ <%= hidden_field id, "id", {value: id} %>
+ <%= button_tag(type: 'submit', class: "btn btn-link") do %>
+
+ <% end %>
+ <% end %>
+ <% else %>
+ <%= form_tag my_favorites_path(current_user.uid), controller: "users", method: "post" do %>
+ <%= hidden_field id, "id", {value: id} %>
+ <%= button_tag(type: 'submit', class: "btn btn-link") do %>
+
+ <% end %>
+ <% end %>
+ <% end %>
+ <% end %>
+
+
+ <% end %>
+
+
+
diff --git a/app/views/suggestions/favorite.html.erb b/app/views/suggestions/favorite.html.erb
new file mode 100644
index 0000000..cd58561
--- /dev/null
+++ b/app/views/suggestions/favorite.html.erb
@@ -0,0 +1 @@
+<%= render partial: "suggestion" %>
\ No newline at end of file
diff --git a/app/views/suggestions/favorites.html.erb b/app/views/suggestions/favorites.html.erb
new file mode 100644
index 0000000..957d482
--- /dev/null
+++ b/app/views/suggestions/favorites.html.erb
@@ -0,0 +1,4 @@
+
+ Top 10 Favorite Suggestions List!
+
+<%= render partial: "suggestion" %>
\ No newline at end of file
diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb
new file mode 100644
index 0000000..49f96f0
--- /dev/null
+++ b/app/views/suggestions/index.html.erb
@@ -0,0 +1,7 @@
+<% if current_user %>
+
+ Here's a list of suggestions!
+
+
+ <%= render partial: "suggestion" %>
+<% end %>
diff --git a/app/views/users/favorites.html.erb b/app/views/users/favorites.html.erb
new file mode 100644
index 0000000..24956c4
--- /dev/null
+++ b/app/views/users/favorites.html.erb
@@ -0,0 +1,33 @@
+
+
+
+
+ Artist
+ Type
+ Album Art
+ Restaurant
+ Delicious Imagery
+ Rating
+ Favorited
+
+
+
+ <% @pairing_suggestions.each do |music, food, id| %>
+
+ <%= link_to(music.name, "#{music.link}") %>
+ <%= music.type %>
+ <%= image_tag("#{music.image}", :class => 'album-art')%>
+ <%= link_to(food.name, "#{food.link}") %>
+ <%= image_tag("#{food.image}")%>
+
+ <%= food.rating[:stars] %>
+ <%= image_tag("#{food.rating[:stars_image]}") %>
+
+
+
+
+
+ <% end %>
+
+
+
diff --git a/config/application.rb b/config/application.rb
index 9b37a86..ff18fa1 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -8,19 +8,8 @@
module TunesTakeout
class Application < Rails::Application
- # Settings in config/environments/* take precedence over those specified here.
- # Application configuration should go into files in config/initializers
- # -- all .rb files in that directory are automatically loaded.
-
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
- # config.time_zone = 'Central Time (US & Canada)'
-
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
- # config.i18n.default_locale = :de
-
- # Do not swallow errors in after_commit/after_rollback callbacks.
config.active_record.raise_in_transactional_callbacks = true
+ config.autoload_paths += %W(#{config.root}/lib)
+ config.autoload_paths += %W(#{config.root}/extras)
end
end
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
new file mode 100644
index 0000000..1232b3c
--- /dev/null
+++ b/config/initializers/omniauth.rb
@@ -0,0 +1,5 @@
+require 'rspotify/oauth'
+
+Rails.application.config.middleware.use OmniAuth::Builder do
+ provider :spotify, ENV["SPOTIFY_CLIENT_ID"], ENV["SPOTIFY_CLIENT_SECRET"], scope: 'user-read-email playlist-modify-public user-library-read user-library-modify'
+end
\ No newline at end of file
diff --git a/config/initializers/spotify.rb b/config/initializers/spotify.rb
new file mode 100644
index 0000000..f3c5fc0
--- /dev/null
+++ b/config/initializers/spotify.rb
@@ -0,0 +1,3 @@
+require 'rspotify'
+
+RSpotify::authenticate(ENV["SPOTIFY_CLIENT_ID"], ENV["SPOTIFY_CLIENT_SECRET"])
\ No newline at end of file
diff --git a/config/initializers/yelp.rb b/config/initializers/yelp.rb
new file mode 100644
index 0000000..e1bb5ad
--- /dev/null
+++ b/config/initializers/yelp.rb
@@ -0,0 +1,8 @@
+require 'yelp'
+
+Yelp.client.configure do |config|
+ config.consumer_key = ENV["YELP_CONSUMER_KEY"]
+ config.consumer_secret = ENV["YELP_CONSUMER_SECRET"]
+ config.token = ENV["YELP_TOKEN"]
+ config.token_secret = ENV["YELP_TOKEN_SECRET"]
+end
diff --git a/config/routes.rb b/config/routes.rb
index 3f66539..57a61c8 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,56 +1,12 @@
Rails.application.routes.draw do
- # The priority is based upon order of creation: first created -> highest priority.
- # See how all your routes lay out with "rake routes".
-
- # You can have the root of your site routed with "root"
- # root 'welcome#index'
-
- # Example of regular route:
- # get 'products/:id' => 'catalog#view'
-
- # Example of named route that can be invoked with purchase_url(id: product.id)
- # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
-
- # Example resource route (maps HTTP verbs to controller actions automatically):
- # resources :products
-
- # Example resource route with options:
- # resources :products do
- # member do
- # get 'short'
- # post 'toggle'
- # end
- #
- # collection do
- # get 'sold'
- # end
- # end
-
- # Example resource route with sub-resources:
- # resources :products do
- # resources :comments, :sales
- # resource :seller
- # end
-
- # Example resource route with more complex sub-resources:
- # resources :products do
- # resources :comments
- # resources :sales do
- # get 'recent', on: :collection
- # end
- # end
-
- # Example resource route with concerns:
- # concern :toggleable do
- # post 'toggle'
- # end
- # resources :posts, concerns: :toggleable
- # resources :photos, concerns: :toggleable
-
- # Example resource route within a namespace:
- # namespace :admin do
- # # Directs /admin/products/* to Admin::ProductsController
- # # (app/controllers/admin/products_controller.rb)
- # resources :products
- # end
+ root 'home#index'
+ get '/sign-in' => 'sessions#new', as: :signin
+ delete '/logout' => 'sessions#destroy', as: :logout
+ get '/auth/:provider/callback' => 'sessions#create'
+ get '/suggestions' => 'suggestions#index'
+ post '/suggestions' => 'suggestions#create'
+ get '/favorites' => 'suggestions#favorites', as: :favorites
+ get '/:uid/favorites' => 'users#favorites', as: :my_favorites
+ post '/:uid/favorites' => 'users#favorite', as: :favorite
+ delete '/:uid/favorites' => 'users#unfavorite'
end
diff --git a/config/secrets.yml b/config/secrets.yml
index be83593..d2c55fe 100644
--- a/config/secrets.yml
+++ b/config/secrets.yml
@@ -11,11 +11,9 @@
# if you're sharing your code publicly.
development:
- secret_key_base: 553149b03d6ba63414be540733245f323d241c1c9a37f3266d1216d93effd901fefb43f0782e4d2b739d61a3de1488c681a90435b22318114f638d9fc6e0f8c1
-
+ secret_key_base: db7e6840cccde3debf77d5f3248bb203374da39baca1a887d4dbed47db740a3f860f9b3dce0069d28890962eaa3d64a2e412bede772dd20dc5a519acd405d38a
test:
- secret_key_base: 0c9e2ff02abb06b715fccfbd8a7fb390a12595cf1c4d8b58cae707903a17a4a58ea0762f4a2125da40cf59b211620b81e702e13d58c4a50e4591f48dcbf1cbaa
-
+ secret_key_base: b060a8937c44c51655498ac8d5434c9e8421e73fdbf5e39981a0faaf2a0b42a5199607e6fe7adf1deeeb7ebdb5f6db9a61a9bd6ebfdf2e7591b44a2ee0538e15
# Do not keep production secrets in the repository,
# instead read values from the environment.
production:
diff --git a/db/migrate/20160517173932_create_users.rb b/db/migrate/20160517173932_create_users.rb
new file mode 100644
index 0000000..ef829da
--- /dev/null
+++ b/db/migrate/20160517173932_create_users.rb
@@ -0,0 +1,9 @@
+class CreateUsers < ActiveRecord::Migration
+ def change
+ create_table :users do |t|
+ t.string :id, null: false
+ t.string :display_name, null: false
+ t.string :email, null: false
+ t.timestamps null: false
+ end
+end
diff --git a/db/migrate/20160517180300_create_foods.rb b/db/migrate/20160517180300_create_foods.rb
new file mode 100644
index 0000000..5d62fcd
--- /dev/null
+++ b/db/migrate/20160517180300_create_foods.rb
@@ -0,0 +1,8 @@
+class CreateFoods < ActiveRecord::Migration
+ def change
+ create_table :foods do |t|
+
+ t.timestamps null: false
+ end
+ end
+end
diff --git a/db/migrate/20160517180306_create_musics.rb b/db/migrate/20160517180306_create_musics.rb
new file mode 100644
index 0000000..2cc03f3
--- /dev/null
+++ b/db/migrate/20160517180306_create_musics.rb
@@ -0,0 +1,8 @@
+class CreateMusics < ActiveRecord::Migration
+ def change
+ create_table :musics do |t|
+
+ t.timestamps null: false
+ end
+ end
+end
diff --git a/db/migrate/20160518000618_update_users_table_with_spotify_info.rb b/db/migrate/20160518000618_update_users_table_with_spotify_info.rb
new file mode 100644
index 0000000..daa069d
--- /dev/null
+++ b/db/migrate/20160518000618_update_users_table_with_spotify_info.rb
@@ -0,0 +1,7 @@
+class UpdateUsersTableWithSpotifyInfo < ActiveRecord::Migration
+ def change
+ add_column :users, :id, :string, null: false
+ add_column :users, :display_name, :string, null: true
+ add_column :users, :email, :string, null: true
+ end
+end
diff --git a/db/migrate/20160518001155_adding_all_things_to_users.rb b/db/migrate/20160518001155_adding_all_things_to_users.rb
new file mode 100644
index 0000000..8b5bf6d
--- /dev/null
+++ b/db/migrate/20160518001155_adding_all_things_to_users.rb
@@ -0,0 +1,7 @@
+class AddingAllThingsToUsers < ActiveRecord::Migration
+ def change
+ change_column :users, :uid, :string
+ change_column :users, :display_name, :string
+ change_column :users, :email, :string
+ change_column :users, :provider, :string
+end
diff --git a/db/migrate/20160519064009_add_photo_url_to_users.rb b/db/migrate/20160519064009_add_photo_url_to_users.rb
new file mode 100644
index 0000000..007ea70
--- /dev/null
+++ b/db/migrate/20160519064009_add_photo_url_to_users.rb
@@ -0,0 +1,5 @@
+class AddPhotoUrlToUsers < ActiveRecord::Migration
+ def change
+ add_column :users, :photo_url, :string
+ end
+end
diff --git a/db/migrate/20160523001927_update_users_schema_per_spec.rb b/db/migrate/20160523001927_update_users_schema_per_spec.rb
new file mode 100644
index 0000000..edcf38a
--- /dev/null
+++ b/db/migrate/20160523001927_update_users_schema_per_spec.rb
@@ -0,0 +1,5 @@
+class UpdateUsersSchemaPerSpec < ActiveRecord::Migration
+ def change
+ change_column :users, :uid, :string
+ end
+end
diff --git a/db/migrate/20160523002203_update_users_schema_to_remove_null_constraints.rb b/db/migrate/20160523002203_update_users_schema_to_remove_null_constraints.rb
new file mode 100644
index 0000000..c0ec35e
--- /dev/null
+++ b/db/migrate/20160523002203_update_users_schema_to_remove_null_constraints.rb
@@ -0,0 +1,8 @@
+class UpdateUsersSchemaToRemoveNullConstraints < ActiveRecord::Migration
+ def change
+ change_column :users, :uid, :string, :null true
+ change_column :users, :display_name, :string, :null true
+ change_column :users, :email, :string, :null true
+ change_column :users, :provider, :string, :null true
+ end
+end
diff --git a/db/migrate/20160523002905_update_users_to_not_null.rb b/db/migrate/20160523002905_update_users_to_not_null.rb
new file mode 100644
index 0000000..c4a01ea
--- /dev/null
+++ b/db/migrate/20160523002905_update_users_to_not_null.rb
@@ -0,0 +1,8 @@
+class UpdateUsersToNotNull < ActiveRecord::Migration
+ def change
+ change_column_null :users, :uid, :string, true
+ change_column_null :users, :display_name, :string, true
+ change_column_null :users, :email, :string, true
+ change_column_null :users, :provider, :string, true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
new file mode 100644
index 0000000..501175f
--- /dev/null
+++ b/db/schema.rb
@@ -0,0 +1,39 @@
+# encoding: UTF-8
+# This file is auto-generated from the current state of the database. Instead
+# of editing this file, please use the migrations feature of Active Record to
+# incrementally modify your database, and then regenerate this schema definition.
+#
+# Note that this schema.rb definition is the authoritative source for your
+# database schema. If you need to create the application database on another
+# system, you should be using db:schema:load, not running all the migrations
+# from scratch. The latter is a flawed and unsustainable approach (the more migrations
+# you'll amass, the slower it'll run and the greater likelihood for issues).
+#
+# It's strongly recommended that you check this file into your version control system.
+
+ActiveRecord::Schema.define(version: 20160523002905) do
+
+ # These are extensions that must be enabled in order to support this database
+ enable_extension "plpgsql"
+
+ create_table "foods", force: :cascade do |t|
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ create_table "musics", force: :cascade do |t|
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ end
+
+ create_table "users", force: :cascade do |t|
+ t.datetime "created_at", null: false
+ t.datetime "updated_at", null: false
+ t.string "uid"
+ t.string "display_name"
+ t.string "email"
+ t.string "provider"
+ t.string "photo_url"
+ end
+
+end
diff --git a/lib/tunes_takeout_wrapper.rb b/lib/tunes_takeout_wrapper.rb
new file mode 100644
index 0000000..6dacd03
--- /dev/null
+++ b/lib/tunes_takeout_wrapper.rb
@@ -0,0 +1,40 @@
+require 'httparty'
+require 'json'
+
+class TunesTakeoutWrapper
+ BASE_URL = "https://tunes-takeout-api.herokuapp.com/v1/"
+ attr_reader :suggestions, :href
+
+ def initialize(data)
+ @href = data["href"]
+ @suggestions = data["suggestions"]
+ end
+
+ def self.search(query, limit=10, seed=nil)
+ data = HTTParty.get(BASE_URL + "suggestions/search?query=#{query}").parsed_response
+ self.new(data)
+ end
+
+ def self.top_favorites(limit=10)
+ data = HTTParty.get(BASE_URL + "suggestions/top?limit=#{limit}").parsed_response
+ self.new(data)
+ end
+
+ def self.each_favorite(id)
+ data = HTTParty.get(BASE_URL + "suggestions/#{id}").parsed_response
+ @suggestion = data["suggestion"]
+ end
+
+ def self.get_favorites(user_id)
+ data = HTTParty.get(BASE_URL + "users/#{user_id}/favorites").parsed_response
+ @favorites = data["suggestions"]
+ end
+
+ def self.favorite(user_id, suggestion_id)
+ HTTParty.post(BASE_URL + "users/#{user_id}/favorites", { body: { "suggestion": suggestion_id }.to_json} )
+ end
+
+ def self.unfavorite(user_id, suggestion_id)
+ HTTParty.delete(BASE_URL + "users/#{user_id}/favorites", { body: { "suggestion": suggestion_id }.to_json} )
+ end
+end
diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_access_a_single_favorite_by_url.yml b/test/cassettes/TunesTakeoutWrapper/API/can_access_a_single_favorite_by_url.yml
new file mode 100644
index 0000000..b9335ce
--- /dev/null
+++ b/test/cassettes/TunesTakeoutWrapper/API/can_access_a_single_favorite_by_url.yml
@@ -0,0 +1,207 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?query=avocado
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:48 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '2514'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu
+ Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT1hdm9jYWRvXHUwMDI2
+ bGltaXQ9MjBcdTAwMjZzZWVkPWF2b2NhZG8iLCJzdWdnZXN0aW9ucyI6W3si
+ aWQiOiJWMElaRWxFbEp3QUR6R00wIiwiZm9vZF9pZCI6ImhvbWVncm93bi1z
+ ZWF0dGxlLTMiLCJtdXNpY19pZCI6IjNRcGgxRFB6RU9zamVDMW1DQ24zSzgi
+ LCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdN
+ MSIsImZvb2RfaWQiOiJlbC1jYW1pw7NuLXNlYXR0bGUtNiIsIm11c2ljX2lk
+ IjoiNDQxUTdtYjJRYmdZTklDNDVoOTdOciIsIm11c2ljX3R5cGUiOiJ0cmFj
+ ayJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R00yIiwiZm9vZF9pZCI6InBsdW0t
+ dmVnYW4tYmlzdHJvLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFiWkFKMnpPRERQ
+ ZmFaVnRZMTMwV0ciLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJ
+ WkVsRWxKd0FEekdNMyIsImZvb2RfaWQiOiJtb21pamktc2VhdHRsZSIsIm11
+ c2ljX2lkIjoiMXl1Vkd5bk5OcGJwek16V0M3WFNkZCIsIm11c2ljX3R5cGUi
+ OiJhbGJ1bSJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R000IiwiZm9vZF9pZCI6
+ Im5vLWJvbmVzLWJlYWNoLWNsdWItc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIz
+ SEdVWXNSWDVkSGxVeE1EY2dyOUlKIiwibXVzaWNfdHlwZSI6InRyYWNrIn0s
+ eyJpZCI6IlZ6ODNDdkxXN3dBRHBNQ2EiLCJmb29kX2lkIjoiZ3JlYXQtbnct
+ c291cC1zZWF0dGxlIiwibXVzaWNfaWQiOiI0RU5wMXdldVpLVGlNaXJTU3pL
+ WkFzIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTTUiLCJmb29kX2lkIjoiYmVhY29uLWF2ZS1zYW5kd2ljaGVzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjEzd01mN21rdHVXY3Zxb1c1VFl3bXIiLCJtdXNp
+ Y190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdNNiIsImZv
+ b2RfaWQiOiJvZGRmZWxsb3dzLWNhZmUtYW5kLWJhci1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxYllxQ2p5b1g0NTZZT3NDNU1oaU5DIiwibXVzaWNfdHlwZSI6
+ InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTciLCJmb29kX2lkIjoi
+ Y2FmZS15dW1tLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMG82ZzJDZFpPdjlw
+ ZzZybjdWdkJxQyIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsiaWQiOiJWMEla
+ RWxFbEp3QUR6R004IiwiZm9vZF9pZCI6InNlYXR0bGUtc2FsYWRzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjNIb2lCdXA3QzU1cmxJUnVZQzlObnQiLCJtdXNp
+ Y190eXBlIjoidHJhY2sifSx7ImlkIjoiVnowVWRRak5xQUFEQmJfQiIsImZv
+ b2RfaWQiOiJzZcOxb3ItbW9vc2UtY2Fmw6ktc2VhdHRsZS0yIiwibXVzaWNf
+ aWQiOiIwbjVUcGlWN3NsWjc0eElKTVRNZFI4IiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTkiLCJmb29kX2lkIjoic2hp
+ a3Utc3VzaGktc2VhdHRsZSIsIm11c2ljX2lkIjoiMWtUNGxLUlV3VGJsQlVV
+ b1h0ZjB0ZCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWejAtZGdq
+ TnFBQURCYzAxIiwiZm9vZF9pZCI6ImFtZXJpY2FuYS1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxMXBhUmp6cFR0eWd0REwwM2JTQjUwIiwibXVzaWNfdHlwZSI6
+ ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTS0iLCJmb29kX2lkIjoi
+ Z2xvcy1zZWF0dGxlIiwibXVzaWNfaWQiOiIyc2duSXdaUU5YaTlOTnc4blBs
+ MU5aIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTV8iLCJmb29kX2lkIjoic3VzaGktbWFraS1zZWF0dGxlIiwibXVzaWNf
+ aWQiOiIxcjBDREl1Z0NmeEppZThkVmpFSU9VIiwibXVzaWNfdHlwZSI6ImFs
+ YnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkEiLCJmb29kX2lkIjoibWFu
+ ZWtpLXNlYXR0bGUiLCJtdXNpY19pZCI6IjJnZWJUU3llVVkwMDlaajFuODNl
+ WW8iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJWkVsRWxKd0FE
+ ekdOQiIsImZvb2RfaWQiOiJob21lZ3Jvd24tc2VhdHRsZS01IiwibXVzaWNf
+ aWQiOiIzSTM3QWRLRmlWS0xtcUtjZ2lXQ1REIiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkMiLCJmb29kX2lkIjoibmlq
+ by1zdXNoaS1iYXItYW5kLWdyaWxsLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFZ
+ MnBaTTVJakp0aEZ2TDVGVkRBMG4iLCJtdXNpY190eXBlIjoiYXJ0aXN0In0s
+ eyJpZCI6IlYwSVpFbEVsSndBRHpHTkQiLCJmb29kX2lkIjoiaS1sb3ZlLXN1
+ c2hpLW9uLWxha2UtdW5pb24tc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIwUUFH
+ QkRWakxpNE1uazJNR3lQUUZVIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJp
+ ZCI6IlYwSVpFbEVsSndBRHpHTkUiLCJmb29kX2lkIjoiY2hhY28tY2FueW9u
+ LW9yZ2FuaWMtY2FmZS1zZWF0dGxlLTIiLCJtdXNpY19pZCI6IjJadjdRUldG
+ bmJRa3RxbDY4WkxZMGUiLCJtdXNpY190eXBlIjoiYWxidW0ifV19
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:49 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:49 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '284'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9Q","Vz0KO4-RRwADbn9d","Vz0KQY-RRwADboEq"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:50 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:50 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '219'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f","suggestion":{"id":"Vz0KO4-RRwADbn9f","food_id":"cactus-restaurants-seattle-2","music_id":"20OmjCaPoZZg3hQ9iOKmrq","music_type":"album"}}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:50 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:50 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:51 GMT
+recorded_with: VCR 3.0.3
diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_favorite_a_suggestion.yml b/test/cassettes/TunesTakeoutWrapper/API/can_favorite_a_suggestion.yml
new file mode 100644
index 0000000..7c7e799
--- /dev/null
+++ b/test/cassettes/TunesTakeoutWrapper/API/can_favorite_a_suggestion.yml
@@ -0,0 +1,285 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?query=avocado
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:55 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '2514'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu
+ Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT1hdm9jYWRvXHUwMDI2
+ bGltaXQ9MjBcdTAwMjZzZWVkPWF2b2NhZG8iLCJzdWdnZXN0aW9ucyI6W3si
+ aWQiOiJWMElaRWxFbEp3QUR6R00wIiwiZm9vZF9pZCI6ImhvbWVncm93bi1z
+ ZWF0dGxlLTMiLCJtdXNpY19pZCI6IjNRcGgxRFB6RU9zamVDMW1DQ24zSzgi
+ LCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdN
+ MSIsImZvb2RfaWQiOiJlbC1jYW1pw7NuLXNlYXR0bGUtNiIsIm11c2ljX2lk
+ IjoiNDQxUTdtYjJRYmdZTklDNDVoOTdOciIsIm11c2ljX3R5cGUiOiJ0cmFj
+ ayJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R00yIiwiZm9vZF9pZCI6InBsdW0t
+ dmVnYW4tYmlzdHJvLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFiWkFKMnpPRERQ
+ ZmFaVnRZMTMwV0ciLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJ
+ WkVsRWxKd0FEekdNMyIsImZvb2RfaWQiOiJtb21pamktc2VhdHRsZSIsIm11
+ c2ljX2lkIjoiMXl1Vkd5bk5OcGJwek16V0M3WFNkZCIsIm11c2ljX3R5cGUi
+ OiJhbGJ1bSJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R000IiwiZm9vZF9pZCI6
+ Im5vLWJvbmVzLWJlYWNoLWNsdWItc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIz
+ SEdVWXNSWDVkSGxVeE1EY2dyOUlKIiwibXVzaWNfdHlwZSI6InRyYWNrIn0s
+ eyJpZCI6IlZ6ODNDdkxXN3dBRHBNQ2EiLCJmb29kX2lkIjoiZ3JlYXQtbnct
+ c291cC1zZWF0dGxlIiwibXVzaWNfaWQiOiI0RU5wMXdldVpLVGlNaXJTU3pL
+ WkFzIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTTUiLCJmb29kX2lkIjoiYmVhY29uLWF2ZS1zYW5kd2ljaGVzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjEzd01mN21rdHVXY3Zxb1c1VFl3bXIiLCJtdXNp
+ Y190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdNNiIsImZv
+ b2RfaWQiOiJvZGRmZWxsb3dzLWNhZmUtYW5kLWJhci1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxYllxQ2p5b1g0NTZZT3NDNU1oaU5DIiwibXVzaWNfdHlwZSI6
+ InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTciLCJmb29kX2lkIjoi
+ Y2FmZS15dW1tLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMG82ZzJDZFpPdjlw
+ ZzZybjdWdkJxQyIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsiaWQiOiJWMEla
+ RWxFbEp3QUR6R004IiwiZm9vZF9pZCI6InNlYXR0bGUtc2FsYWRzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjNIb2lCdXA3QzU1cmxJUnVZQzlObnQiLCJtdXNp
+ Y190eXBlIjoidHJhY2sifSx7ImlkIjoiVnowVWRRak5xQUFEQmJfQiIsImZv
+ b2RfaWQiOiJzZcOxb3ItbW9vc2UtY2Fmw6ktc2VhdHRsZS0yIiwibXVzaWNf
+ aWQiOiIwbjVUcGlWN3NsWjc0eElKTVRNZFI4IiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTkiLCJmb29kX2lkIjoic2hp
+ a3Utc3VzaGktc2VhdHRsZSIsIm11c2ljX2lkIjoiMWtUNGxLUlV3VGJsQlVV
+ b1h0ZjB0ZCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWejAtZGdq
+ TnFBQURCYzAxIiwiZm9vZF9pZCI6ImFtZXJpY2FuYS1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxMXBhUmp6cFR0eWd0REwwM2JTQjUwIiwibXVzaWNfdHlwZSI6
+ ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTS0iLCJmb29kX2lkIjoi
+ Z2xvcy1zZWF0dGxlIiwibXVzaWNfaWQiOiIyc2duSXdaUU5YaTlOTnc4blBs
+ MU5aIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTV8iLCJmb29kX2lkIjoic3VzaGktbWFraS1zZWF0dGxlIiwibXVzaWNf
+ aWQiOiIxcjBDREl1Z0NmeEppZThkVmpFSU9VIiwibXVzaWNfdHlwZSI6ImFs
+ YnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkEiLCJmb29kX2lkIjoibWFu
+ ZWtpLXNlYXR0bGUiLCJtdXNpY19pZCI6IjJnZWJUU3llVVkwMDlaajFuODNl
+ WW8iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJWkVsRWxKd0FE
+ ekdOQiIsImZvb2RfaWQiOiJob21lZ3Jvd24tc2VhdHRsZS01IiwibXVzaWNf
+ aWQiOiIzSTM3QWRLRmlWS0xtcUtjZ2lXQ1REIiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkMiLCJmb29kX2lkIjoibmlq
+ by1zdXNoaS1iYXItYW5kLWdyaWxsLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFZ
+ MnBaTTVJakp0aEZ2TDVGVkRBMG4iLCJtdXNpY190eXBlIjoiYXJ0aXN0In0s
+ eyJpZCI6IlYwSVpFbEVsSndBRHpHTkQiLCJmb29kX2lkIjoiaS1sb3ZlLXN1
+ c2hpLW9uLWxha2UtdW5pb24tc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIwUUFH
+ QkRWakxpNE1uazJNR3lQUUZVIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJp
+ ZCI6IlYwSVpFbEVsSndBRHpHTkUiLCJmb29kX2lkIjoiY2hhY28tY2FueW9u
+ LW9yZ2FuaWMtY2FmZS1zZWF0dGxlLTIiLCJtdXNpY19pZCI6IjJadjdRUldG
+ bmJRa3RxbDY4WkxZMGUiLCJtdXNpY190eXBlIjoiYWxidW0ifV19
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:55 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:55 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '284'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9Q","Vz0KO4-RRwADbn9d","Vz0KQY-RRwADboEq"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:56 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:56 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '219'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f","suggestion":{"id":"Vz0KO4-RRwADbn9f","food_id":"cactus-restaurants-seattle-2","music_id":"20OmjCaPoZZg3hQ9iOKmrq","music_type":"album"}}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:56 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:56 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:57 GMT
+- request:
+ method: post
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: UTF-8
+ string: '{"suggestion":"Vz92VPLW7wADpNDB"}'
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 409
+ message: Conflict
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:57 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - text/html;charset=utf-8
+ X-Xss-Protection:
+ - 1; mode=block
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ Content-Length:
+ - '0'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:57 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:57 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:58 GMT
+recorded_with: VCR 3.0.3
diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_unfavorite_a_suggestion.yml b/test/cassettes/TunesTakeoutWrapper/API/can_unfavorite_a_suggestion.yml
new file mode 100644
index 0000000..0387a3b
--- /dev/null
+++ b/test/cassettes/TunesTakeoutWrapper/API/can_unfavorite_a_suggestion.yml
@@ -0,0 +1,320 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?query=avocado
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:01 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '2514'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu
+ Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT1hdm9jYWRvXHUwMDI2
+ bGltaXQ9MjBcdTAwMjZzZWVkPWF2b2NhZG8iLCJzdWdnZXN0aW9ucyI6W3si
+ aWQiOiJWMElaRWxFbEp3QUR6R00wIiwiZm9vZF9pZCI6ImhvbWVncm93bi1z
+ ZWF0dGxlLTMiLCJtdXNpY19pZCI6IjNRcGgxRFB6RU9zamVDMW1DQ24zSzgi
+ LCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdN
+ MSIsImZvb2RfaWQiOiJlbC1jYW1pw7NuLXNlYXR0bGUtNiIsIm11c2ljX2lk
+ IjoiNDQxUTdtYjJRYmdZTklDNDVoOTdOciIsIm11c2ljX3R5cGUiOiJ0cmFj
+ ayJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R00yIiwiZm9vZF9pZCI6InBsdW0t
+ dmVnYW4tYmlzdHJvLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFiWkFKMnpPRERQ
+ ZmFaVnRZMTMwV0ciLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJ
+ WkVsRWxKd0FEekdNMyIsImZvb2RfaWQiOiJtb21pamktc2VhdHRsZSIsIm11
+ c2ljX2lkIjoiMXl1Vkd5bk5OcGJwek16V0M3WFNkZCIsIm11c2ljX3R5cGUi
+ OiJhbGJ1bSJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R000IiwiZm9vZF9pZCI6
+ Im5vLWJvbmVzLWJlYWNoLWNsdWItc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIz
+ SEdVWXNSWDVkSGxVeE1EY2dyOUlKIiwibXVzaWNfdHlwZSI6InRyYWNrIn0s
+ eyJpZCI6IlZ6ODNDdkxXN3dBRHBNQ2EiLCJmb29kX2lkIjoiZ3JlYXQtbnct
+ c291cC1zZWF0dGxlIiwibXVzaWNfaWQiOiI0RU5wMXdldVpLVGlNaXJTU3pL
+ WkFzIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTTUiLCJmb29kX2lkIjoiYmVhY29uLWF2ZS1zYW5kd2ljaGVzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjEzd01mN21rdHVXY3Zxb1c1VFl3bXIiLCJtdXNp
+ Y190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdNNiIsImZv
+ b2RfaWQiOiJvZGRmZWxsb3dzLWNhZmUtYW5kLWJhci1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxYllxQ2p5b1g0NTZZT3NDNU1oaU5DIiwibXVzaWNfdHlwZSI6
+ InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTciLCJmb29kX2lkIjoi
+ Y2FmZS15dW1tLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMG82ZzJDZFpPdjlw
+ ZzZybjdWdkJxQyIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsiaWQiOiJWMEla
+ RWxFbEp3QUR6R004IiwiZm9vZF9pZCI6InNlYXR0bGUtc2FsYWRzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjNIb2lCdXA3QzU1cmxJUnVZQzlObnQiLCJtdXNp
+ Y190eXBlIjoidHJhY2sifSx7ImlkIjoiVnowVWRRak5xQUFEQmJfQiIsImZv
+ b2RfaWQiOiJzZcOxb3ItbW9vc2UtY2Fmw6ktc2VhdHRsZS0yIiwibXVzaWNf
+ aWQiOiIwbjVUcGlWN3NsWjc0eElKTVRNZFI4IiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTkiLCJmb29kX2lkIjoic2hp
+ a3Utc3VzaGktc2VhdHRsZSIsIm11c2ljX2lkIjoiMWtUNGxLUlV3VGJsQlVV
+ b1h0ZjB0ZCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWejAtZGdq
+ TnFBQURCYzAxIiwiZm9vZF9pZCI6ImFtZXJpY2FuYS1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxMXBhUmp6cFR0eWd0REwwM2JTQjUwIiwibXVzaWNfdHlwZSI6
+ ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTS0iLCJmb29kX2lkIjoi
+ Z2xvcy1zZWF0dGxlIiwibXVzaWNfaWQiOiIyc2duSXdaUU5YaTlOTnc4blBs
+ MU5aIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTV8iLCJmb29kX2lkIjoic3VzaGktbWFraS1zZWF0dGxlIiwibXVzaWNf
+ aWQiOiIxcjBDREl1Z0NmeEppZThkVmpFSU9VIiwibXVzaWNfdHlwZSI6ImFs
+ YnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkEiLCJmb29kX2lkIjoibWFu
+ ZWtpLXNlYXR0bGUiLCJtdXNpY19pZCI6IjJnZWJUU3llVVkwMDlaajFuODNl
+ WW8iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJWkVsRWxKd0FE
+ ekdOQiIsImZvb2RfaWQiOiJob21lZ3Jvd24tc2VhdHRsZS01IiwibXVzaWNf
+ aWQiOiIzSTM3QWRLRmlWS0xtcUtjZ2lXQ1REIiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkMiLCJmb29kX2lkIjoibmlq
+ by1zdXNoaS1iYXItYW5kLWdyaWxsLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFZ
+ MnBaTTVJakp0aEZ2TDVGVkRBMG4iLCJtdXNpY190eXBlIjoiYXJ0aXN0In0s
+ eyJpZCI6IlYwSVpFbEVsSndBRHpHTkQiLCJmb29kX2lkIjoiaS1sb3ZlLXN1
+ c2hpLW9uLWxha2UtdW5pb24tc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIwUUFH
+ QkRWakxpNE1uazJNR3lQUUZVIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJp
+ ZCI6IlYwSVpFbEVsSndBRHpHTkUiLCJmb29kX2lkIjoiY2hhY28tY2FueW9u
+ LW9yZ2FuaWMtY2FmZS1zZWF0dGxlLTIiLCJtdXNpY19pZCI6IjJadjdRUldG
+ bmJRa3RxbDY4WkxZMGUiLCJtdXNpY190eXBlIjoiYWxidW0ifV19
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:02 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:02 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '284'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9Q","Vz0KO4-RRwADbn9d","Vz0KQY-RRwADboEq"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:03 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:02 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '219'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f","suggestion":{"id":"Vz0KO4-RRwADbn9f","food_id":"cactus-restaurants-seattle-2","music_id":"20OmjCaPoZZg3hQ9iOKmrq","music_type":"album"}}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:03 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:03 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:03 GMT
+- request:
+ method: post
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: UTF-8
+ string: '{"suggestion":"Vz0KNY-RRwADbn3d"}'
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 201
+ message: Created
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:03 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - text/html;charset=utf-8
+ X-Xss-Protection:
+ - 1; mode=block
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ Content-Length:
+ - '0'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:04 GMT
+- request:
+ method: delete
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: UTF-8
+ string: '{"suggestion":"Vz0KNY-RRwADbn3d"}'
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 204
+ message: No Content
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:03 GMT
+ Content-Length:
+ - '0'
+ Connection:
+ - keep-alive
+ X-Content-Type-Options:
+ - nosniff
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: ''
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:04 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:56:05 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:56:05 GMT
+recorded_with: VCR 3.0.3
diff --git a/test/cassettes/TunesTakeoutWrapper/API/returns_twenty_pairing_suggestions.yml b/test/cassettes/TunesTakeoutWrapper/API/returns_twenty_pairing_suggestions.yml
new file mode 100644
index 0000000..6c41810
--- /dev/null
+++ b/test/cassettes/TunesTakeoutWrapper/API/returns_twenty_pairing_suggestions.yml
@@ -0,0 +1,207 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?query=avocado
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:36 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '2514'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu
+ Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT1hdm9jYWRvXHUwMDI2
+ bGltaXQ9MjBcdTAwMjZzZWVkPWF2b2NhZG8iLCJzdWdnZXN0aW9ucyI6W3si
+ aWQiOiJWMElaRWxFbEp3QUR6R00wIiwiZm9vZF9pZCI6ImhvbWVncm93bi1z
+ ZWF0dGxlLTMiLCJtdXNpY19pZCI6IjNRcGgxRFB6RU9zamVDMW1DQ24zSzgi
+ LCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdN
+ MSIsImZvb2RfaWQiOiJlbC1jYW1pw7NuLXNlYXR0bGUtNiIsIm11c2ljX2lk
+ IjoiNDQxUTdtYjJRYmdZTklDNDVoOTdOciIsIm11c2ljX3R5cGUiOiJ0cmFj
+ ayJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R00yIiwiZm9vZF9pZCI6InBsdW0t
+ dmVnYW4tYmlzdHJvLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFiWkFKMnpPRERQ
+ ZmFaVnRZMTMwV0ciLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJ
+ WkVsRWxKd0FEekdNMyIsImZvb2RfaWQiOiJtb21pamktc2VhdHRsZSIsIm11
+ c2ljX2lkIjoiMXl1Vkd5bk5OcGJwek16V0M3WFNkZCIsIm11c2ljX3R5cGUi
+ OiJhbGJ1bSJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R000IiwiZm9vZF9pZCI6
+ Im5vLWJvbmVzLWJlYWNoLWNsdWItc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIz
+ SEdVWXNSWDVkSGxVeE1EY2dyOUlKIiwibXVzaWNfdHlwZSI6InRyYWNrIn0s
+ eyJpZCI6IlZ6ODNDdkxXN3dBRHBNQ2EiLCJmb29kX2lkIjoiZ3JlYXQtbnct
+ c291cC1zZWF0dGxlIiwibXVzaWNfaWQiOiI0RU5wMXdldVpLVGlNaXJTU3pL
+ WkFzIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTTUiLCJmb29kX2lkIjoiYmVhY29uLWF2ZS1zYW5kd2ljaGVzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjEzd01mN21rdHVXY3Zxb1c1VFl3bXIiLCJtdXNp
+ Y190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdNNiIsImZv
+ b2RfaWQiOiJvZGRmZWxsb3dzLWNhZmUtYW5kLWJhci1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxYllxQ2p5b1g0NTZZT3NDNU1oaU5DIiwibXVzaWNfdHlwZSI6
+ InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTciLCJmb29kX2lkIjoi
+ Y2FmZS15dW1tLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMG82ZzJDZFpPdjlw
+ ZzZybjdWdkJxQyIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsiaWQiOiJWMEla
+ RWxFbEp3QUR6R004IiwiZm9vZF9pZCI6InNlYXR0bGUtc2FsYWRzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjNIb2lCdXA3QzU1cmxJUnVZQzlObnQiLCJtdXNp
+ Y190eXBlIjoidHJhY2sifSx7ImlkIjoiVnowVWRRak5xQUFEQmJfQiIsImZv
+ b2RfaWQiOiJzZcOxb3ItbW9vc2UtY2Fmw6ktc2VhdHRsZS0yIiwibXVzaWNf
+ aWQiOiIwbjVUcGlWN3NsWjc0eElKTVRNZFI4IiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTkiLCJmb29kX2lkIjoic2hp
+ a3Utc3VzaGktc2VhdHRsZSIsIm11c2ljX2lkIjoiMWtUNGxLUlV3VGJsQlVV
+ b1h0ZjB0ZCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWejAtZGdq
+ TnFBQURCYzAxIiwiZm9vZF9pZCI6ImFtZXJpY2FuYS1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxMXBhUmp6cFR0eWd0REwwM2JTQjUwIiwibXVzaWNfdHlwZSI6
+ ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTS0iLCJmb29kX2lkIjoi
+ Z2xvcy1zZWF0dGxlIiwibXVzaWNfaWQiOiIyc2duSXdaUU5YaTlOTnc4blBs
+ MU5aIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTV8iLCJmb29kX2lkIjoic3VzaGktbWFraS1zZWF0dGxlIiwibXVzaWNf
+ aWQiOiIxcjBDREl1Z0NmeEppZThkVmpFSU9VIiwibXVzaWNfdHlwZSI6ImFs
+ YnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkEiLCJmb29kX2lkIjoibWFu
+ ZWtpLXNlYXR0bGUiLCJtdXNpY19pZCI6IjJnZWJUU3llVVkwMDlaajFuODNl
+ WW8iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJWkVsRWxKd0FE
+ ekdOQiIsImZvb2RfaWQiOiJob21lZ3Jvd24tc2VhdHRsZS01IiwibXVzaWNf
+ aWQiOiIzSTM3QWRLRmlWS0xtcUtjZ2lXQ1REIiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkMiLCJmb29kX2lkIjoibmlq
+ by1zdXNoaS1iYXItYW5kLWdyaWxsLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFZ
+ MnBaTTVJakp0aEZ2TDVGVkRBMG4iLCJtdXNpY190eXBlIjoiYXJ0aXN0In0s
+ eyJpZCI6IlYwSVpFbEVsSndBRHpHTkQiLCJmb29kX2lkIjoiaS1sb3ZlLXN1
+ c2hpLW9uLWxha2UtdW5pb24tc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIwUUFH
+ QkRWakxpNE1uazJNR3lQUUZVIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJp
+ ZCI6IlYwSVpFbEVsSndBRHpHTkUiLCJmb29kX2lkIjoiY2hhY28tY2FueW9u
+ LW9yZ2FuaWMtY2FmZS1zZWF0dGxlLTIiLCJtdXNpY19pZCI6IjJadjdRUldG
+ bmJRa3RxbDY4WkxZMGUiLCJtdXNpY190eXBlIjoiYWxidW0ifV19
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:37 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:36 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '284'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9Q","Vz0KO4-RRwADbn9d","Vz0KQY-RRwADboEq"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:37 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:37 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '219'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f","suggestion":{"id":"Vz0KO4-RRwADbn9f","food_id":"cactus-restaurants-seattle-2","music_id":"20OmjCaPoZZg3hQ9iOKmrq","music_type":"album"}}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:38 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:37 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:38 GMT
+recorded_with: VCR 3.0.3
diff --git a/test/cassettes/TunesTakeoutWrapper/API/will_return_a_list_of_top_favorites.yml b/test/cassettes/TunesTakeoutWrapper/API/will_return_a_list_of_top_favorites.yml
new file mode 100644
index 0000000..ed4b3a0
--- /dev/null
+++ b/test/cassettes/TunesTakeoutWrapper/API/will_return_a_list_of_top_favorites.yml
@@ -0,0 +1,207 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?query=avocado
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:42 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '2514'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu
+ Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT1hdm9jYWRvXHUwMDI2
+ bGltaXQ9MjBcdTAwMjZzZWVkPWF2b2NhZG8iLCJzdWdnZXN0aW9ucyI6W3si
+ aWQiOiJWMElaRWxFbEp3QUR6R00wIiwiZm9vZF9pZCI6ImhvbWVncm93bi1z
+ ZWF0dGxlLTMiLCJtdXNpY19pZCI6IjNRcGgxRFB6RU9zamVDMW1DQ24zSzgi
+ LCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdN
+ MSIsImZvb2RfaWQiOiJlbC1jYW1pw7NuLXNlYXR0bGUtNiIsIm11c2ljX2lk
+ IjoiNDQxUTdtYjJRYmdZTklDNDVoOTdOciIsIm11c2ljX3R5cGUiOiJ0cmFj
+ ayJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R00yIiwiZm9vZF9pZCI6InBsdW0t
+ dmVnYW4tYmlzdHJvLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFiWkFKMnpPRERQ
+ ZmFaVnRZMTMwV0ciLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJ
+ WkVsRWxKd0FEekdNMyIsImZvb2RfaWQiOiJtb21pamktc2VhdHRsZSIsIm11
+ c2ljX2lkIjoiMXl1Vkd5bk5OcGJwek16V0M3WFNkZCIsIm11c2ljX3R5cGUi
+ OiJhbGJ1bSJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R000IiwiZm9vZF9pZCI6
+ Im5vLWJvbmVzLWJlYWNoLWNsdWItc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIz
+ SEdVWXNSWDVkSGxVeE1EY2dyOUlKIiwibXVzaWNfdHlwZSI6InRyYWNrIn0s
+ eyJpZCI6IlZ6ODNDdkxXN3dBRHBNQ2EiLCJmb29kX2lkIjoiZ3JlYXQtbnct
+ c291cC1zZWF0dGxlIiwibXVzaWNfaWQiOiI0RU5wMXdldVpLVGlNaXJTU3pL
+ WkFzIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTTUiLCJmb29kX2lkIjoiYmVhY29uLWF2ZS1zYW5kd2ljaGVzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjEzd01mN21rdHVXY3Zxb1c1VFl3bXIiLCJtdXNp
+ Y190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdNNiIsImZv
+ b2RfaWQiOiJvZGRmZWxsb3dzLWNhZmUtYW5kLWJhci1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxYllxQ2p5b1g0NTZZT3NDNU1oaU5DIiwibXVzaWNfdHlwZSI6
+ InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTciLCJmb29kX2lkIjoi
+ Y2FmZS15dW1tLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMG82ZzJDZFpPdjlw
+ ZzZybjdWdkJxQyIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsiaWQiOiJWMEla
+ RWxFbEp3QUR6R004IiwiZm9vZF9pZCI6InNlYXR0bGUtc2FsYWRzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjNIb2lCdXA3QzU1cmxJUnVZQzlObnQiLCJtdXNp
+ Y190eXBlIjoidHJhY2sifSx7ImlkIjoiVnowVWRRak5xQUFEQmJfQiIsImZv
+ b2RfaWQiOiJzZcOxb3ItbW9vc2UtY2Fmw6ktc2VhdHRsZS0yIiwibXVzaWNf
+ aWQiOiIwbjVUcGlWN3NsWjc0eElKTVRNZFI4IiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTkiLCJmb29kX2lkIjoic2hp
+ a3Utc3VzaGktc2VhdHRsZSIsIm11c2ljX2lkIjoiMWtUNGxLUlV3VGJsQlVV
+ b1h0ZjB0ZCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWejAtZGdq
+ TnFBQURCYzAxIiwiZm9vZF9pZCI6ImFtZXJpY2FuYS1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxMXBhUmp6cFR0eWd0REwwM2JTQjUwIiwibXVzaWNfdHlwZSI6
+ ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTS0iLCJmb29kX2lkIjoi
+ Z2xvcy1zZWF0dGxlIiwibXVzaWNfaWQiOiIyc2duSXdaUU5YaTlOTnc4blBs
+ MU5aIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTV8iLCJmb29kX2lkIjoic3VzaGktbWFraS1zZWF0dGxlIiwibXVzaWNf
+ aWQiOiIxcjBDREl1Z0NmeEppZThkVmpFSU9VIiwibXVzaWNfdHlwZSI6ImFs
+ YnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkEiLCJmb29kX2lkIjoibWFu
+ ZWtpLXNlYXR0bGUiLCJtdXNpY19pZCI6IjJnZWJUU3llVVkwMDlaajFuODNl
+ WW8iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJWkVsRWxKd0FE
+ ekdOQiIsImZvb2RfaWQiOiJob21lZ3Jvd24tc2VhdHRsZS01IiwibXVzaWNf
+ aWQiOiIzSTM3QWRLRmlWS0xtcUtjZ2lXQ1REIiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkMiLCJmb29kX2lkIjoibmlq
+ by1zdXNoaS1iYXItYW5kLWdyaWxsLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFZ
+ MnBaTTVJakp0aEZ2TDVGVkRBMG4iLCJtdXNpY190eXBlIjoiYXJ0aXN0In0s
+ eyJpZCI6IlYwSVpFbEVsSndBRHpHTkQiLCJmb29kX2lkIjoiaS1sb3ZlLXN1
+ c2hpLW9uLWxha2UtdW5pb24tc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIwUUFH
+ QkRWakxpNE1uazJNR3lQUUZVIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJp
+ ZCI6IlYwSVpFbEVsSndBRHpHTkUiLCJmb29kX2lkIjoiY2hhY28tY2FueW9u
+ LW9yZ2FuaWMtY2FmZS1zZWF0dGxlLTIiLCJtdXNpY19pZCI6IjJadjdRUldG
+ bmJRa3RxbDY4WkxZMGUiLCJtdXNpY190eXBlIjoiYWxidW0ifV19
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:43 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:43 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '284'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9Q","Vz0KO4-RRwADbn9d","Vz0KQY-RRwADboEq"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:43 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:43 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '219'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f","suggestion":{"id":"Vz0KO4-RRwADbn9f","food_id":"cactus-restaurants-seattle-2","music_id":"20OmjCaPoZZg3hQ9iOKmrq","music_type":"album"}}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:44 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:43 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:44 GMT
+recorded_with: VCR 3.0.3
diff --git a/test/cassettes/TunesTakeoutWrapper/API/will_return_favorites_for_a_given_user_id.yml b/test/cassettes/TunesTakeoutWrapper/API/will_return_favorites_for_a_given_user_id.yml
new file mode 100644
index 0000000..b5f911b
--- /dev/null
+++ b/test/cassettes/TunesTakeoutWrapper/API/will_return_favorites_for_a_given_user_id.yml
@@ -0,0 +1,207 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?query=avocado
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:30 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '2514'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: ASCII-8BIT
+ string: !binary |-
+ eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu
+ Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT1hdm9jYWRvXHUwMDI2
+ bGltaXQ9MjBcdTAwMjZzZWVkPWF2b2NhZG8iLCJzdWdnZXN0aW9ucyI6W3si
+ aWQiOiJWMElaRWxFbEp3QUR6R00wIiwiZm9vZF9pZCI6ImhvbWVncm93bi1z
+ ZWF0dGxlLTMiLCJtdXNpY19pZCI6IjNRcGgxRFB6RU9zamVDMW1DQ24zSzgi
+ LCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdN
+ MSIsImZvb2RfaWQiOiJlbC1jYW1pw7NuLXNlYXR0bGUtNiIsIm11c2ljX2lk
+ IjoiNDQxUTdtYjJRYmdZTklDNDVoOTdOciIsIm11c2ljX3R5cGUiOiJ0cmFj
+ ayJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R00yIiwiZm9vZF9pZCI6InBsdW0t
+ dmVnYW4tYmlzdHJvLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFiWkFKMnpPRERQ
+ ZmFaVnRZMTMwV0ciLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJ
+ WkVsRWxKd0FEekdNMyIsImZvb2RfaWQiOiJtb21pamktc2VhdHRsZSIsIm11
+ c2ljX2lkIjoiMXl1Vkd5bk5OcGJwek16V0M3WFNkZCIsIm11c2ljX3R5cGUi
+ OiJhbGJ1bSJ9LHsiaWQiOiJWMElaRWxFbEp3QUR6R000IiwiZm9vZF9pZCI6
+ Im5vLWJvbmVzLWJlYWNoLWNsdWItc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIz
+ SEdVWXNSWDVkSGxVeE1EY2dyOUlKIiwibXVzaWNfdHlwZSI6InRyYWNrIn0s
+ eyJpZCI6IlZ6ODNDdkxXN3dBRHBNQ2EiLCJmb29kX2lkIjoiZ3JlYXQtbnct
+ c291cC1zZWF0dGxlIiwibXVzaWNfaWQiOiI0RU5wMXdldVpLVGlNaXJTU3pL
+ WkFzIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTTUiLCJmb29kX2lkIjoiYmVhY29uLWF2ZS1zYW5kd2ljaGVzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjEzd01mN21rdHVXY3Zxb1c1VFl3bXIiLCJtdXNp
+ Y190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBJWkVsRWxKd0FEekdNNiIsImZv
+ b2RfaWQiOiJvZGRmZWxsb3dzLWNhZmUtYW5kLWJhci1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxYllxQ2p5b1g0NTZZT3NDNU1oaU5DIiwibXVzaWNfdHlwZSI6
+ InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTciLCJmb29kX2lkIjoi
+ Y2FmZS15dW1tLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMG82ZzJDZFpPdjlw
+ ZzZybjdWdkJxQyIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsiaWQiOiJWMEla
+ RWxFbEp3QUR6R004IiwiZm9vZF9pZCI6InNlYXR0bGUtc2FsYWRzLXNlYXR0
+ bGUiLCJtdXNpY19pZCI6IjNIb2lCdXA3QzU1cmxJUnVZQzlObnQiLCJtdXNp
+ Y190eXBlIjoidHJhY2sifSx7ImlkIjoiVnowVWRRak5xQUFEQmJfQiIsImZv
+ b2RfaWQiOiJzZcOxb3ItbW9vc2UtY2Fmw6ktc2VhdHRsZS0yIiwibXVzaWNf
+ aWQiOiIwbjVUcGlWN3NsWjc0eElKTVRNZFI4IiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTTkiLCJmb29kX2lkIjoic2hp
+ a3Utc3VzaGktc2VhdHRsZSIsIm11c2ljX2lkIjoiMWtUNGxLUlV3VGJsQlVV
+ b1h0ZjB0ZCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWejAtZGdq
+ TnFBQURCYzAxIiwiZm9vZF9pZCI6ImFtZXJpY2FuYS1zZWF0dGxlIiwibXVz
+ aWNfaWQiOiIxMXBhUmp6cFR0eWd0REwwM2JTQjUwIiwibXVzaWNfdHlwZSI6
+ ImFsYnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTS0iLCJmb29kX2lkIjoi
+ Z2xvcy1zZWF0dGxlIiwibXVzaWNfaWQiOiIyc2duSXdaUU5YaTlOTnc4blBs
+ MU5aIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSVpFbEVsSndB
+ RHpHTV8iLCJmb29kX2lkIjoic3VzaGktbWFraS1zZWF0dGxlIiwibXVzaWNf
+ aWQiOiIxcjBDREl1Z0NmeEppZThkVmpFSU9VIiwibXVzaWNfdHlwZSI6ImFs
+ YnVtIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkEiLCJmb29kX2lkIjoibWFu
+ ZWtpLXNlYXR0bGUiLCJtdXNpY19pZCI6IjJnZWJUU3llVVkwMDlaajFuODNl
+ WW8iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBJWkVsRWxKd0FE
+ ekdOQiIsImZvb2RfaWQiOiJob21lZ3Jvd24tc2VhdHRsZS01IiwibXVzaWNf
+ aWQiOiIzSTM3QWRLRmlWS0xtcUtjZ2lXQ1REIiwibXVzaWNfdHlwZSI6InRy
+ YWNrIn0seyJpZCI6IlYwSVpFbEVsSndBRHpHTkMiLCJmb29kX2lkIjoibmlq
+ by1zdXNoaS1iYXItYW5kLWdyaWxsLXNlYXR0bGUiLCJtdXNpY19pZCI6IjFZ
+ MnBaTTVJakp0aEZ2TDVGVkRBMG4iLCJtdXNpY190eXBlIjoiYXJ0aXN0In0s
+ eyJpZCI6IlYwSVpFbEVsSndBRHpHTkQiLCJmb29kX2lkIjoiaS1sb3ZlLXN1
+ c2hpLW9uLWxha2UtdW5pb24tc2VhdHRsZS0yIiwibXVzaWNfaWQiOiIwUUFH
+ QkRWakxpNE1uazJNR3lQUUZVIiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJp
+ ZCI6IlYwSVpFbEVsSndBRHpHTkUiLCJmb29kX2lkIjoiY2hhY28tY2FueW9u
+ LW9yZ2FuaWMtY2FmZS1zZWF0dGxlLTIiLCJtdXNpY19pZCI6IjJadjdRUldG
+ bmJRa3RxbDY4WkxZMGUiLCJtdXNpY190eXBlIjoiYWxidW0ifV19
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:30 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:30 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '284'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=10","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9Q","Vz0KO4-RRwADbn9d","Vz0KQY-RRwADboEq"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:30 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:31 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '219'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9f","suggestion":{"id":"Vz0KO4-RRwADbn9f","food_id":"cactus-restaurants-seattle-2","music_id":"20OmjCaPoZZg3hQ9iOKmrq","music_type":"album"}}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:31 GMT
+- request:
+ method: get
+ uri: https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - Cowboy
+ Date:
+ - Mon, 23 May 2016 00:55:31 GMT
+ Connection:
+ - keep-alive
+ Content-Type:
+ - application/json
+ X-Content-Type-Options:
+ - nosniff
+ Content-Length:
+ - '286'
+ Via:
+ - 1.1 vegur
+ body:
+ encoding: UTF-8
+ string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/jadieladie/favorites","suggestions":["Vz0KQY-RRwADboEQ","Vz83CvLW7wADpMCa","V0IZElElJwADzGM0","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboFP","V0IZElElJwADzGM_","V0DZcD2OhAADuST8","V0Ij-1ElJwADzGZQ","Vz92VPLW7wADpNDB"]}'
+ http_version:
+ recorded_at: Mon, 23 May 2016 00:55:31 GMT
+recorded_with: VCR 3.0.3
diff --git a/test/controllers/home_controller_test.rb b/test/controllers/home_controller_test.rb
new file mode 100644
index 0000000..730478d
--- /dev/null
+++ b/test/controllers/home_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class HomeControllerTest < ActionController::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb
new file mode 100644
index 0000000..d30ebc3
--- /dev/null
+++ b/test/controllers/sessions_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class SessionsControllerTest < ActionController::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/suggestions_controller_test.rb b/test/controllers/suggestions_controller_test.rb
new file mode 100644
index 0000000..f4587a5
--- /dev/null
+++ b/test/controllers/suggestions_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class SuggestionsControllerTest < ActionController::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
new file mode 100644
index 0000000..d23f182
--- /dev/null
+++ b/test/controllers/users_controller_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class UsersControllerTest < ActionController::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/fixtures/foods.yml b/test/fixtures/foods.yml
new file mode 100644
index 0000000..937a0c0
--- /dev/null
+++ b/test/fixtures/foods.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+# This model initially had no columns defined. If you add columns to the
+# model remove the '{}' from the fixture names and add the columns immediately
+# below each fixture, per the syntax in the comments below
+#
+one: {}
+# column: value
+#
+two: {}
+# column: value
diff --git a/test/fixtures/musics.yml b/test/fixtures/musics.yml
new file mode 100644
index 0000000..937a0c0
--- /dev/null
+++ b/test/fixtures/musics.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+# This model initially had no columns defined. If you add columns to the
+# model remove the '{}' from the fixture names and add the columns immediately
+# below each fixture, per the syntax in the comments below
+#
+one: {}
+# column: value
+#
+two: {}
+# column: value
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
new file mode 100644
index 0000000..e237959
--- /dev/null
+++ b/test/fixtures/users.yml
@@ -0,0 +1,11 @@
+# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
+
+# This model initially had no columns defined. If you add columns to the
+# model remove the '{}' from the fixture names and add the columns immediately
+# below each fixture, per the syntax in the comments below
+#
+known_user:
+ provider: spotify
+ display_name: known user
+ uid: known_user
+ photo_url: http://i.imgur.com/2D35e.jpg
\ No newline at end of file
diff --git a/test/models/food_test.rb b/test/models/food_test.rb
new file mode 100644
index 0000000..8ad7dff
--- /dev/null
+++ b/test/models/food_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class FoodTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/music_test.rb b/test/models/music_test.rb
new file mode 100644
index 0000000..c5c6737
--- /dev/null
+++ b/test/models/music_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class MusicTest < ActiveSupport::TestCase
+ # test "the truth" do
+ # assert true
+ # end
+end
diff --git a/test/models/user_test.rb b/test/models/user_test.rb
new file mode 100644
index 0000000..b3a6298
--- /dev/null
+++ b/test/models/user_test.rb
@@ -0,0 +1,48 @@
+require 'test_helper'
+
+class UserTest < ActiveSupport::TestCase
+
+ def setup
+ @known = { "provider" => "spotify", "info" => { "id" => "known_user", "display_name" => "known user" , "images" => ["url" => "http://i.imgur.com/2D35e.jpg"]}}
+ @unknown = { "provider" => "spotify", "info" => { "id" => "unknown_user", "display_name" => "unknown user" , "images" => ["url" => "http://i.imgur.com/2D35e.jpg"]} }
+ @unknown_with_uid = OmniAuth.config.mock_auth[:spotify_uid]
+ end
+
+ test "creates new user with oauth spotify hash of unknown user" do
+ assert_difference 'User.count', 1 do
+ @user = User.find_or_create_from_omniauth @unknown
+ end
+ end
+
+ test "finds an existing user given an oauth spotify hash" do
+ assert_equal users(:known_user), User.find_or_create_from_omniauth(@known)
+ end
+
+ test "uses oauth data to set data for new users" do
+ user = User.find_or_create_from_omniauth @unknown
+
+ assert_equal @unknown['provider'], user.provider
+ assert_equal @unknown['info']['id'], user.uid
+ assert_equal @unknown['info']['display_name'], user.display_name
+ end
+
+ test "validation: provider must be spotify" do
+ user = User.new
+ user.provider = "monkey face"
+ assert_not user.valid?
+ assert user.errors.keys.include?(:provider), "provider is not in the errors hash"
+ end
+
+
+ test "validation: provider must be present" do
+ user = User.new
+ assert_not user.valid?
+ assert user.errors.keys.include?(:provider), "provider is not the errors hash"
+ end
+
+ test "validation: uid must be present" do
+ user = User.new
+ assert_not user.valid?
+ assert user.errors.keys.include?(:uid), "uid is not in the errors hash"
+ end
+end
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 92e39b2..84b335e 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -1,10 +1,32 @@
+require 'simplecov'
+SimpleCov.start 'rails'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
require 'rails/test_help'
+require 'minitest/spec'
+require "minispec-metadata"
+require 'vcr'
+require 'minitest-vcr'
+require 'webmock/minitest'
+require "minitest/reporters"
+
+
+
+VCR.configure do |c|
+ c.cassette_library_dir = 'test/cassettes'
+ c.hook_into :webmock
+end
+
+Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new
+MinitestVcr::Spec.configure!
+
class ActiveSupport::TestCase
- # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
fixtures :all
- # Add more helper methods to be used by all tests here...
-end
+ def setup
+ OmniAuth.config.test_mode = true
+ OmniAuth.config.mock_auth[:spotify] = OmniAuth::AuthHash.new({:provider => 'spotify', :uid => 'jadieladie', info: { name: "Jade Vance"}})
+ end
+
+end
\ No newline at end of file
diff --git a/test/tunes_takeout_wrapper_test.rb b/test/tunes_takeout_wrapper_test.rb
new file mode 100644
index 0000000..397669f
--- /dev/null
+++ b/test/tunes_takeout_wrapper_test.rb
@@ -0,0 +1,65 @@
+
+require 'test_helper'
+
+class TunesTakeoutWrapperTest < ActiveSupport::TestCase
+
+ describe "TunesTakeoutWrapper" do
+ it "Accesses the correct API URL and version" do
+ assert_equal "https://tunes-takeout-api.herokuapp.com/v1/", TunesTakeoutWrapper::BASE_URL
+ end
+
+ describe "API" , :vcr do
+ before do
+ @avocado = TunesTakeoutWrapper.search("avocado")
+ @top_favorites = TunesTakeoutWrapper.top_favorites
+ @single_favorite = TunesTakeoutWrapper.each_favorite("Vz0KO4-RRwADbn9f")
+ @favorite_id_array = TunesTakeoutWrapper.get_favorites("jadieladie")
+ end
+
+ it "returns twenty pairing suggestions", :vcr do
+ choices = @avocado.suggestions.count
+ assert_equal choices, 20
+ end
+
+ it "will return a list of top favorites", :vcr do
+ assert_equal @top_favorites.class, TunesTakeoutWrapper
+ refute_nil @top_favorites
+ end
+
+ it "will return favorites for a given user id", :vcr do
+ assert_equal @favorite_id_array.class, Array
+ assert_equal @favorite_id_array.length, 10
+ refute_nil @favorite_id_array
+ end
+
+ it "can access a single favorite by url", :vcr do
+ assert_equal @single_favorite["id"], "Vz0KO4-RRwADbn9f"
+ refute_nil @single_favorite
+ end
+
+ it "can favorite a suggestion" , :vcr do
+ @original_count = @favorite_id_array.count
+ TunesTakeoutWrapper.favorite('jadieladie', "Vz92VPLW7wADpNDB")
+ @new_count = TunesTakeoutWrapper.get_favorites("jadieladie").count
+ assert_equal (@original_count), @new_count
+ end
+
+ it "can unfavorite a suggestion", :vcr do
+ TunesTakeoutWrapper.favorite('jadieladie', "Vz0KNY-RRwADbn3d")
+ @original_count = @favorite_id_array.count
+ TunesTakeoutWrapper.unfavorite('jadieladie', "Vz0KNY-RRwADbn3d")
+ @new_count = TunesTakeoutWrapper.get_favorites("jadieladie").count
+ assert_equal (@original_count), @new_count
+ end
+ end
+ end
+end
+
+
+# I really wanted to do a test on response codes but it was pissy about string vs json
+# putting a note here to ask about it on Monday
+
+# it "can't favorite a pairing already favorited", :vcr do
+# test = @favorite_suggestion
+# assert_equal test.response, #
+# end