From 1e7eace9b2c584300bc85a2d8ec93ff6d3e18966 Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Mon, 16 May 2016 15:41:49 -0700 Subject: [PATCH 01/13] Boilerplate. Gems install and model file creation. --- Gemfile | 6 ++++-- Gemfile.lock | 42 +++++++++++++++++++++++++++++++++++++++++- app/models/food.rb | 0 app/models/music.rb | 0 app/models/user.rb | 0 5 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 app/models/food.rb create mode 100644 app/models/music.rb create mode 100644 app/models/user.rb diff --git a/Gemfile b/Gemfile index 288bb87..54bcb12 100644 --- a/Gemfile +++ b/Gemfile @@ -1,5 +1,5 @@ source 'https://rubygems.org' -ruby '2.3.1' +ruby '2.3.0' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '4.2.6' @@ -23,6 +23,9 @@ gem 'sdoc', '~> 0.4.0', group: :doc # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' +gem 'yelp', require: 'yelp' +gem 'rspotify' +gem 'httparty' # Use Unicorn as the app server # gem 'unicorn' @@ -42,4 +45,3 @@ group :development do # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' end - diff --git a/Gemfile.lock b/Gemfile.lock index 6ff0f39..a18a678 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,8 +52,16 @@ GEM debug_inspector (0.0.2) 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) + 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,6 +71,7 @@ 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) @@ -73,8 +82,23 @@ GEM mini_portile2 (2.0.0) minitest (5.8.4) 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.4.0) + oauth2 (~> 1.0) + omniauth (~> 1.2) pg (0.18.4) rack (1.6.4) rack-test (0.6.3) @@ -106,6 +130,11 @@ 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) sass (3.4.22) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -116,6 +145,7 @@ GEM sdoc (0.4.1) json (~> 1.7, >= 1.7.7) rdoc (~> 4.0) + simple_oauth (0.3.1) spring (1.7.1) sprockets (3.6.0) concurrent-ruby (~> 1.0) @@ -136,6 +166,10 @@ GEM binding_of_caller (>= 0.7.2) railties (>= 4.0) sprockets-rails (>= 2.0, < 4.0) + yelp (2.1.2) + faraday (~> 0.8, >= 0.8.0) + faraday_middleware (~> 0.8, >= 0.8.0) + simple_oauth (~> 0.3.1) PLATFORMS ruby @@ -143,15 +177,21 @@ PLATFORMS DEPENDENCIES byebug coffee-rails (~> 4.1.0) + httparty jbuilder (~> 2.0) jquery-rails pg (~> 0.15) rails (= 4.2.6) + rspotify sass-rails (~> 5.0) sdoc (~> 0.4.0) spring uglifier (>= 1.3.0) web-console (~> 2.0) + yelp + +RUBY VERSION + ruby 2.3.0p0 BUNDLED WITH - 1.12.3 + 1.12.4 diff --git a/app/models/food.rb b/app/models/food.rb new file mode 100644 index 0000000..e69de29 diff --git a/app/models/music.rb b/app/models/music.rb new file mode 100644 index 0000000..e69de29 diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..e69de29 From 808f2de5be4ab0fdd96b791c7b327fd41f3fc70a Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Thu, 19 May 2016 15:56:12 -0700 Subject: [PATCH 02/13] Index and search working and displaying suggestions. --- .gitignore | 1 + Gemfile | 9 +++ Gemfile.lock | 50 +++++++++---- app/assets/javascripts/sessions.coffee | 3 + app/assets/javascripts/suggestions.coffee | 3 + app/assets/stylesheets/sessions.scss | 3 + app/assets/stylesheets/suggestions.scss | 3 + app/controllers/application_controller.rb | 8 ++ app/controllers/sessions_controller.rb | 26 +++++++ app/controllers/suggestions_controller.rb | 73 +++++++++++++++++++ app/helpers/sessions_helper.rb | 2 + app/helpers/suggestions_helper.rb | 2 + app/models/food.rb | 32 ++++++++ app/models/music.rb | 40 ++++++++++ app/models/user.rb | 35 +++++++++ app/views/layouts/application.html.erb | 13 +++- .../suggestions/display_results.html.erb | 17 +++++ app/views/suggestions/index.html.erb | 19 +++++ app/views/suggestions/search_by_term.html.erb | 7 ++ config/application.rb | 2 +- config/initializers/omniauth.rb | 7 ++ config/initializers/yelp_client.rb | 11 +++ config/routes.rb | 10 ++- db/migrate/20160517224119_create_users.rb | 8 ++ db/migrate/20160517225432_omni_auth_user.rb | 6 ++ db/schema.rb | 26 +++++++ lib/TunesTakeoutWrapper.rb | 19 +++++ omniauth.rb | 7 ++ test/controllers/sessions_controller_test.rb | 7 ++ .../suggestions_controller_test.rb | 7 ++ test/fixtures/users.yml | 11 +++ test/models/user_test.rb | 7 ++ 32 files changed, 458 insertions(+), 16 deletions(-) create mode 100644 app/assets/javascripts/sessions.coffee create mode 100644 app/assets/javascripts/suggestions.coffee create mode 100644 app/assets/stylesheets/sessions.scss create mode 100644 app/assets/stylesheets/suggestions.scss create mode 100644 app/controllers/sessions_controller.rb create mode 100644 app/controllers/suggestions_controller.rb create mode 100644 app/helpers/sessions_helper.rb create mode 100644 app/helpers/suggestions_helper.rb create mode 100644 app/views/suggestions/display_results.html.erb create mode 100644 app/views/suggestions/index.html.erb create mode 100644 app/views/suggestions/search_by_term.html.erb create mode 100644 config/initializers/omniauth.rb create mode 100644 config/initializers/yelp_client.rb create mode 100644 db/migrate/20160517224119_create_users.rb create mode 100644 db/migrate/20160517225432_omni_auth_user.rb create mode 100644 db/schema.rb create mode 100644 lib/TunesTakeoutWrapper.rb create mode 100644 omniauth.rb create mode 100644 test/controllers/sessions_controller_test.rb create mode 100644 test/controllers/suggestions_controller_test.rb create mode 100644 test/fixtures/users.yml create mode 100644 test/models/user_test.rb diff --git a/.gitignore b/.gitignore index 03f3ce7..fd9e9ba 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ # Used by dotenv library to load environment variables. # .env +/.env ## Specific to RubyMotion: .dat* diff --git a/Gemfile b/Gemfile index 54bcb12..9bf9073 100644 --- a/Gemfile +++ b/Gemfile @@ -25,7 +25,14 @@ gem 'sdoc', '~> 0.4.0', group: :doc # gem 'bcrypt', '~> 3.1.7' gem 'yelp', require: 'yelp' gem 'rspotify' +gem 'omniauth' +gem 'omniauth-spotify' gem 'httparty' +gem 'simplecov', :require => false, :group => :test + + +gem 'omniauth-oauth2', '~> 1.3.1' + # Use Unicorn as the app server # gem 'unicorn' @@ -36,6 +43,8 @@ gem 'httparty' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' + gem 'dotenv-rails' + end group :development do diff --git a/Gemfile.lock b/Gemfile.lock index a18a678..d6ae82e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -40,7 +40,7 @@ GEM binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) - byebug (8.2.5) + byebug (9.0.3) coffee-rails (4.1.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.1.x) @@ -50,6 +50,13 @@ GEM coffee-script-source (1.10.0) concurrent-ruby (1.0.2) debug_inspector (0.0.2) + docile (1.1.5) + domain_name (0.5.20160310) + unf (>= 0.0.5, < 1.0.0) + 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) @@ -59,6 +66,8 @@ GEM globalid (0.3.6) activesupport (>= 4.1.0) hashie (3.4.4) + http-cookie (1.0.2) + domain_name (~> 0.5) httparty (0.13.7) json (~> 1.8) multi_xml (>= 0.5.2) @@ -76,15 +85,13 @@ GEM nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) - mime-types (3.0) - mime-types-data (~> 3.2015) - mime-types-data (3.2016.0221) + mime-types (2.99.1) mini_portile2 (2.0.0) - minitest (5.8.4) + minitest (5.9.0) multi_json (1.12.0) multi_xml (0.5.5) multipart-post (2.0.0) - netrc (0.7.9) + netrc (0.11.0) nokogiri (1.6.7.2) mini_portile2 (~> 2.0.0.rc2) oauth2 (1.1.0) @@ -96,9 +103,11 @@ GEM omniauth (1.3.1) hashie (>= 1.2, < 4) rack (>= 1.0, < 3) - omniauth-oauth2 (1.4.0) + omniauth-oauth2 (1.3.1) oauth2 (~> 1.0) omniauth (~> 1.2) + omniauth-spotify (0.0.9) + omniauth-oauth2 (~> 1.1) pg (0.18.4) rack (1.6.4) rack-test (0.6.3) @@ -130,11 +139,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) + rest-client (1.8.0) + http-cookie (>= 1.0.2, < 2.0) + mime-types (>= 1.16, < 3.0) + netrc (~> 0.7) + rspotify (1.18.0) + omniauth-oauth2 (~> 1.3.1) + rest-client (~> 1.7) sass (3.4.22) sass-rails (5.0.4) railties (>= 4.0.0, < 5.0) @@ -146,6 +157,11 @@ GEM 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) spring (1.7.1) sprockets (3.6.0) concurrent-ruby (~> 1.0) @@ -156,11 +172,14 @@ GEM sprockets (>= 3.0.0) thor (0.19.1) thread_safe (0.3.5) - tilt (2.0.2) + tilt (2.0.4) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (3.0.0) execjs (>= 0.3.0, < 3) + unf (0.1.4) + unf_ext + unf_ext (0.0.7.2) web-console (2.3.0) activemodel (>= 4.0) binding_of_caller (>= 0.7.2) @@ -177,14 +196,19 @@ PLATFORMS DEPENDENCIES byebug coffee-rails (~> 4.1.0) + dotenv-rails httparty jbuilder (~> 2.0) jquery-rails + omniauth + omniauth-oauth2 (~> 1.3.1) + omniauth-spotify pg (~> 0.15) rails (= 4.2.6) rspotify sass-rails (~> 5.0) sdoc (~> 0.4.0) + simplecov spring uglifier (>= 1.3.0) web-console (~> 2.0) 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/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/controllers/application_controller.rb b/app/controllers/application_controller.rb index d83690e..aee5e4a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -2,4 +2,12 @@ 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 + + + def current_user + @user ||= User.find_by(id: session[:user_id]) + end + end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..6b7fc3c --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,26 @@ +class SessionsController < ApplicationController + + def new #why not initialize? + #shows a view with OAuth sign-in link + end + + def create + #accepts OAuth information from Spotify, finds or creates a User account, and sets user_id in session + auth_hash = request.env['omniauth.auth'] #request is a variable that you get + @user = User.find_or_create_from_omniauth(auth_hash) + # user = User.log_in(params[:xemail], params[:password]) + if @user + session[:user_id] = @user.id + redirect_to root_path + else + redirect_to root_path + end + end + + def destroy + #deletes user_id from session + 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..9fbe27a --- /dev/null +++ b/app/controllers/suggestions_controller.rb @@ -0,0 +1,73 @@ +require_relative '../../lib/TunesTakeoutWrapper.rb' +require 'yelp' +require 'httparty' + +class SuggestionsController < ApplicationController + # extend TunesTakeoutWrapper + + def index + #shows top 20 suggestions, ranked by total number of favorites + suggestion_ids = TunesTakeoutWrapper.top["suggestions"] #this should return array of sugg ids + + + @pairings = [] + suggestion_ids.each do |suggestion_id| + + suggestion_object = TunesTakeoutWrapper.find(suggestion_id) + + suggestion = suggestion_object["suggestion"] + + yelp_id = suggestion["food_id"] + spotify_id = suggestion["music_id"] + spotify_type = suggestion["music_type"] + + array = [] + array << Food.find(yelp_id) #first thing in array is yelp + array << Music.find(spotify_id, spotify_type) #second thing is music + + @pairings << array + end + end + + def favorites + #shows all suggestions favorited by the signed-in User + + end + + def search_by_term + #Returns a hash from the TunesTakeoutWrapper + end + + def display_results + results = TunesTakeoutWrapper.search(params[:term]) + suggestions = results["suggestions"] + + + @pairings = [] + suggestions.each do |suggestion| + + yelp_id = suggestion["food_id"] + spotify_id = suggestion["music_id"] + spotify_type = suggestion["music_type"] + + array = [] + array << Food.find(yelp_id) #first thing in array is yelp + array << Music.find(spotify_id, spotify_type) #second thing is music + + @pairings << array + + end + + end + + def favorite + #adds a suggestion into the favorite list for the signed-in User. This requires interaction with the Tunes & Takeout API. + + end + + def unfavorite + #removes a suggestion from the favorite list for the signed-in User. This requires interaction with the Tunes & Takeout API + + end + +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/models/food.rb b/app/models/food.rb index e69de29..8d772f7 100644 --- a/app/models/food.rb +++ b/app/models/food.rb @@ -0,0 +1,32 @@ +# business_id string Yelp-specific ID, which can be used to make calls to the Yelp Business API to retrieve complete details +# name string Name of the business +# url string Yelp URL for this business +# image_url string URL of the photo to display for this business +# phone string Phone number for the business +# rating decimal number Average rating for this business based on Yelp reviews + +require 'httparty' + +class Food + BASE_URL = "https://api.yelp.com/v2" + attr_reader :business_id, :name, :url, :image_url, :phone, :rating + + def initialize(data) + @business_id = data.business.id + @name = data.business.name + @url = data.business.url + @image_url = data.business.image_url + @phone = data.business.phone + @rating = data.business.rating + end + + def self.find(id) + # https://api.yelp.com/v2/search?term=food + #find a business with the passed term +++ NOT TERM, BUT business_id? + #data = HTTParty.get(BASE_URL + "/search?term=#{term}").parsed_response + data = Yelp.client.business(id) + #return an array of instances of business for that term + self.new(data) + end + +end diff --git a/app/models/music.rb b/app/models/music.rb index e69de29..7e2891e 100644 --- a/app/models/music.rb +++ b/app/models/music.rb @@ -0,0 +1,40 @@ +# attribute data type description +# item_id string Spotify-specific ID, which can be used in conjunction with the type to make calls to the Spotify API +# type string Which type of resource this item is. Can be: artist, album, track, playlist +# name string Name of the item +# url string URL for opening this item in a browser-based Spotify player +# image_url string URL of the photo to display for this item + + +require 'rspotify' + +class Music + BASE_URL = "http://" + attr_reader :item_id, :type, :name, :url, :image_url + + def initialize(data) + @item_id = data.id + @type = data.type + @name = data.name + @url = data.external_urls["spotify"] + # @image_url = data.images.first.url #first is widest image + end + + def self.find(id, type) + + if type == "album" + data = RSpotify::Album.find(id) + self.new(data) + elsif type == "track" + data = RSpotify::Track.find(id) + self.new(data) + elsif type == "artist" + data = RSpotify::Artist.find(id) + self.new(data) + end + + end + +end + +# @music.external_urls["spotify"] <= to listen to track! diff --git a/app/models/user.rb b/app/models/user.rb index e69de29..9a37c81 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -0,0 +1,35 @@ +class User < ActiveRecord::Base + #User: A signed-in user account, created via OmniAuth and connected to a Spotify account. + # Validations: + # provider must be a string, must be present, and must equal spotify + # uid must be a string, and must be present + # name, if present, must be a string + validates :uid, :provider, presence: true + + def self.find_or_create_from_omniauth(auth_hash) + # Find or create a user + #user = User.where(uid: auth_hash["uid"]).where(provider: auth_hash["provider"]).first + user = self.find_by(uid: auth_hash["uid"], provider: auth_hash["provider"]) + # user = //something else here// + if !user.nil? + # return user that was found + return user + else + # no user found, do something here + user = User.new + user.uid = auth_hash["uid"] + user.provider = auth_hash["provider"] + # user.name = auth_hash["info"]["name"] + # user.email = auth_hash["info"]["email"] + + if user.save + return user + else + return nil + end + end + end + + + +end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 509d1a2..975c2d0 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -8,7 +8,18 @@ -<%= yield %> +
+ + <%= "Hi #{ current_user.uid }!" if current_user %> + <%= yield %> +
diff --git a/app/views/suggestions/display_results.html.erb b/app/views/suggestions/display_results.html.erb new file mode 100644 index 0000000..d73953a --- /dev/null +++ b/app/views/suggestions/display_results.html.erb @@ -0,0 +1,17 @@ +

Your Results

+ +<% @pairings.each do |pair| %> + +

+ Food: + <%= pair[0].name%> + <%= pair[0].rating%> +

+ +

+ Music: + <%= pair[1].name%> + <%= pair[1].url%> +

+ +<% end %> diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb new file mode 100644 index 0000000..b151c73 --- /dev/null +++ b/app/views/suggestions/index.html.erb @@ -0,0 +1,19 @@ +

Here's the list of top favorited suggestions

+ +<% @pairings.each do |pair| %> + + <%food = pair[0]%> + <%music = pair[1]%> +

+ Food: + <%= link_to food.name, food.url%> + Rating:<%= food.rating%> +

+ +

+ Music: + <%= link_to music.name, music.url%> + <%= %> +

+ +<% end %> diff --git a/app/views/suggestions/search_by_term.html.erb b/app/views/suggestions/search_by_term.html.erb new file mode 100644 index 0000000..c510f22 --- /dev/null +++ b/app/views/suggestions/search_by_term.html.erb @@ -0,0 +1,7 @@ +

Search suggestions by keyword:

+ +<%= form_tag results_path do %> + <%= label_tag :term %> + <%= text_field_tag :term %> + <%= submit_tag %> +<% end %> diff --git a/config/application.rb b/config/application.rb index 9b37a86..90793f2 100644 --- a/config/application.rb +++ b/config/application.rb @@ -6,7 +6,7 @@ # you've limited to :test, :development, or :production. Bundler.require(*Rails.groups) -module TunesTakeout +module CharlesTunesTakeout class Application < Rails::Application # Settings in config/environments/* take precedence over those specified here. # Application configuration should go into files in config/initializers diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 0000000..99a62c9 --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,7 @@ +# Set up OmniAuth to use Client ID and Secret + +# config/initializers/omniauth.rb +Rails.application.config.middleware.use OmniAuth::Builder do + provider :spotify, ENV["SPOTIFY_CLIENT_ID"], ENV["SPOTIFY_CLIENT_SECRET"] # Do not put IDs here directly, + #because when you commit people will be able to see it +end diff --git a/config/initializers/yelp_client.rb b/config/initializers/yelp_client.rb new file mode 100644 index 0000000..d15bf7d --- /dev/null +++ b/config/initializers/yelp_client.rb @@ -0,0 +1,11 @@ +require 'yelp' + +Yelp.client.configure do |config| + config.consumer_key = ENV["YOUR_CONSUMER_KEY"] + config.consumer_secret = ENV["YOUR_CONSUMER_SECRET"] + config.token = ENV["YOUR_TOKEN"] + config.token_secret = ENV["YOUR_TOKEN_SECRET"] +end + +# To use the Business API after you have a client you just need to call #business with a business id# +# client.business('yelp-san-francisco') diff --git a/config/routes.rb b/config/routes.rb index 3f66539..f5d4f94 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,8 +3,16 @@ # See how all your routes lay out with "rake routes". # You can have the root of your site routed with "root" - # root 'welcome#index' + # get "auth/spotify" => 'sessions#new' + get "/auth/:provider/callback" => "sessions#create" + delete "/logout" => "sessions#destroy" + + root 'suggestions#index' + + get 'suggestions/search_by_term' => 'suggestions#search_by_term', as: :search + + post 'suggestions/display_results' => 'suggestions#display_results', as: :results # Example of regular route: # get 'products/:id' => 'catalog#view' diff --git a/db/migrate/20160517224119_create_users.rb b/db/migrate/20160517224119_create_users.rb new file mode 100644 index 0000000..e6f0ee5 --- /dev/null +++ b/db/migrate/20160517224119_create_users.rb @@ -0,0 +1,8 @@ +class CreateUsers < ActiveRecord::Migration + def change + create_table :users do |t| + + t.timestamps null: false + end + end +end diff --git a/db/migrate/20160517225432_omni_auth_user.rb b/db/migrate/20160517225432_omni_auth_user.rb new file mode 100644 index 0000000..d00309d --- /dev/null +++ b/db/migrate/20160517225432_omni_auth_user.rb @@ -0,0 +1,6 @@ +class OmniAuthUser < ActiveRecord::Migration + def change + add_column :users, :uid, :string # for the unique user identifier from the provider + add_column :users, :provider, :string # for the provider name + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 0000000..2bac25b --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,26 @@ +# 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: 20160517225432) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "users", force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "uid" + t.string "provider" + end + +end diff --git a/lib/TunesTakeoutWrapper.rb b/lib/TunesTakeoutWrapper.rb new file mode 100644 index 0000000..f6e5613 --- /dev/null +++ b/lib/TunesTakeoutWrapper.rb @@ -0,0 +1,19 @@ +require 'httparty' + +module TunesTakeoutWrapper + BASE_URL = "https://tunes-takeout-api.herokuapp.com/v1" + + def self.find(id) + #/v1/suggestions/VzoikPLQUk2WS7xp + HTTParty.get(BASE_URL + "/suggestions/" + id).parsed_response + end + + def self.search(term, limit = 20) + HTTParty.get(BASE_URL + "/suggestions/search?query=#{term}&limit=#{limit}").parsed_response + end + + def self.top + HTTParty.get(BASE_URL + "/suggestions/top").parsed_response + # parsed response is hash ["suggestions"] has array with 20 suggestions + end +end diff --git a/omniauth.rb b/omniauth.rb new file mode 100644 index 0000000..0f7f438 --- /dev/null +++ b/omniauth.rb @@ -0,0 +1,7 @@ +# Set up OmniAuth to use Client ID and Secret + +# config/initializers/omniauth.rb +Rails.application.config.middleware.use OmniAuth::Builder do + provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"] # Do not put IDs here directly, + #because when you commit people will be able to see it +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/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..937a0c0 --- /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 +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..82f61e0 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end From 3ce15064aa7072cfc09c99796e4155c49b1b02ee Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Thu, 19 May 2016 19:18:09 -0700 Subject: [PATCH 03/13] Suggestions displayed now include image and link --- app/controllers/suggestions_controller.rb | 3 +- app/models/music.rb | 6 ++- .../suggestions/display_results.html.erb | 34 ++++++++++------- app/views/suggestions/index.html.erb | 37 ++++++++++--------- 4 files changed, 45 insertions(+), 35 deletions(-) diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index 9fbe27a..c3bcae1 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -16,7 +16,7 @@ def index suggestion_object = TunesTakeoutWrapper.find(suggestion_id) suggestion = suggestion_object["suggestion"] - + yelp_id = suggestion["food_id"] spotify_id = suggestion["music_id"] spotify_type = suggestion["music_type"] @@ -53,7 +53,6 @@ def display_results array = [] array << Food.find(yelp_id) #first thing in array is yelp array << Music.find(spotify_id, spotify_type) #second thing is music - @pairings << array end diff --git a/app/models/music.rb b/app/models/music.rb index 7e2891e..f493116 100644 --- a/app/models/music.rb +++ b/app/models/music.rb @@ -17,11 +17,13 @@ def initialize(data) @type = data.type @name = data.name @url = data.external_urls["spotify"] - # @image_url = data.images.first.url #first is widest image + if data.type == "album" || data.type == "artist" + @image_url = data.images.first["url"] if !data.images.empty? + end + @image_url = data.album.images.first["url"] if data.type == "track" #first is widest image end def self.find(id, type) - if type == "album" data = RSpotify::Album.find(id) self.new(data) diff --git a/app/views/suggestions/display_results.html.erb b/app/views/suggestions/display_results.html.erb index d73953a..424571f 100644 --- a/app/views/suggestions/display_results.html.erb +++ b/app/views/suggestions/display_results.html.erb @@ -1,17 +1,23 @@

Your Results

-<% @pairings.each do |pair| %> -

- Food: - <%= pair[0].name%> - <%= pair[0].rating%> -

- -

- Music: - <%= pair[1].name%> - <%= pair[1].url%> -

- -<% end %> + + + + + + <% @pairings.each do |pair| %> + <%food = pair[0]%> + <%music = pair[1]%> + + + + + <% end %> +
FoodMusic
+ <%= image_tag food.image_url%> + <%= link_to food.name, food.url%> + + <%= image_tag music.image_url%> + <%= link_to music.name, music.url%> +
diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb index b151c73..ad1096a 100644 --- a/app/views/suggestions/index.html.erb +++ b/app/views/suggestions/index.html.erb @@ -1,19 +1,22 @@

Here's the list of top favorited suggestions

-<% @pairings.each do |pair| %> - - <%food = pair[0]%> - <%music = pair[1]%> -

- Food: - <%= link_to food.name, food.url%> - Rating:<%= food.rating%> -

- -

- Music: - <%= link_to music.name, music.url%> - <%= %> -

- -<% end %> +
+ + + + + <% @pairings.each do |pair| %> + <%food = pair[0]%> + <%music = pair[1]%> + + + + + <% end %> +
FoodMusic
+ <%= image_tag food.image_url%> + <%= link_to food.name, food.url%> + + <%= image_tag music.image_url%> + <%= link_to music.name, music.url%> +
From 9e97d97f2c960515f00038480e8d12fe721e2103 Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Fri, 20 May 2016 10:51:05 -0700 Subject: [PATCH 04/13] Adds suggestion to favorited --- app/controllers/suggestions_controller.rb | 4 +++- app/models/user.rb | 5 +++-- app/views/layouts/application.html.erb | 4 +++- app/views/suggestions/index.html.erb | 3 +++ config/routes.rb | 4 ++++ db/migrate/20160520023240_add_name_to_users.rb | 5 +++++ db/migrate/20160520024126_add_image_to_users.rb | 5 +++++ db/migrate/20160520033609_add_url_to_users.rb | 5 +++++ db/schema.rb | 5 ++++- lib/TunesTakeoutWrapper.rb | 6 ++++++ 10 files changed, 41 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20160520023240_add_name_to_users.rb create mode 100644 db/migrate/20160520024126_add_image_to_users.rb create mode 100644 db/migrate/20160520033609_add_url_to_users.rb diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index c3bcae1..435bcfd 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -53,6 +53,7 @@ def display_results array = [] array << Food.find(yelp_id) #first thing in array is yelp array << Music.find(spotify_id, spotify_type) #second thing is music + array << suggestion["id"] @pairings << array end @@ -61,7 +62,8 @@ def display_results def favorite #adds a suggestion into the favorite list for the signed-in User. This requires interaction with the Tunes & Takeout API. - + TunesTakeoutWrapper.add_favorite(current_user.uid, params[:suggestion_id]) + redirect_to root_path end def unfavorite diff --git a/app/models/user.rb b/app/models/user.rb index 9a37c81..63f34fd 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -19,8 +19,9 @@ def self.find_or_create_from_omniauth(auth_hash) user = User.new user.uid = auth_hash["uid"] user.provider = auth_hash["provider"] - # user.name = auth_hash["info"]["name"] - # user.email = auth_hash["info"]["email"] + user.name = auth_hash["info"]["name"] + user.image = auth_hash["info"]["image"] + user.url = auth_hash["info"]["urls"]["spotify"] if user.save return user diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 975c2d0..e40c483 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -17,7 +17,9 @@
  • <%= link_to "Search", search_path if current_user%>
  • - <%= "Hi #{ current_user.uid }!" if current_user %> + <%= link_to current_user.name, current_user.url if current_user %> + <%= link_to (image_tag current_user.image), current_user.url if current_user %> + <%= yield %> diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb index ad1096a..4a286b4 100644 --- a/app/views/suggestions/index.html.erb +++ b/app/views/suggestions/index.html.erb @@ -4,14 +4,17 @@
    + <% @pairings.each do |pair| %> <%food = pair[0]%> <%music = pair[1]%> + <%suggestion_id = pair[2]%> + <% end %>
    Food MusicFavorite It
    <%= image_tag food.image_url%> <%= link_to food.name, food.url%> + <%=link_to "Favorite This", favorite_path(:suggestion_id), method: :post if current_user%> <%= image_tag music.image_url%> diff --git a/config/routes.rb b/config/routes.rb index f5d4f94..c9a0798 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -16,6 +16,10 @@ # Example of regular route: # get 'products/:id' => 'catalog#view' + #post to favorite + post 'suggestions/favorite/:suggestion_id' => 'suggestions#favorite', as: :favorite + + # Example of named route that can be invoked with purchase_url(id: product.id) # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase diff --git a/db/migrate/20160520023240_add_name_to_users.rb b/db/migrate/20160520023240_add_name_to_users.rb new file mode 100644 index 0000000..bac750e --- /dev/null +++ b/db/migrate/20160520023240_add_name_to_users.rb @@ -0,0 +1,5 @@ +class AddNameToUsers < ActiveRecord::Migration + def change + add_column :users, :name, :string + end +end diff --git a/db/migrate/20160520024126_add_image_to_users.rb b/db/migrate/20160520024126_add_image_to_users.rb new file mode 100644 index 0000000..f0c4b49 --- /dev/null +++ b/db/migrate/20160520024126_add_image_to_users.rb @@ -0,0 +1,5 @@ +class AddImageToUsers < ActiveRecord::Migration + def change + add_column :users, :image, :string + end +end diff --git a/db/migrate/20160520033609_add_url_to_users.rb b/db/migrate/20160520033609_add_url_to_users.rb new file mode 100644 index 0000000..23c3903 --- /dev/null +++ b/db/migrate/20160520033609_add_url_to_users.rb @@ -0,0 +1,5 @@ +class AddUrlToUsers < ActiveRecord::Migration + def change + add_column :users, :url, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 2bac25b..d0f701d 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20160517225432) do +ActiveRecord::Schema.define(version: 20160520033609) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -21,6 +21,9 @@ t.datetime "updated_at", null: false t.string "uid" t.string "provider" + t.string "name" + t.string "image" + t.string "url" end end diff --git a/lib/TunesTakeoutWrapper.rb b/lib/TunesTakeoutWrapper.rb index f6e5613..98d0b59 100644 --- a/lib/TunesTakeoutWrapper.rb +++ b/lib/TunesTakeoutWrapper.rb @@ -16,4 +16,10 @@ def self.top HTTParty.get(BASE_URL + "/suggestions/top").parsed_response # parsed response is hash ["suggestions"] has array with 20 suggestions end + + def self.add_favorite(user_uid, suggestion_id) + #/v1/users/:user_id/favorites + HTTParty.post(BASE_URL+"/users/#{user_uid}/favorites", + :body => {"suggestion": suggestion_id}.to_json) + end end From 17fd2b5235e0d80d13ac330b546fb92b3edf2df7 Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Fri, 20 May 2016 11:25:18 -0700 Subject: [PATCH 05/13] Favorite is working! --- app/controllers/suggestions_controller.rb | 11 +++++++++++ app/views/suggestions/index.html.erb | 9 ++++++++- lib/TunesTakeoutWrapper.rb | 7 +++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index 435bcfd..6af0be7 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -21,9 +21,14 @@ def index spotify_id = suggestion["music_id"] spotify_type = suggestion["music_type"] + favorite = is_favorite?(suggestion["id"]) + + array = [] array << Food.find(yelp_id) #first thing in array is yelp array << Music.find(spotify_id, spotify_type) #second thing is music + array << suggestion["id"] + array << favorite @pairings << array end @@ -71,4 +76,10 @@ def unfavorite end + def is_favorite?(suggestion_id) + favorites_response = TunesTakeoutWrapper.favorites(current_user.uid) + user_favorites = favorites_response["suggestions"] #an array + return user_favorites.include? suggestion_id + end + end diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb index 4a286b4..02ac3b6 100644 --- a/app/views/suggestions/index.html.erb +++ b/app/views/suggestions/index.html.erb @@ -10,16 +10,23 @@ <%food = pair[0]%> <%music = pair[1]%> <%suggestion_id = pair[2]%> + <%favorite = pair[3]%>
    <%= image_tag food.image_url%> <%= link_to food.name, food.url%> - <%=link_to "Favorite This", favorite_path(:suggestion_id), method: :post if current_user%> <%= image_tag music.image_url%> <%= link_to music.name, music.url%> + <% if !favorite%> + <%=link_to "Favorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> + <% elsif favorite%> + <%=link_to "Unfavorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> + <% end %> +
    diff --git a/lib/TunesTakeoutWrapper.rb b/lib/TunesTakeoutWrapper.rb index 98d0b59..e5c94b6 100644 --- a/lib/TunesTakeoutWrapper.rb +++ b/lib/TunesTakeoutWrapper.rb @@ -22,4 +22,11 @@ def self.add_favorite(user_uid, suggestion_id) HTTParty.post(BASE_URL+"/users/#{user_uid}/favorites", :body => {"suggestion": suggestion_id}.to_json) end + + def self.favorites(user_uid) + HTTParty.get(BASE_URL + "/users/#{user_uid}/favorites").parsed_response + end + + + end From 5cc6af31431ca5dd040b837b235366a480dc1ccb Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Fri, 20 May 2016 12:38:52 -0700 Subject: [PATCH 06/13] Unfavorite is working! --- app/controllers/suggestions_controller.rb | 3 ++- app/views/suggestions/index.html.erb | 2 +- config/routes.rb | 4 ++-- lib/TunesTakeoutWrapper.rb | 5 +++++ 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index 6af0be7..5d018e8 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -73,7 +73,8 @@ def favorite def unfavorite #removes a suggestion from the favorite list for the signed-in User. This requires interaction with the Tunes & Takeout API - + TunesTakeoutWrapper.remove_favorite(current_user.uid, params[:suggestion_id]) + redirect_to root_path end def is_favorite?(suggestion_id) diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb index 02ac3b6..e33c1cb 100644 --- a/app/views/suggestions/index.html.erb +++ b/app/views/suggestions/index.html.erb @@ -24,7 +24,7 @@ <% if !favorite%> <%=link_to "Favorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> <% elsif favorite%> - <%=link_to "Unfavorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> + <%=link_to "Unfavorite", unfavorite_path(suggestion_id: suggestion_id), method: :delete if current_user%> <% end %> diff --git a/config/routes.rb b/config/routes.rb index c9a0798..8b1c6a0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,8 +17,8 @@ # get 'products/:id' => 'catalog#view' #post to favorite - post 'suggestions/favorite/:suggestion_id' => 'suggestions#favorite', as: :favorite - + post 'suggestions/favorite/:suggestion_id' => 'suggestions#favorite', as: :favorite + delete 'suggestions/favorite/:suggestion_id' => 'suggestions#unfavorite', as: :unfavorite # Example of named route that can be invoked with purchase_url(id: product.id) # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase diff --git a/lib/TunesTakeoutWrapper.rb b/lib/TunesTakeoutWrapper.rb index e5c94b6..61865c3 100644 --- a/lib/TunesTakeoutWrapper.rb +++ b/lib/TunesTakeoutWrapper.rb @@ -23,6 +23,11 @@ def self.add_favorite(user_uid, suggestion_id) :body => {"suggestion": suggestion_id}.to_json) end + def self.remove_favorite(user_uid, suggestion_id) + HTTParty.delete(BASE_URL+"/users/#{user_uid}/favorites", + :body => {"suggestion": suggestion_id}.to_json) + end + def self.favorites(user_uid) HTTParty.get(BASE_URL + "/users/#{user_uid}/favorites").parsed_response end From fde245b32406d1daa75ec625adf4798ac4fa719b Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Fri, 20 May 2016 13:49:12 -0700 Subject: [PATCH 07/13] Refactored views with partials --- app/controllers/suggestions_controller.rb | 24 +++++++++++++- app/views/suggestions/_suggestions.html.erb | 31 +++++++++++++++++++ .../suggestions/display_results.html.erb | 21 +------------ app/views/suggestions/favorites.html.erb | 4 +++ app/views/suggestions/index.html.erb | 31 +------------------ 5 files changed, 60 insertions(+), 51 deletions(-) create mode 100644 app/views/suggestions/_suggestions.html.erb create mode 100644 app/views/suggestions/favorites.html.erb diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index 5d018e8..e1d0649 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -3,7 +3,7 @@ require 'httparty' class SuggestionsController < ApplicationController - # extend TunesTakeoutWrapper +#skip before action def index #shows top 20 suggestions, ranked by total number of favorites @@ -83,4 +83,26 @@ def is_favorite?(suggestion_id) return user_favorites.include? suggestion_id end + def favorites + favorites_response = TunesTakeoutWrapper.favorites(current_user.uid) + suggestions = favorites_response["suggestions"] + + @pairings = [] + suggestions.each do |suggestion| + + yelp_id = suggestion["food_id"] + spotify_id = suggestion["music_id"] + spotify_type = suggestion["music_type"] + + array = [] + array << Food.find(yelp_id) #first thing in array is yelp + array << Music.find(spotify_id, spotify_type) #second thing is music + array << suggestion["id"] + @pairings << array + end + + # ready to pass on @pairings to view, but now lets try to reuse views with partials + + end + end diff --git a/app/views/suggestions/_suggestions.html.erb b/app/views/suggestions/_suggestions.html.erb new file mode 100644 index 0000000..ef3e680 --- /dev/null +++ b/app/views/suggestions/_suggestions.html.erb @@ -0,0 +1,31 @@ + +
    + + + + + + <% @pairings.each do |pair| %> + <%food = pair[0]%> + <%music = pair[1]%> + <%suggestion_id = pair[2]%> + <%favorite = pair[3]%> + + + + + + <% end %> +
    FoodMusicFavorite It
    + <%= image_tag food.image_url%> + <%= link_to food.name, food.url%> + + <%= image_tag music.image_url%> + <%= link_to music.name, music.url%> + + <% if !favorite%> + <%=link_to "Favorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> + <% elsif favorite%> + <%=link_to "Unfavorite", unfavorite_path(suggestion_id: suggestion_id), method: :delete if current_user%> + <% end %> +
    diff --git a/app/views/suggestions/display_results.html.erb b/app/views/suggestions/display_results.html.erb index 424571f..bca0684 100644 --- a/app/views/suggestions/display_results.html.erb +++ b/app/views/suggestions/display_results.html.erb @@ -1,23 +1,4 @@

    Your Results

    -
    - - - - - <% @pairings.each do |pair| %> - <%food = pair[0]%> - <%music = pair[1]%> - - - - - <% end %> -
    FoodMusic
    - <%= image_tag food.image_url%> - <%= link_to food.name, food.url%> - - <%= image_tag music.image_url%> - <%= link_to music.name, music.url%> -
    +<%= render :partial => "suggestions" %> diff --git a/app/views/suggestions/favorites.html.erb b/app/views/suggestions/favorites.html.erb new file mode 100644 index 0000000..e06b681 --- /dev/null +++ b/app/views/suggestions/favorites.html.erb @@ -0,0 +1,4 @@ + +

    Here's a list of your favorited suggestions:

    + +<%= render :partial => "suggestions" %> diff --git a/app/views/suggestions/index.html.erb b/app/views/suggestions/index.html.erb index e33c1cb..ddcf558 100644 --- a/app/views/suggestions/index.html.erb +++ b/app/views/suggestions/index.html.erb @@ -1,32 +1,3 @@

    Here's the list of top favorited suggestions

    -
    - - - - - - <% @pairings.each do |pair| %> - <%food = pair[0]%> - <%music = pair[1]%> - <%suggestion_id = pair[2]%> - <%favorite = pair[3]%> - - - - - - <% end %> -
    FoodMusicFavorite It
    - <%= image_tag food.image_url%> - <%= link_to food.name, food.url%> - - <%= image_tag music.image_url%> - <%= link_to music.name, music.url%> - - <% if !favorite%> - <%=link_to "Favorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> - <% elsif favorite%> - <%=link_to "Unfavorite", unfavorite_path(suggestion_id: suggestion_id), method: :delete if current_user%> - <% end %> -
    +<%= render :partial => "suggestions" %> From ed44fd8f7babb0240ed3b2bd75270d84894e994c Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Fri, 20 May 2016 14:16:20 -0700 Subject: [PATCH 08/13] Favorites for user is working --- Gemfile.lock | 3 --- app/controllers/suggestions_controller.rb | 24 +++++++++++++---------- app/views/layouts/application.html.erb | 2 ++ config/routes.rb | 2 ++ 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d6ae82e..8a97782 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -214,8 +214,5 @@ DEPENDENCIES web-console (~> 2.0) yelp -RUBY VERSION - ruby 2.3.0p0 - BUNDLED WITH 1.12.4 diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index e1d0649..469ee74 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -9,7 +9,6 @@ def index #shows top 20 suggestions, ranked by total number of favorites suggestion_ids = TunesTakeoutWrapper.top["suggestions"] #this should return array of sugg ids - @pairings = [] suggestion_ids.each do |suggestion_id| @@ -34,10 +33,6 @@ def index end end - def favorites - #shows all suggestions favorited by the signed-in User - - end def search_by_term #Returns a hash from the TunesTakeoutWrapper @@ -47,7 +42,6 @@ def display_results results = TunesTakeoutWrapper.search(params[:term]) suggestions = results["suggestions"] - @pairings = [] suggestions.each do |suggestion| @@ -55,10 +49,14 @@ def display_results spotify_id = suggestion["music_id"] spotify_type = suggestion["music_type"] + favorite = is_favorite?(suggestion["id"]) + array = [] array << Food.find(yelp_id) #first thing in array is yelp array << Music.find(spotify_id, spotify_type) #second thing is music array << suggestion["id"] + array << favorite + @pairings << array end @@ -85,23 +83,29 @@ def is_favorite?(suggestion_id) def favorites favorites_response = TunesTakeoutWrapper.favorites(current_user.uid) - suggestions = favorites_response["suggestions"] + suggestion_ids = favorites_response["suggestions"] #this is array of suggestion_ids @pairings = [] - suggestions.each do |suggestion| + suggestion_ids.each do |suggestion_id| + + suggestion_object = TunesTakeoutWrapper.find(suggestion_id) + suggestion = suggestion_object["suggestion"] yelp_id = suggestion["food_id"] spotify_id = suggestion["music_id"] spotify_type = suggestion["music_type"] + favorite = is_favorite?(suggestion["id"]) + array = [] array << Food.find(yelp_id) #first thing in array is yelp array << Music.find(spotify_id, spotify_type) #second thing is music array << suggestion["id"] + array << favorite + @pairings << array - end + end - # ready to pass on @pairings to view, but now lets try to reuse views with partials end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index e40c483..b4ce464 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -15,11 +15,13 @@
  • <%= link_to "Log In", "/auth/spotify" unless current_user %>
  • <%= link_to "Log Out", logout_path, method: :delete if current_user%>
  • <%= link_to "Search", search_path if current_user%>
  • +
  • <%= link_to "My Favorites", favorites_path if current_user%>
  • <%= link_to current_user.name, current_user.url if current_user %> <%= link_to (image_tag current_user.image), current_user.url if current_user %> + <%= yield %> diff --git a/config/routes.rb b/config/routes.rb index 8b1c6a0..6071a10 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,6 +20,8 @@ post 'suggestions/favorite/:suggestion_id' => 'suggestions#favorite', as: :favorite delete 'suggestions/favorite/:suggestion_id' => 'suggestions#unfavorite', as: :unfavorite + get 'suggestions/favorites' => 'suggestions#favorites', as: :favorites + # Example of named route that can be invoked with purchase_url(id: product.id) # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase From 24c1a623ac70bc188b2fb0e3fc8bc6796086af2a Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Sun, 22 May 2016 16:11:59 -0700 Subject: [PATCH 09/13] User model test --- app/models/user.rb | 17 ++++++++++- test/fixtures/users.yml | 16 ++++------ test/models/user_test.rb | 63 ++++++++++++++++++++++++++++++++++++++-- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 63f34fd..6f200aa 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,6 +5,21 @@ class User < ActiveRecord::Base # uid must be a string, and must be present # name, if present, must be a string validates :uid, :provider, presence: true + validate :provider_must_be_spotify + validate :name_cant_be_empty_string + + def provider_must_be_spotify + if provider != "spotify" + errors.add(:provider, "provider must be spotify") + end + end + + def name_cant_be_empty_string + if name == "" + errors.add(:name, "name can't be empty string") + end + end + def self.find_or_create_from_omniauth(auth_hash) # Find or create a user @@ -22,7 +37,6 @@ def self.find_or_create_from_omniauth(auth_hash) user.name = auth_hash["info"]["name"] user.image = auth_hash["info"]["image"] user.url = auth_hash["info"]["urls"]["spotify"] - if user.save return user else @@ -33,4 +47,5 @@ def self.find_or_create_from_omniauth(auth_hash) + end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index 937a0c0..928e70b 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -1,11 +1,5 @@ -# 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 +known_user: + provider: spotify + name: known user + uid: known_user + image: http://www.lol.com diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 82f61e0..013de90 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -1,7 +1,64 @@ require 'test_helper' class UserTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end + + def setup + @unknown = { + "uid" => "unknown_user", + "provider" => "spotify", + "info" => {"name" => "unknown user" , "image" => "http://www.lol.com", "urls" => {"spotify" => "http://spotify-user-url"}} + } + @known = { + "uid" => "known_user", + "provider" => "spotify", + "info" => {"name" => "known user" , "image" => "http://www.lol.com", "urls" => {"spotify" => "http://spotify-user-url"}} + } + @unknown_with_uid = OmniAuth.config.mock_auth[:spotify_uid] + end + + test "can make a new user given the oauth spotify hash of unknown user" do + assert_difference 'User.count', 1 do + @user = User.find_or_create_from_omniauth @unknown + end + end + + test "can find 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 user name, provider and uid for new users" do + user = User.find_or_create_from_omniauth @unknown + + assert_equal @unknown['info']['name'], user.name + assert_equal @unknown['provider'], user.provider + assert_equal @unknown['uid'], user.uid + end + + test "validations: username cannot be empty string" do + user = User.new + user.name = "" + assert_not user.valid? + assert user.errors.keys.include?(:name), "name is not in the errors hash" + end + + test "validation: provider must be spotify" do + user = User.new + user.provider = "rectify" + 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 From 841023a795f7b77929791d414a23b21d046a9867 Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Sun, 22 May 2016 16:52:15 -0700 Subject: [PATCH 10/13] Food model testing using vcr --- Gemfile | 4 + Gemfile.lock | 39 ++++++++ ...can_find_a_business_on_yelp_using_name.yml | 91 +++++++++++++++++++ test/models/food_test.rb | 27 ++++++ test/test_helper.rb | 22 ++++- 5 files changed, 182 insertions(+), 1 deletion(-) create mode 100644 test/cassettes/Food/Business_information/can_find_a_business_on_yelp_using_name.yml create mode 100644 test/models/food_test.rb diff --git a/Gemfile b/Gemfile index 9bf9073..a04316c 100644 --- a/Gemfile +++ b/Gemfile @@ -44,6 +44,10 @@ group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' gem 'dotenv-rails' + gem 'pry-rails' + gem 'minitest-vcr' + gem 'minitest-reporters' + gem 'webmock' end diff --git a/Gemfile.lock b/Gemfile.lock index 8a97782..6d52e1f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -36,11 +36,14 @@ 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) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) builder (3.2.2) byebug (9.0.3) + coderay (1.1.1) coffee-rails (4.1.1) coffee-script (>= 2.2.0) railties (>= 4.0.0, < 5.1.x) @@ -49,6 +52,8 @@ 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) domain_name (0.5.20160310) @@ -65,6 +70,7 @@ GEM faraday (>= 0.7.4, < 0.10) globalid (0.3.6) activesupport (>= 4.1.0) + hashdiff (0.3.0) hashie (3.4.4) http-cookie (1.0.2) domain_name (~> 0.5) @@ -85,9 +91,21 @@ GEM nokogiri (>= 1.5.9) mail (2.6.4) mime-types (>= 1.16, < 4) + method_source (0.8.2) mime-types (2.99.1) mini_portile2 (2.0.0) + minispec-metadata (2.0.0) + minitest minitest (5.9.0) + 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) @@ -109,6 +127,12 @@ GEM omniauth-spotify (0.0.9) omniauth-oauth2 (~> 1.1) 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) @@ -146,6 +170,8 @@ GEM rspotify (1.18.0) omniauth-oauth2 (~> 1.3.1) rest-client (~> 1.7) + 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) @@ -162,6 +188,7 @@ GEM 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) @@ -180,11 +207,16 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) + 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) @@ -200,10 +232,13 @@ DEPENDENCIES httparty jbuilder (~> 2.0) jquery-rails + minitest-reporters + minitest-vcr omniauth omniauth-oauth2 (~> 1.3.1) omniauth-spotify pg (~> 0.15) + pry-rails rails (= 4.2.6) rspotify sass-rails (~> 5.0) @@ -212,7 +247,11 @@ DEPENDENCIES spring uglifier (>= 1.3.0) web-console (~> 2.0) + webmock yelp +RUBY VERSION + ruby 2.3.0p0 + BUNDLED WITH 1.12.4 diff --git a/test/cassettes/Food/Business_information/can_find_a_business_on_yelp_using_name.yml b/test/cassettes/Food/Business_information/can_find_a_business_on_yelp_using_name.yml new file mode 100644 index 0000000..7c2d169 --- /dev/null +++ b/test/cassettes/Food/Business_information/can_find_a_business_on_yelp_using_name.yml @@ -0,0 +1,91 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.yelp.com/v2/business/emerald-city-fish-and-chips-seattle + body: + encoding: US-ASCII + string: '' + headers: + User-Agent: + - Faraday v0.9.2 + Authorization: + - OAuth oauth_consumer_key="vayhg9rFzQyxCqKNBvnDYQ", oauth_nonce="6a0212e5f2bebc6e7e1b6d9d8e570fdf", + oauth_signature="RBQSJuBiHtJE2vHi0VfkHuMsg5w%3D", oauth_signature_method="HMAC-SHA1", + oauth_timestamp="1463961124", oauth_token="UCxSqa9ksYit2pvuDajq4pXmgaV1pV_s", + oauth_version="1.0" + Accept-Encoding: + - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 + Accept: + - "*/*" + response: + status: + code: 200 + message: OK + headers: + Date: + - Sun, 22 May 2016 23:52:06 GMT + Content-Type: + - application/json; charset=UTF-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Set-Cookie: + - __cfduid=d9d8b3ff06cd862b873363f65b8a377c71463961126; expires=Mon, 22-May-17 + 23:52:06 GMT; path=/; domain=.yelp.com; HttpOnly + - bse=39e68e040ec2381ce95595d8d7b7af79; Domain=.yelp.com; Path=/; HttpOnly + - yuv=6vrzKDYhRi8-XLgpWboT21-GUrqac4vIl2RkYGqR3jEkcenMLUjsWvaBDjfh__Rh0hJO-3tjbpwD9b7Awu1nVTDbVEiS8T8z; + Domain=.yelp.com; Max-Age=630720000; Path=/; expires=Sat, 17-May-2036 23:52:06 + GMT + X-Node: + - api_com + - web41-r6-sfo2 + Cache-Control: + - max-age=0, must-revalidate, no-cache, no-store, private + Expires: + - Sun, 22 May 2016 23:52:06 GMT + Pragma: + - no-cache + Vary: + - Accept-Encoding,User-Agent + X-Mode: + - ro + X-Proxied: + - extlb7-r10-sfo2 + Server: + - cloudflare-nginx + Cf-Ray: + - 2a742e0f03cf2a9d-SEA + body: + encoding: ASCII-8BIT + string: '{"is_claimed": true, "rating": 4.0, "mobile_url": "http://m.yelp.com/biz/emerald-city-fish-and-chips-seattle?utm_campaign=yelp_api\u0026utm_medium=api_v2_business\u0026utm_source=vayhg9rFzQyxCqKNBvnDYQ", + "rating_img_url": "https://s3-media4.fl.yelpcdn.com/assets/2/www/img/c2f3dd9799a5/ico/stars/v1/stars_4.png", + "review_count": 168, "name": "Emerald City Fish \u0026 Chips", "rating_img_url_small": + "https://s3-media4.fl.yelpcdn.com/assets/2/www/img/f62a5be2f902/ico/stars/v1/stars_small_4.png", + "url": "http://www.yelp.com/biz/emerald-city-fish-and-chips-seattle?utm_campaign=yelp_api\u0026utm_medium=api_v2_business\u0026utm_source=vayhg9rFzQyxCqKNBvnDYQ", + "categories": [["Fish \u0026 Chips", "fishnchips"], ["Seafood", "seafood"], + ["Sandwiches", "sandwiches"]], "menu_date_updated": 1461367203, "reviews": + [{"rating": 5, "excerpt": "Fast, delicious and very affordable. \n\nNot the + best in town but pretty damn good. \n\nThey have some really good deals on + cod and salmon. \n\nPlus there''s...", "time_created": 1458677353, "rating_image_url": + "https://s3-media1.fl.yelpcdn.com/assets/2/www/img/f1def11e4e79/ico/stars/v1/stars_5.png", + "rating_image_small_url": "https://s3-media1.fl.yelpcdn.com/assets/2/www/img/c7623205d5cd/ico/stars/v1/stars_small_5.png", + "user": {"image_url": "http://s3-media2.fl.yelpcdn.com/photo/KAjjds8VQ7C9j_hqZaSZGw/ms.jpg", + "id": "zqZN7C6M0ybbHUclJttmlw", "name": "Matthew A."}, "rating_image_large_url": + "https://s3-media3.fl.yelpcdn.com/assets/2/www/img/22affc4e6c38/ico/stars/v1/stars_large_5.png", + "id": "Dqv0NYNg5Wsu2T97oQJYwA"}], "phone": "2067603474", "snippet_text": "Fast, + delicious and very affordable. \n\nNot the best in town but pretty damn good. + \n\nThey have some really good deals on cod and salmon. \n\nPlus there''s...", + "image_url": "https://s3-media3.fl.yelpcdn.com/bphoto/1HHsIopsUezmGi7fPR3NOw/ms.jpg", + "snippet_image_url": "http://s3-media2.fl.yelpcdn.com/photo/KAjjds8VQ7C9j_hqZaSZGw/ms.jpg", + "display_phone": "+1-206-760-3474", "rating_img_url_large": "https://s3-media2.fl.yelpcdn.com/assets/2/www/img/ccf2b76faa2c/ico/stars/v1/stars_large_4.png", + "menu_provider": "eat24", "id": "emerald-city-fish-and-chips-seattle", "is_closed": + false, "location": {"cross_streets": "Charlestown St \u0026 S 33rd Ave", "city": + "Seattle", "display_address": ["3756 Rainier Ave S", "Mount Baker", "Seattle, + WA 98144"], "geo_accuracy": 8.0, "neighborhoods": ["Mount Baker"], "postal_code": + "98144", "country_code": "US", "address": ["3756 Rainier Ave S"], "coordinate": + {"latitude": 47.57002, "longitude": -122.29063}, "state_code": "WA"}}' + http_version: + recorded_at: Sun, 22 May 2016 23:52:06 GMT +recorded_with: VCR 3.0.3 diff --git a/test/models/food_test.rb b/test/models/food_test.rb new file mode 100644 index 0000000..c9ec1e8 --- /dev/null +++ b/test/models/food_test.rb @@ -0,0 +1,27 @@ +require 'test_helper' + +class FoodTest < ActiveSupport::TestCase + + describe Food do + + describe "Business information", :vcr do + before do + @suggestion = { + "id"=>"Vz0KQY-RRwADboFN", + "food_id"=>"emerald-city-fish-and-chips-seattle", + "music_id"=>"18nhNX9AEFPINp1txOsaJS", + "music_type"=>"album" + } + + @business = Food.find(@suggestion["food_id"]) + end + + it "can find a business on yelp using name", :vcr do + assert_equal "Emerald City Fish & Chips", @business.name + end + + + end + end + +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 92e39b2..f2b8961 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,10 +1,30 @@ +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... + def setup + OmniAuth.config.test_mode = true + OmniAuth.config.mock_auth[:spotify] = OmniAuth::AuthHash.new({:provider => 'spotify', :uid => 'musiclover', info: { name: "music lover", id: "12345"}}) + end end From 1cdbe4d598a67ece04e3a14219066127ecd1ab06 Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Sun, 22 May 2016 17:08:33 -0700 Subject: [PATCH 11/13] Music model test using VCR --- .../can_find_in_spotify_name_of_an_album.yml | 117 ++++++++++++++++++ test/models/music_test.rb | 27 ++++ 2 files changed, 144 insertions(+) create mode 100644 test/cassettes/Music/music_object_information/can_find_in_spotify_name_of_an_album.yml create mode 100644 test/models/music_test.rb diff --git a/test/cassettes/Music/music_object_information/can_find_in_spotify_name_of_an_album.yml b/test/cassettes/Music/music_object_information/can_find_in_spotify_name_of_an_album.yml new file mode 100644 index 0000000..99b13dd --- /dev/null +++ b/test/cassettes/Music/music_object_information/can_find_in_spotify_name_of_an_album.yml @@ -0,0 +1,117 @@ +--- +http_interactions: +- request: + method: get + uri: https://api.spotify.com/v1/albums/18nhNX9AEFPINp1txOsaJS + body: + encoding: US-ASCII + string: '' + headers: + Accept: + - "*/*; q=0.5, application/xml" + Accept-Encoding: + - gzip, deflate + User-Agent: + - Ruby + response: + status: + code: 200 + message: OK + headers: + Server: + - nginx + Date: + - Mon, 23 May 2016 00:05:15 GMT + Content-Type: + - application/json; charset=utf-8 + Transfer-Encoding: + - chunked + Connection: + - keep-alive + Keep-Alive: + - timeout=600 + Cache-Control: + - public, max-age=7200 + Access-Control-Allow-Origin: + - "*" + Access-Control-Allow-Methods: + - GET, POST, OPTIONS, PUT, DELETE + Access-Control-Allow-Credentials: + - 'true' + Access-Control-Max-Age: + - '604800' + Access-Control-Allow-Headers: + - Accept, Authorization, Origin, Content-Type + Content-Encoding: + - gzip + X-Content-Type-Options: + - nosniff + Strict-Transport-Security: + - max-age=31536000; + body: + encoding: ASCII-8BIT + string: !binary |- + H4sIAAAAAAAAAOydWVPjOhaA3++vcPEw89J90b501dQU0CyBALlhaWBqitKa + uMlG7ITl1v3v4ygQaJI4xLkwL+4HdZCOj+RjnU86lmX/+VsUramWHrSv04ee + W4u+Pf259iWU9NM4SZNR9n+iP7OcLM/dp67fUa3rQb8VSsb5WUnS66axfwhK + mmnaS76tr3d7rvP7U8HvptteH6tc56hydLp/Rx7/uDndrse7rI7rB+laUPXX + l3FNzb7zvyhTvfgXXUP4pC6Zp+9JU2yDnnyhjmqPDbDVd6od1WL3XPJimlDb + c/agH4fcpyZ9G5d+m39qf0X/HZt1qOKW0i133Vb9G/ds4LWN+tqXLD0L6eko + 3dwO6XFIQ+nm7ijd2ghpNaShdCuUbl2G9GqUfj8IaSj9HvRsb4U0/D45H6U7 + lZCGY3fHaah37yikQcNeaE/lJKTh2EqQqQYN1fHvIHMYaj8MOYcXo/QotPAo + tOco1HUU2lML7a8F+VrQWdsLaZCvBQ0n4UxPQhu2Q+0nQXIrSJ7+CGlo81nQ + cxZkdjeD9b6HVoUaD8NZV76vPVnfdHsP/bjRfNOv06xjh8uJAKTR/D6wFa7k + l2UPq73uABMfiu0rF1ob9My4nwKEMYGSMwnHtf023/He6XYjp16HotM8upAb + 2zu1ylEPpvfHido/eami4Tp992SWcUvf5YMj3ck85UHNkwPmirRVw/16SZpu + dJlGWYyAidO1fmlP1hpjO1lT1oOCdQeoMBIo6gg0HBGgFbbWUeoMdJwDQb30 + SJDnC3QX27T5VMUvF/alcgzeWzllynBKiFXQSyY1MNhiDrzO/sIeYKcxFhqy + qcqzKuZUzsg76ybUMSEBhN575BnVWnJAtNUCKS8cRdgyBWee+KueOYEgBNGl + U/0k6vqXXh0hAGj0NRr19fFV63V7g5bqx2nofzzk9V3LqcRdW5W6iWt8BeQr + hGtTAte9vjNxEnc7QdSqh7FM2lfm5nU3X7knro9V/rvrfeLSf4F/tOJ2nP6L + gskokbr2Lx1w9giYPwr+rSPhq9Hw7x0R3z0q5o+MOaNjsREynPC4K47NX46U + /7+RMlwBGyfmujNoa9cf2R6+FAz6Ks3c9nrsM4giLsWk1N33WrGJA8K8aiXu + Vclcz3mf3wQ3Xic/NyoPh3uNe3HQbg82mxf2eK+3O+lDk+re4zJjMMxTOVH1 + 5C+LxCbecho3MqNN8jPQDWN3d/0W5L0JyNs9/PVJat1yDayl2dhFGBv9phBT + yy1RWlDhJGYSUGnpi/5wFjMv1cRDg8jLEW/dMxR/y7PsZIQq0ViisUTjO9FI + JAL889DIH1TDksqA38aG71/4q+aeqW+vhMY5Kt+icZHYxFtOnIsuVVTNJoCF + CUkMlopCwinlAjLhMGRcKmE8h45hgCQ3zCg+n5CoICHzDFwSsiRkScilCYkI + RTMJmfYHfzsgsT9Hd02Y8NpdvNWq/tg7365ztRIg56h8C8hFYi9zx6aLtodx + K6p0kti6oox0TKMMhV5rRKUQkHOkDbbKCgQlhg5wiKAnej4jcUFG5tm4ZGTJ + yJKRyzISI0rZJ84iQYudnnWwPz7G6rbZ0EdDxzZWm0XOVjk1i1wg9jKLHJhm + pKJa8mCa3aKIxA4zwhnNAmsPslh7dAeVeQGlchplUTYWCgn/GsFvEUmKTiNz + LFwiskRkicglEYkBZYR8HiJxq9u5sKkc1qpnxwk4ueObCTtbbR45W+XUPHKB + 2MRbjrpRtTt0Ud21VdxJikJSGQ490tYLogHQShIAqPbaEcosZyxDqFKEy/mQ + pEXnkTk2LiFZQrKE5JKQRAjyz7wbSdr0FoMD3HzsHG5t7lz+jG9dZbW7kXNU + Ti3ULBCbeMumstGe0nFamI9YOeRwxkOAs0k691pCL7JZpPCKI6GcMQZqCnLu + RbKCfMwzb8nHko8lH5fkIxQEkdn3Ij8mzta3+zE9uY8FbVy2L+Kz+qPg1dXi + 7Nkqp+LsBWITbzmMkyTu/DO67A4K34h0jithnWMQIU7B6DYkJIBhw6ACnHrD + jNXKzAckLwjIPPuWgCwBWQJyWUBKDgCeCciPWKxh9UZFNfc39ux2/+5G/vSH + +vCsthIf56h8y8dFYhNn2VGtVpR2o3qcuGijkQXaheNsyY0WhgGtsSDKCW2R + 5EJZJaGwWchtEXHO2vmYFAUxmWfmEpMlJktMLolJRCCRn7emTerqpr/f02Kj + 1jjfNDv4j5/128vVwuzZKqfC7AViE2epOjV0UdyJtrptVZSQVBsOw7OmVFPn + tFTccw6xkZx7jzniHgLCxHxCyqKRdo6FS0KWhCwJuSQhocAI0U8jJOLn/uyh + muDTyx/ttFWvAnnMrlYi5ByVbwm5SOyFkN1OI8owaYs/Fak4VcQIoQmwkAnB + GeGOEJD9w0pjnIXc2lGbs1IDQUFA5hm4BGQJyBKQSwISEYLI7KWaD4m0yYY4 + rctteEUq7U6qk2EvPu2vFmnPVjkVaS8QmzjLj2a3X/hhSEaJtB4jB6n0gEHs + jWUGI4yzGaWFGmBpoQF5aCy6pybPtCUaSzSWaFwajQDTz7sJiX4euPs64sd7 + FUX6D73e3cHh1eNqc8fZKqfmjgvEJs5yFfeiSlqYjZ4qn00ULcdCeOgNA9QI + CBm2yDAvgSRYcUNy2Fh0N02ebUs2lmws2bgsGymDbHZc/TEr2MPG4+VdmjZE + 6/ZYDJubBwfbKVhtBXu2yqkV7AViL9tpujcP3eho9FKNx6KIRFQ6JSRQSBDm + EfeGKgakAySDo+QaICygwjgHkUU30+RZuERkicgSkcsiEnBOwechEm50zQ5k + O7d3cvvu53dz1T5McWUlRM5R+RaRi8Qm3rLdcibtxybabA0Kh9iSCUg49BZS + QymXSltouZXOWwI4NAqOnpL0OZtpYNHdNHkmLhlZMrJk5NKMJJLJmYz8kBA7 + ofIEacqO49ur5v7FrjLpcLX9hnNUToXYC8RePedj3Og5n9H/RQmpFaOGcGG5 + IERDz5AlyHLkGEOEa59F2QQqg3IIWXQrTZ6FS0KWhCwJuSwhIZLw8xaw2dWj + 6Vz5i91+Wr+qeSftRvXscLX1mdkqp9ZnFoi9WsAeuqiSZHPIuGOLItJ4Tujo + NT7WWkmZ1cRKZbL4GgHhOGaI0SwGz3vEBxbdTZNn4hKRJSJLRC6LyMyV+Wfu + puncIIMb7uTq4MbdHpD+ufIn96vdi5ytcupe5AKxl7dWdKNNVRiOBDkMAPIc + YMuIMTCLrqFxEiGCfRZaeyp0Fm7DHDgW3kmTY9sSjiUcSzguC0dACJv9Sp8P + ibCHB3vVo2ZydAHI1ePp8HhwiU2yWoQ9W+VUhL1AbOIse900OnGdJFipKCK9 + cp4yYzFhGjroGKQZHqExRELOhNNUYqlcXohddBdNnolLRJaILBG5JCIhJxDO + fqXPh4TYarBR/36e1hp3prq5UYXg5OxGrxZiz1Y5FWIvEHtB5KDT6D9EvtuP + DtVD07WLYhJ4ZTLjSkYFyyJrpoQWAnhmKSUGj3ZoW4SFzHvDeNGtNHlmnvjp + Wvg+w+jo55W6tc7Tx1Y6g1brKWv8NYdR5rNQOL/uIHkjmHZT1Rq3+rfn753M + +ubRFFxGRd/mfTnlr/8BAAD//wMAAzrzyUJpAAA= + http_version: + recorded_at: Mon, 23 May 2016 00:05:14 GMT +recorded_with: VCR 3.0.3 diff --git a/test/models/music_test.rb b/test/models/music_test.rb new file mode 100644 index 0000000..54bbed6 --- /dev/null +++ b/test/models/music_test.rb @@ -0,0 +1,27 @@ +require 'test_helper' + +class MusicTest < ActiveSupport::TestCase + + describe Music do + + describe "music object information", :vcr do + before do + @suggestion = { + "id"=>"Vz0KQY-RRwADboFN", + "food_id"=>"emerald-city-fish-and-chips-seattle", + "music_id"=>"18nhNX9AEFPINp1txOsaJS", + "music_type"=>"album" + } + + @music_object = Music.find(@suggestion["music_id"], @suggestion["music_type"]) + end + + it "can find in spotify name of an album", :vcr do + assert_equal "10 Years of Cream Pie 2005 - 2015", @music_object.name + end + + end + + end + +end From 13916f7444db5517dbb9698696192f43e3d3558a Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Sun, 22 May 2016 17:34:53 -0700 Subject: [PATCH 12/13] TunesTakeoutWrapper testing using VCR --- ...an_add_a_favorite_suggestion_to_a_user.yml | 249 ++++++++++++++ ...lete_a_favorite_suggestion_from_a_user.yml | 321 ++++++++++++++++++ ...rieve_the_top_favorited_20_suggestions.yml | 171 ++++++++++ ...eturn_20_suggestions_after_user_search.yml | 171 ++++++++++ ...ggestions_that_include_the_search_term.yml | 171 ++++++++++ ...estion_hash_when_given_a_suggestion_id.yml | 171 ++++++++++ test/models/TunesTakeoutWrapper_test.rb | 54 +++ 7 files changed, 1308 insertions(+) create mode 100644 test/cassettes/TunesTakeoutWrapper/API/can_add_a_favorite_suggestion_to_a_user.yml create mode 100644 test/cassettes/TunesTakeoutWrapper/API/can_delete_a_favorite_suggestion_from_a_user.yml create mode 100644 test/cassettes/TunesTakeoutWrapper/API/can_retrieve_the_top_favorited_20_suggestions.yml create mode 100644 test/cassettes/TunesTakeoutWrapper/API/can_return_20_suggestions_after_user_search.yml create mode 100644 test/cassettes/TunesTakeoutWrapper/API/can_return_suggestions_that_include_the_search_term.yml create mode 100644 test/cassettes/TunesTakeoutWrapper/API/returns_the_suggestion_hash_when_given_a_suggestion_id.yml create mode 100644 test/models/TunesTakeoutWrapper_test.rb diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_add_a_favorite_suggestion_to_a_user.yml b/test/cassettes/TunesTakeoutWrapper/API/can_add_a_favorite_suggestion_to_a_user.yml new file mode 100644 index 0000000..5c6089a --- /dev/null +++ b/test/cassettes/TunesTakeoutWrapper/API/can_add_a_favorite_suggestion_to_a_user.yml @@ -0,0 +1,249 @@ +--- +http_interactions: +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?limit=20&query=tacos + 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:30:54 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '2534' + Via: + - 1.1 vegur + body: + encoding: ASCII-8BIT + string: !binary |- + eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu + Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT10YWNvc1x1MDAyNmxp + bWl0PTIwXHUwMDI2c2VlZD10YWNvcyIsInN1Z2dlc3Rpb25zIjpbeyJpZCI6 + IlYwSk1CMUVsSndBRHpHdzQiLCJmb29kX2lkIjoibGEtY29jaW5hLW9heGFx + dWVuYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIxUWRsVXY3Mm9WOFJIeDd4TVJY + QWx1IiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndB + RHpHdzUiLCJmb29kX2lkIjoiZ3VhbmFjb3MtdGFjb3MtcHVwdXNlcmlhLXNl + YXR0bGUiLCJtdXNpY19pZCI6IjJ0Z0tDZ1JxRmJYZG1vNkVUVHhMc2IiLCJt + dXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd3NiIs + ImZvb2RfaWQiOiJ0cm9waWNvcy1icmVlemUtc2VhdHRsZSIsIm11c2ljX2lk + IjoiMldZN1preU5UQ01WZXllY1ROSmo2cyIsIm11c2ljX3R5cGUiOiJhbGJ1 + bSJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3c3IiwiZm9vZF9pZCI6InRhY29z + LWVsLXRhamluLXNlYXR0bGUiLCJtdXNpY19pZCI6IjBxT2hrUUhQaTNGZUlF + a1V0d2ZMVk4iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIx + RWxKd0FEekd3OCIsImZvb2RfaWQiOiJjYWN0dXMtcmVzdGF1cmFudHMtc2Vh + dHRsZS0zIiwibXVzaWNfaWQiOiIwc0tDemJ0ck5YRkVJVTZweHpFeGM5Iiwi + bXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdzki + LCJmb29kX2lkIjoiZm9uZGEtbGEtY2F0cmluYS1zZWF0dGxlIiwibXVzaWNf + aWQiOiIzNGEzSTNsQlo2Yks5UkpkMjVhcWpKIiwibXVzaWNfdHlwZSI6InRy + YWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdy0iLCJmb29kX2lkIjoidG9y + dGFzLWNvbmRlc2Etc2VhdHRsZSIsIm11c2ljX2lkIjoiMUZzWnc5eXlyZ3po + dVZKcVVWQnFTZSIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpN + QjFFbEp3QUR6R3dfIiwiZm9vZF9pZCI6ImVsLXJhbmNob24tc2VhdHRsZSIs + Im11c2ljX2lkIjoiM0szaDhTY2ZvbW82NVppMjJrR1NMWiIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hBIiwiZm9vZF9p + ZCI6InRhcXVlcmlhLWVsLW1lem9uLXNlYXR0bGUtMyIsIm11c2ljX2lkIjoi + MlBkdjdMTGMwWjNCZEJOMEt4ekkzMSIsIm11c2ljX3R5cGUiOiJhcnRpc3Qi + fSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4QiIsImZvb2RfaWQiOiJ0bnQtdGFx + dWVyaWEtc2VhdHRsZSIsIm11c2ljX2lkIjoiMWExS0x1OWxxM2Zrdk5OeWpj + V1l0SSIsIm11c2ljX3R5cGUiOiJhcnRpc3QifSx7ImlkIjoiVjBKTUIxRWxK + d0FEekd4QyIsImZvb2RfaWQiOiJiZWJhcy1hbmQtYW1pZ29zLXNlYXR0bGUi + LCJtdXNpY19pZCI6IjIwT21qQ2FQb1paZzNoUTlpT0ttcnEiLCJtdXNpY190 + eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4RCIsImZvb2Rf + aWQiOiJmb2fDs24tY29jaW5hLW1leGljYW5hLXNlYXR0bGUtMiIsIm11c2lj + X2lkIjoiM2dBb1hGUk9melpUVmltRWwxbUVkUyIsIm11c2ljX3R5cGUiOiJ0 + cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hFIiwiZm9vZF9pZCI6Imdy + YWNpYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIweG11QXpLU211a0REbjlwZTVH + YU9HIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlZ6M2ptSXZlOUFB + RFNFN20iLCJmb29kX2lkIjoibWFsZW5hcy10YWNvLXNob3Atc2VhdHRsZS0y + IiwibXVzaWNfaWQiOiIwZUZTaVk4emluS2k1eDJyRHpsbnV5IiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEYiLCJmb29k + X2lkIjoiYmFyLW5vcm9lc3RlLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMWdF + dTJLdU1GQzNEZzBHNGViT3VQRiIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsi + aWQiOiJWMEpNQjFFbEp3QUR6R3hHIiwiZm9vZF9pZCI6InRhcXVlcmlhLWxh + dGlub3MtaWktc2VhdHRsZSIsIm11c2ljX2lkIjoiNGFCR1VjWmc5aWNZa1E4 + SlAzSEYxRCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFF + bEp3QUR6R3hIIiwiZm9vZF9pZCI6InRhY29zLWd1YXltYXMtc2VhdHRsZS02 + IiwibXVzaWNfaWQiOiIweGtYck56ODN4V0dhNEI3VFd6enJuIiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEkiLCJmb29k + X2lkIjoicmFuY2hvLWJyYXZvLXRhY29zLXNlYXR0bGUtMiIsIm11c2ljX2lk + IjoiNFFnTEtyclRNU3YzT1laa2ZWbml3UiIsIm11c2ljX3R5cGUiOiJ0cmFj + ayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hKIiwiZm9vZF9pZCI6InBvcXVp + dG9zLXNlYXR0bGUiLCJtdXNpY19pZCI6IjNvck1LMk44RTNQTHQxTktsRVhs + bUsiLCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FE + ekd4SyIsImZvb2RfaWQiOiJsYS1jYXJ0YS1kZS1vYXhhY2Etc2VhdHRsZSIs + Im11c2ljX2lkIjoiM2kzZjZObU1MQ3dTT24wcnd6S2E4eSIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9XX0= + http_version: + recorded_at: Mon, 23 May 2016 00:30:54 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t + 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:30:55 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '221' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t","suggestion":{"id":"Vz0KO4-RRwADbn9t","food_id":"taqueria-la-pasadita-seattle-3","music_id":"0jEsVskTgxfybttvO9gnLK","music_type":"album"}}' + http_version: + recorded_at: Mon, 23 May 2016 00:30:55 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top + 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:30:55 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '474' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=20","suggestions":["Vz0KQY-RRwADboE-","Vz0KQY-RRwADboEQ","Vz0KO4-RRwADbn9t","Vz0KO4-RRwADbn9f","Vz0KNY-RRwADbn29","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9c","Vz0KO4-RRwADbn9Q","Vz0KQY-RRwADboFN","Vz0KQY-RRwADboEq","Vz0KO4-RRwADbn9d","Vz0KO4-RRwADbn9V","Vz0KO4-RRwADbn9x","Vz0KO4-RRwADbn8Z","Vz0KO4-RRwADbn8x","Vz0KO4-RRwADbn9I","Vz0KO4-RRwADbn9U","Vz0KO4-RRwADbn85","Vz0KNY-RRwADbn2n","Vz0KO4-RRwADbn9b"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:30:56 GMT +- request: + method: post + uri: https://tunes-takeout-api.herokuapp.com/v1/users/user1/favorites + body: + encoding: UTF-8 + string: '{"suggestion":"Vz0KO4-RRwADbn9f"}' + 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:30:56 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:30:56 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/users/user1/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:30:57 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '110' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/user1/favorites","suggestions":["Vz0KO4-RRwADbn9f"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:30:57 GMT +recorded_with: VCR 3.0.3 diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_delete_a_favorite_suggestion_from_a_user.yml b/test/cassettes/TunesTakeoutWrapper/API/can_delete_a_favorite_suggestion_from_a_user.yml new file mode 100644 index 0000000..0de8183 --- /dev/null +++ b/test/cassettes/TunesTakeoutWrapper/API/can_delete_a_favorite_suggestion_from_a_user.yml @@ -0,0 +1,321 @@ +--- +http_interactions: +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?limit=20&query=tacos + 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:34:24 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '2534' + Via: + - 1.1 vegur + body: + encoding: ASCII-8BIT + string: !binary |- + eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu + Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT10YWNvc1x1MDAyNmxp + bWl0PTIwXHUwMDI2c2VlZD10YWNvcyIsInN1Z2dlc3Rpb25zIjpbeyJpZCI6 + IlYwSk1CMUVsSndBRHpHdzQiLCJmb29kX2lkIjoibGEtY29jaW5hLW9heGFx + dWVuYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIxUWRsVXY3Mm9WOFJIeDd4TVJY + QWx1IiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndB + RHpHdzUiLCJmb29kX2lkIjoiZ3VhbmFjb3MtdGFjb3MtcHVwdXNlcmlhLXNl + YXR0bGUiLCJtdXNpY19pZCI6IjJ0Z0tDZ1JxRmJYZG1vNkVUVHhMc2IiLCJt + dXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd3NiIs + ImZvb2RfaWQiOiJ0cm9waWNvcy1icmVlemUtc2VhdHRsZSIsIm11c2ljX2lk + IjoiMldZN1preU5UQ01WZXllY1ROSmo2cyIsIm11c2ljX3R5cGUiOiJhbGJ1 + bSJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3c3IiwiZm9vZF9pZCI6InRhY29z + LWVsLXRhamluLXNlYXR0bGUiLCJtdXNpY19pZCI6IjBxT2hrUUhQaTNGZUlF + a1V0d2ZMVk4iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIx + RWxKd0FEekd3OCIsImZvb2RfaWQiOiJjYWN0dXMtcmVzdGF1cmFudHMtc2Vh + dHRsZS0zIiwibXVzaWNfaWQiOiIwc0tDemJ0ck5YRkVJVTZweHpFeGM5Iiwi + bXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdzki + LCJmb29kX2lkIjoiZm9uZGEtbGEtY2F0cmluYS1zZWF0dGxlIiwibXVzaWNf + aWQiOiIzNGEzSTNsQlo2Yks5UkpkMjVhcWpKIiwibXVzaWNfdHlwZSI6InRy + YWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdy0iLCJmb29kX2lkIjoidG9y + dGFzLWNvbmRlc2Etc2VhdHRsZSIsIm11c2ljX2lkIjoiMUZzWnc5eXlyZ3po + dVZKcVVWQnFTZSIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpN + QjFFbEp3QUR6R3dfIiwiZm9vZF9pZCI6ImVsLXJhbmNob24tc2VhdHRsZSIs + Im11c2ljX2lkIjoiM0szaDhTY2ZvbW82NVppMjJrR1NMWiIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hBIiwiZm9vZF9p + ZCI6InRhcXVlcmlhLWVsLW1lem9uLXNlYXR0bGUtMyIsIm11c2ljX2lkIjoi + MlBkdjdMTGMwWjNCZEJOMEt4ekkzMSIsIm11c2ljX3R5cGUiOiJhcnRpc3Qi + fSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4QiIsImZvb2RfaWQiOiJ0bnQtdGFx + dWVyaWEtc2VhdHRsZSIsIm11c2ljX2lkIjoiMWExS0x1OWxxM2Zrdk5OeWpj + V1l0SSIsIm11c2ljX3R5cGUiOiJhcnRpc3QifSx7ImlkIjoiVjBKTUIxRWxK + d0FEekd4QyIsImZvb2RfaWQiOiJiZWJhcy1hbmQtYW1pZ29zLXNlYXR0bGUi + LCJtdXNpY19pZCI6IjIwT21qQ2FQb1paZzNoUTlpT0ttcnEiLCJtdXNpY190 + eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4RCIsImZvb2Rf + aWQiOiJmb2fDs24tY29jaW5hLW1leGljYW5hLXNlYXR0bGUtMiIsIm11c2lj + X2lkIjoiM2dBb1hGUk9melpUVmltRWwxbUVkUyIsIm11c2ljX3R5cGUiOiJ0 + cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hFIiwiZm9vZF9pZCI6Imdy + YWNpYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIweG11QXpLU211a0REbjlwZTVH + YU9HIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlZ6M2ptSXZlOUFB + RFNFN20iLCJmb29kX2lkIjoibWFsZW5hcy10YWNvLXNob3Atc2VhdHRsZS0y + IiwibXVzaWNfaWQiOiIwZUZTaVk4emluS2k1eDJyRHpsbnV5IiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEYiLCJmb29k + X2lkIjoiYmFyLW5vcm9lc3RlLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMWdF + dTJLdU1GQzNEZzBHNGViT3VQRiIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsi + aWQiOiJWMEpNQjFFbEp3QUR6R3hHIiwiZm9vZF9pZCI6InRhcXVlcmlhLWxh + dGlub3MtaWktc2VhdHRsZSIsIm11c2ljX2lkIjoiNGFCR1VjWmc5aWNZa1E4 + SlAzSEYxRCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFF + bEp3QUR6R3hIIiwiZm9vZF9pZCI6InRhY29zLWd1YXltYXMtc2VhdHRsZS02 + IiwibXVzaWNfaWQiOiIweGtYck56ODN4V0dhNEI3VFd6enJuIiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEkiLCJmb29k + X2lkIjoicmFuY2hvLWJyYXZvLXRhY29zLXNlYXR0bGUtMiIsIm11c2ljX2lk + IjoiNFFnTEtyclRNU3YzT1laa2ZWbml3UiIsIm11c2ljX3R5cGUiOiJ0cmFj + ayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hKIiwiZm9vZF9pZCI6InBvcXVp + dG9zLXNlYXR0bGUiLCJtdXNpY19pZCI6IjNvck1LMk44RTNQTHQxTktsRVhs + bUsiLCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FE + ekd4SyIsImZvb2RfaWQiOiJsYS1jYXJ0YS1kZS1vYXhhY2Etc2VhdHRsZSIs + Im11c2ljX2lkIjoiM2kzZjZObU1MQ3dTT24wcnd6S2E4eSIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9XX0= + http_version: + recorded_at: Mon, 23 May 2016 00:34:25 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t + 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:34:26 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '221' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t","suggestion":{"id":"Vz0KO4-RRwADbn9t","food_id":"taqueria-la-pasadita-seattle-3","music_id":"0jEsVskTgxfybttvO9gnLK","music_type":"album"}}' + http_version: + recorded_at: Mon, 23 May 2016 00:34:26 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top + 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:34:29 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '474' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=20","suggestions":["Vz0KQY-RRwADboE-","Vz0KQY-RRwADboEQ","Vz0KO4-RRwADbn9t","Vz0KO4-RRwADbn9f","Vz0KNY-RRwADbn29","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9c","Vz0KO4-RRwADbn9Q","Vz0KQY-RRwADboFN","Vz0KQY-RRwADboEq","Vz0KO4-RRwADbn9d","Vz0KO4-RRwADbn9V","Vz0KO4-RRwADbn9x","Vz0KO4-RRwADbn8Z","Vz0KO4-RRwADbn8x","Vz0KO4-RRwADbn9I","Vz0KO4-RRwADbn9U","Vz0KO4-RRwADbn85","Vz0KNY-RRwADbn2n","Vz0KO4-RRwADbn9b"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:34:29 GMT +- request: + method: post + uri: https://tunes-takeout-api.herokuapp.com/v1/users/user2/favorites + body: + encoding: UTF-8 + string: '{"suggestion":"Vz0KO4-RRwADbn9f"}' + 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:34:30 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:34:31 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/users/user2/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:34:32 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '110' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/user2/favorites","suggestions":["Vz0KO4-RRwADbn9f"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:34:32 GMT +- request: + method: delete + uri: https://tunes-takeout-api.herokuapp.com/v1/users/user2/favorites + body: + encoding: UTF-8 + string: '{"suggestion":"Vz0KO4-RRwADbn9f"}' + 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:34:32 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:34:32 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/users/user2/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:34:33 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '92' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/users/user2/favorites","suggestions":[]}' + http_version: + recorded_at: Mon, 23 May 2016 00:34:33 GMT +recorded_with: VCR 3.0.3 diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_retrieve_the_top_favorited_20_suggestions.yml b/test/cassettes/TunesTakeoutWrapper/API/can_retrieve_the_top_favorited_20_suggestions.yml new file mode 100644 index 0000000..07ed3d0 --- /dev/null +++ b/test/cassettes/TunesTakeoutWrapper/API/can_retrieve_the_top_favorited_20_suggestions.yml @@ -0,0 +1,171 @@ +--- +http_interactions: +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?limit=20&query=tacos + 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:17:11 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '2534' + Via: + - 1.1 vegur + body: + encoding: ASCII-8BIT + string: !binary |- + eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu + Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT10YWNvc1x1MDAyNmxp + bWl0PTIwXHUwMDI2c2VlZD10YWNvcyIsInN1Z2dlc3Rpb25zIjpbeyJpZCI6 + IlYwSk1CMUVsSndBRHpHdzQiLCJmb29kX2lkIjoibGEtY29jaW5hLW9heGFx + dWVuYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIxUWRsVXY3Mm9WOFJIeDd4TVJY + QWx1IiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndB + RHpHdzUiLCJmb29kX2lkIjoiZ3VhbmFjb3MtdGFjb3MtcHVwdXNlcmlhLXNl + YXR0bGUiLCJtdXNpY19pZCI6IjJ0Z0tDZ1JxRmJYZG1vNkVUVHhMc2IiLCJt + dXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd3NiIs + ImZvb2RfaWQiOiJ0cm9waWNvcy1icmVlemUtc2VhdHRsZSIsIm11c2ljX2lk + IjoiMldZN1preU5UQ01WZXllY1ROSmo2cyIsIm11c2ljX3R5cGUiOiJhbGJ1 + bSJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3c3IiwiZm9vZF9pZCI6InRhY29z + LWVsLXRhamluLXNlYXR0bGUiLCJtdXNpY19pZCI6IjBxT2hrUUhQaTNGZUlF + a1V0d2ZMVk4iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIx + RWxKd0FEekd3OCIsImZvb2RfaWQiOiJjYWN0dXMtcmVzdGF1cmFudHMtc2Vh + dHRsZS0zIiwibXVzaWNfaWQiOiIwc0tDemJ0ck5YRkVJVTZweHpFeGM5Iiwi + bXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdzki + LCJmb29kX2lkIjoiZm9uZGEtbGEtY2F0cmluYS1zZWF0dGxlIiwibXVzaWNf + aWQiOiIzNGEzSTNsQlo2Yks5UkpkMjVhcWpKIiwibXVzaWNfdHlwZSI6InRy + YWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdy0iLCJmb29kX2lkIjoidG9y + dGFzLWNvbmRlc2Etc2VhdHRsZSIsIm11c2ljX2lkIjoiMUZzWnc5eXlyZ3po + dVZKcVVWQnFTZSIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpN + QjFFbEp3QUR6R3dfIiwiZm9vZF9pZCI6ImVsLXJhbmNob24tc2VhdHRsZSIs + Im11c2ljX2lkIjoiM0szaDhTY2ZvbW82NVppMjJrR1NMWiIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hBIiwiZm9vZF9p + ZCI6InRhcXVlcmlhLWVsLW1lem9uLXNlYXR0bGUtMyIsIm11c2ljX2lkIjoi + MlBkdjdMTGMwWjNCZEJOMEt4ekkzMSIsIm11c2ljX3R5cGUiOiJhcnRpc3Qi + fSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4QiIsImZvb2RfaWQiOiJ0bnQtdGFx + dWVyaWEtc2VhdHRsZSIsIm11c2ljX2lkIjoiMWExS0x1OWxxM2Zrdk5OeWpj + V1l0SSIsIm11c2ljX3R5cGUiOiJhcnRpc3QifSx7ImlkIjoiVjBKTUIxRWxK + d0FEekd4QyIsImZvb2RfaWQiOiJiZWJhcy1hbmQtYW1pZ29zLXNlYXR0bGUi + LCJtdXNpY19pZCI6IjIwT21qQ2FQb1paZzNoUTlpT0ttcnEiLCJtdXNpY190 + eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4RCIsImZvb2Rf + aWQiOiJmb2fDs24tY29jaW5hLW1leGljYW5hLXNlYXR0bGUtMiIsIm11c2lj + X2lkIjoiM2dBb1hGUk9melpUVmltRWwxbUVkUyIsIm11c2ljX3R5cGUiOiJ0 + cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hFIiwiZm9vZF9pZCI6Imdy + YWNpYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIweG11QXpLU211a0REbjlwZTVH + YU9HIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlZ6M2ptSXZlOUFB + RFNFN20iLCJmb29kX2lkIjoibWFsZW5hcy10YWNvLXNob3Atc2VhdHRsZS0y + IiwibXVzaWNfaWQiOiIwZUZTaVk4emluS2k1eDJyRHpsbnV5IiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEYiLCJmb29k + X2lkIjoiYmFyLW5vcm9lc3RlLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMWdF + dTJLdU1GQzNEZzBHNGViT3VQRiIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsi + aWQiOiJWMEpNQjFFbEp3QUR6R3hHIiwiZm9vZF9pZCI6InRhcXVlcmlhLWxh + dGlub3MtaWktc2VhdHRsZSIsIm11c2ljX2lkIjoiNGFCR1VjWmc5aWNZa1E4 + SlAzSEYxRCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFF + bEp3QUR6R3hIIiwiZm9vZF9pZCI6InRhY29zLWd1YXltYXMtc2VhdHRsZS02 + IiwibXVzaWNfaWQiOiIweGtYck56ODN4V0dhNEI3VFd6enJuIiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEkiLCJmb29k + X2lkIjoicmFuY2hvLWJyYXZvLXRhY29zLXNlYXR0bGUtMiIsIm11c2ljX2lk + IjoiNFFnTEtyclRNU3YzT1laa2ZWbml3UiIsIm11c2ljX3R5cGUiOiJ0cmFj + ayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hKIiwiZm9vZF9pZCI6InBvcXVp + dG9zLXNlYXR0bGUiLCJtdXNpY19pZCI6IjNvck1LMk44RTNQTHQxTktsRVhs + bUsiLCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FE + ekd4SyIsImZvb2RfaWQiOiJsYS1jYXJ0YS1kZS1vYXhhY2Etc2VhdHRsZSIs + Im11c2ljX2lkIjoiM2kzZjZObU1MQ3dTT24wcnd6S2E4eSIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9XX0= + http_version: + recorded_at: Mon, 23 May 2016 00:17:11 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t + 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:17:13 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '221' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t","suggestion":{"id":"Vz0KO4-RRwADbn9t","food_id":"taqueria-la-pasadita-seattle-3","music_id":"0jEsVskTgxfybttvO9gnLK","music_type":"album"}}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:13 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top + 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:17:14 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '474' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=20","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KO4-RRwADbn9Q","Vz0KQY-RRwADboFN","Vz0KQY-RRwADboEq","Vz0KO4-RRwADbn9d","Vz0KO4-RRwADbn9V","Vz0KO4-RRwADbn9x","Vz0KO4-RRwADbn8Z","Vz0KO4-RRwADbn8x","Vz0KO4-RRwADbn9I","Vz0KO4-RRwADbn9U","Vz0KO4-RRwADbn85","Vz0KNY-RRwADbn2n","Vz0KO4-RRwADbn9b"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:14 GMT +recorded_with: VCR 3.0.3 diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_return_20_suggestions_after_user_search.yml b/test/cassettes/TunesTakeoutWrapper/API/can_return_20_suggestions_after_user_search.yml new file mode 100644 index 0000000..c63d785 --- /dev/null +++ b/test/cassettes/TunesTakeoutWrapper/API/can_return_20_suggestions_after_user_search.yml @@ -0,0 +1,171 @@ +--- +http_interactions: +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?limit=20&query=tacos + 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:17:25 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '2534' + Via: + - 1.1 vegur + body: + encoding: ASCII-8BIT + string: !binary |- + eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu + Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT10YWNvc1x1MDAyNmxp + bWl0PTIwXHUwMDI2c2VlZD10YWNvcyIsInN1Z2dlc3Rpb25zIjpbeyJpZCI6 + IlYwSk1CMUVsSndBRHpHdzQiLCJmb29kX2lkIjoibGEtY29jaW5hLW9heGFx + dWVuYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIxUWRsVXY3Mm9WOFJIeDd4TVJY + QWx1IiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndB + RHpHdzUiLCJmb29kX2lkIjoiZ3VhbmFjb3MtdGFjb3MtcHVwdXNlcmlhLXNl + YXR0bGUiLCJtdXNpY19pZCI6IjJ0Z0tDZ1JxRmJYZG1vNkVUVHhMc2IiLCJt + dXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd3NiIs + ImZvb2RfaWQiOiJ0cm9waWNvcy1icmVlemUtc2VhdHRsZSIsIm11c2ljX2lk + IjoiMldZN1preU5UQ01WZXllY1ROSmo2cyIsIm11c2ljX3R5cGUiOiJhbGJ1 + bSJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3c3IiwiZm9vZF9pZCI6InRhY29z + LWVsLXRhamluLXNlYXR0bGUiLCJtdXNpY19pZCI6IjBxT2hrUUhQaTNGZUlF + a1V0d2ZMVk4iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIx + RWxKd0FEekd3OCIsImZvb2RfaWQiOiJjYWN0dXMtcmVzdGF1cmFudHMtc2Vh + dHRsZS0zIiwibXVzaWNfaWQiOiIwc0tDemJ0ck5YRkVJVTZweHpFeGM5Iiwi + bXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdzki + LCJmb29kX2lkIjoiZm9uZGEtbGEtY2F0cmluYS1zZWF0dGxlIiwibXVzaWNf + aWQiOiIzNGEzSTNsQlo2Yks5UkpkMjVhcWpKIiwibXVzaWNfdHlwZSI6InRy + YWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdy0iLCJmb29kX2lkIjoidG9y + dGFzLWNvbmRlc2Etc2VhdHRsZSIsIm11c2ljX2lkIjoiMUZzWnc5eXlyZ3po + dVZKcVVWQnFTZSIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpN + QjFFbEp3QUR6R3dfIiwiZm9vZF9pZCI6ImVsLXJhbmNob24tc2VhdHRsZSIs + Im11c2ljX2lkIjoiM0szaDhTY2ZvbW82NVppMjJrR1NMWiIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hBIiwiZm9vZF9p + ZCI6InRhcXVlcmlhLWVsLW1lem9uLXNlYXR0bGUtMyIsIm11c2ljX2lkIjoi + MlBkdjdMTGMwWjNCZEJOMEt4ekkzMSIsIm11c2ljX3R5cGUiOiJhcnRpc3Qi + fSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4QiIsImZvb2RfaWQiOiJ0bnQtdGFx + dWVyaWEtc2VhdHRsZSIsIm11c2ljX2lkIjoiMWExS0x1OWxxM2Zrdk5OeWpj + V1l0SSIsIm11c2ljX3R5cGUiOiJhcnRpc3QifSx7ImlkIjoiVjBKTUIxRWxK + d0FEekd4QyIsImZvb2RfaWQiOiJiZWJhcy1hbmQtYW1pZ29zLXNlYXR0bGUi + LCJtdXNpY19pZCI6IjIwT21qQ2FQb1paZzNoUTlpT0ttcnEiLCJtdXNpY190 + eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4RCIsImZvb2Rf + aWQiOiJmb2fDs24tY29jaW5hLW1leGljYW5hLXNlYXR0bGUtMiIsIm11c2lj + X2lkIjoiM2dBb1hGUk9melpUVmltRWwxbUVkUyIsIm11c2ljX3R5cGUiOiJ0 + cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hFIiwiZm9vZF9pZCI6Imdy + YWNpYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIweG11QXpLU211a0REbjlwZTVH + YU9HIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlZ6M2ptSXZlOUFB + RFNFN20iLCJmb29kX2lkIjoibWFsZW5hcy10YWNvLXNob3Atc2VhdHRsZS0y + IiwibXVzaWNfaWQiOiIwZUZTaVk4emluS2k1eDJyRHpsbnV5IiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEYiLCJmb29k + X2lkIjoiYmFyLW5vcm9lc3RlLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMWdF + dTJLdU1GQzNEZzBHNGViT3VQRiIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsi + aWQiOiJWMEpNQjFFbEp3QUR6R3hHIiwiZm9vZF9pZCI6InRhcXVlcmlhLWxh + dGlub3MtaWktc2VhdHRsZSIsIm11c2ljX2lkIjoiNGFCR1VjWmc5aWNZa1E4 + SlAzSEYxRCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFF + bEp3QUR6R3hIIiwiZm9vZF9pZCI6InRhY29zLWd1YXltYXMtc2VhdHRsZS02 + IiwibXVzaWNfaWQiOiIweGtYck56ODN4V0dhNEI3VFd6enJuIiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEkiLCJmb29k + X2lkIjoicmFuY2hvLWJyYXZvLXRhY29zLXNlYXR0bGUtMiIsIm11c2ljX2lk + IjoiNFFnTEtyclRNU3YzT1laa2ZWbml3UiIsIm11c2ljX3R5cGUiOiJ0cmFj + ayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hKIiwiZm9vZF9pZCI6InBvcXVp + dG9zLXNlYXR0bGUiLCJtdXNpY19pZCI6IjNvck1LMk44RTNQTHQxTktsRVhs + bUsiLCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FE + ekd4SyIsImZvb2RfaWQiOiJsYS1jYXJ0YS1kZS1vYXhhY2Etc2VhdHRsZSIs + Im11c2ljX2lkIjoiM2kzZjZObU1MQ3dTT24wcnd6S2E4eSIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9XX0= + http_version: + recorded_at: Mon, 23 May 2016 00:17:25 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t + 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:17:26 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '221' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t","suggestion":{"id":"Vz0KO4-RRwADbn9t","food_id":"taqueria-la-pasadita-seattle-3","music_id":"0jEsVskTgxfybttvO9gnLK","music_type":"album"}}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:26 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top + 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:17:26 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '474' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=20","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KO4-RRwADbn9Q","Vz0KQY-RRwADboFN","Vz0KQY-RRwADboEq","Vz0KO4-RRwADbn9d","Vz0KO4-RRwADbn9V","Vz0KO4-RRwADbn9x","Vz0KO4-RRwADbn8Z","Vz0KO4-RRwADbn8x","Vz0KO4-RRwADbn9I","Vz0KO4-RRwADbn9U","Vz0KO4-RRwADbn85","Vz0KNY-RRwADbn2n","Vz0KO4-RRwADbn9b"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:26 GMT +recorded_with: VCR 3.0.3 diff --git a/test/cassettes/TunesTakeoutWrapper/API/can_return_suggestions_that_include_the_search_term.yml b/test/cassettes/TunesTakeoutWrapper/API/can_return_suggestions_that_include_the_search_term.yml new file mode 100644 index 0000000..23d2e2d --- /dev/null +++ b/test/cassettes/TunesTakeoutWrapper/API/can_return_suggestions_that_include_the_search_term.yml @@ -0,0 +1,171 @@ +--- +http_interactions: +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?limit=20&query=tacos + 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:17:31 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '2534' + Via: + - 1.1 vegur + body: + encoding: ASCII-8BIT + string: !binary |- + eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu + Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT10YWNvc1x1MDAyNmxp + bWl0PTIwXHUwMDI2c2VlZD10YWNvcyIsInN1Z2dlc3Rpb25zIjpbeyJpZCI6 + IlYwSk1CMUVsSndBRHpHdzQiLCJmb29kX2lkIjoibGEtY29jaW5hLW9heGFx + dWVuYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIxUWRsVXY3Mm9WOFJIeDd4TVJY + QWx1IiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndB + RHpHdzUiLCJmb29kX2lkIjoiZ3VhbmFjb3MtdGFjb3MtcHVwdXNlcmlhLXNl + YXR0bGUiLCJtdXNpY19pZCI6IjJ0Z0tDZ1JxRmJYZG1vNkVUVHhMc2IiLCJt + dXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd3NiIs + ImZvb2RfaWQiOiJ0cm9waWNvcy1icmVlemUtc2VhdHRsZSIsIm11c2ljX2lk + IjoiMldZN1preU5UQ01WZXllY1ROSmo2cyIsIm11c2ljX3R5cGUiOiJhbGJ1 + bSJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3c3IiwiZm9vZF9pZCI6InRhY29z + LWVsLXRhamluLXNlYXR0bGUiLCJtdXNpY19pZCI6IjBxT2hrUUhQaTNGZUlF + a1V0d2ZMVk4iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIx + RWxKd0FEekd3OCIsImZvb2RfaWQiOiJjYWN0dXMtcmVzdGF1cmFudHMtc2Vh + dHRsZS0zIiwibXVzaWNfaWQiOiIwc0tDemJ0ck5YRkVJVTZweHpFeGM5Iiwi + bXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdzki + LCJmb29kX2lkIjoiZm9uZGEtbGEtY2F0cmluYS1zZWF0dGxlIiwibXVzaWNf + aWQiOiIzNGEzSTNsQlo2Yks5UkpkMjVhcWpKIiwibXVzaWNfdHlwZSI6InRy + YWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdy0iLCJmb29kX2lkIjoidG9y + dGFzLWNvbmRlc2Etc2VhdHRsZSIsIm11c2ljX2lkIjoiMUZzWnc5eXlyZ3po + dVZKcVVWQnFTZSIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpN + QjFFbEp3QUR6R3dfIiwiZm9vZF9pZCI6ImVsLXJhbmNob24tc2VhdHRsZSIs + Im11c2ljX2lkIjoiM0szaDhTY2ZvbW82NVppMjJrR1NMWiIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hBIiwiZm9vZF9p + ZCI6InRhcXVlcmlhLWVsLW1lem9uLXNlYXR0bGUtMyIsIm11c2ljX2lkIjoi + MlBkdjdMTGMwWjNCZEJOMEt4ekkzMSIsIm11c2ljX3R5cGUiOiJhcnRpc3Qi + fSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4QiIsImZvb2RfaWQiOiJ0bnQtdGFx + dWVyaWEtc2VhdHRsZSIsIm11c2ljX2lkIjoiMWExS0x1OWxxM2Zrdk5OeWpj + V1l0SSIsIm11c2ljX3R5cGUiOiJhcnRpc3QifSx7ImlkIjoiVjBKTUIxRWxK + d0FEekd4QyIsImZvb2RfaWQiOiJiZWJhcy1hbmQtYW1pZ29zLXNlYXR0bGUi + LCJtdXNpY19pZCI6IjIwT21qQ2FQb1paZzNoUTlpT0ttcnEiLCJtdXNpY190 + eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4RCIsImZvb2Rf + aWQiOiJmb2fDs24tY29jaW5hLW1leGljYW5hLXNlYXR0bGUtMiIsIm11c2lj + X2lkIjoiM2dBb1hGUk9melpUVmltRWwxbUVkUyIsIm11c2ljX3R5cGUiOiJ0 + cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hFIiwiZm9vZF9pZCI6Imdy + YWNpYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIweG11QXpLU211a0REbjlwZTVH + YU9HIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlZ6M2ptSXZlOUFB + RFNFN20iLCJmb29kX2lkIjoibWFsZW5hcy10YWNvLXNob3Atc2VhdHRsZS0y + IiwibXVzaWNfaWQiOiIwZUZTaVk4emluS2k1eDJyRHpsbnV5IiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEYiLCJmb29k + X2lkIjoiYmFyLW5vcm9lc3RlLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMWdF + dTJLdU1GQzNEZzBHNGViT3VQRiIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsi + aWQiOiJWMEpNQjFFbEp3QUR6R3hHIiwiZm9vZF9pZCI6InRhcXVlcmlhLWxh + dGlub3MtaWktc2VhdHRsZSIsIm11c2ljX2lkIjoiNGFCR1VjWmc5aWNZa1E4 + SlAzSEYxRCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFF + bEp3QUR6R3hIIiwiZm9vZF9pZCI6InRhY29zLWd1YXltYXMtc2VhdHRsZS02 + IiwibXVzaWNfaWQiOiIweGtYck56ODN4V0dhNEI3VFd6enJuIiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEkiLCJmb29k + X2lkIjoicmFuY2hvLWJyYXZvLXRhY29zLXNlYXR0bGUtMiIsIm11c2ljX2lk + IjoiNFFnTEtyclRNU3YzT1laa2ZWbml3UiIsIm11c2ljX3R5cGUiOiJ0cmFj + ayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hKIiwiZm9vZF9pZCI6InBvcXVp + dG9zLXNlYXR0bGUiLCJtdXNpY19pZCI6IjNvck1LMk44RTNQTHQxTktsRVhs + bUsiLCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FE + ekd4SyIsImZvb2RfaWQiOiJsYS1jYXJ0YS1kZS1vYXhhY2Etc2VhdHRsZSIs + Im11c2ljX2lkIjoiM2kzZjZObU1MQ3dTT24wcnd6S2E4eSIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9XX0= + http_version: + recorded_at: Mon, 23 May 2016 00:17:31 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t + 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:17:32 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '221' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t","suggestion":{"id":"Vz0KO4-RRwADbn9t","food_id":"taqueria-la-pasadita-seattle-3","music_id":"0jEsVskTgxfybttvO9gnLK","music_type":"album"}}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:32 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top + 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:17:33 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '474' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=20","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KO4-RRwADbn9Q","Vz0KQY-RRwADboFN","Vz0KQY-RRwADboEq","Vz0KO4-RRwADbn9d","Vz0KO4-RRwADbn9V","Vz0KO4-RRwADbn9x","Vz0KO4-RRwADbn8Z","Vz0KO4-RRwADbn8x","Vz0KO4-RRwADbn9I","Vz0KO4-RRwADbn9U","Vz0KO4-RRwADbn85","Vz0KNY-RRwADbn2n","Vz0KO4-RRwADbn9b"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:32 GMT +recorded_with: VCR 3.0.3 diff --git a/test/cassettes/TunesTakeoutWrapper/API/returns_the_suggestion_hash_when_given_a_suggestion_id.yml b/test/cassettes/TunesTakeoutWrapper/API/returns_the_suggestion_hash_when_given_a_suggestion_id.yml new file mode 100644 index 0000000..90e572d --- /dev/null +++ b/test/cassettes/TunesTakeoutWrapper/API/returns_the_suggestion_hash_when_given_a_suggestion_id.yml @@ -0,0 +1,171 @@ +--- +http_interactions: +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/search?limit=20&query=tacos + 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:17:18 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '2534' + Via: + - 1.1 vegur + body: + encoding: ASCII-8BIT + string: !binary |- + eyJocmVmIjoiaHR0cHM6Ly90dW5lcy10YWtlb3V0LWFwaS5oZXJva3VhcHAu + Y29tL3YxL3N1Z2dlc3Rpb25zL3NlYXJjaD9xdWVyeT10YWNvc1x1MDAyNmxp + bWl0PTIwXHUwMDI2c2VlZD10YWNvcyIsInN1Z2dlc3Rpb25zIjpbeyJpZCI6 + IlYwSk1CMUVsSndBRHpHdzQiLCJmb29kX2lkIjoibGEtY29jaW5hLW9heGFx + dWVuYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIxUWRsVXY3Mm9WOFJIeDd4TVJY + QWx1IiwibXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndB + RHpHdzUiLCJmb29kX2lkIjoiZ3VhbmFjb3MtdGFjb3MtcHVwdXNlcmlhLXNl + YXR0bGUiLCJtdXNpY19pZCI6IjJ0Z0tDZ1JxRmJYZG1vNkVUVHhMc2IiLCJt + dXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd3NiIs + ImZvb2RfaWQiOiJ0cm9waWNvcy1icmVlemUtc2VhdHRsZSIsIm11c2ljX2lk + IjoiMldZN1preU5UQ01WZXllY1ROSmo2cyIsIm11c2ljX3R5cGUiOiJhbGJ1 + bSJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3c3IiwiZm9vZF9pZCI6InRhY29z + LWVsLXRhamluLXNlYXR0bGUiLCJtdXNpY19pZCI6IjBxT2hrUUhQaTNGZUlF + a1V0d2ZMVk4iLCJtdXNpY190eXBlIjoidHJhY2sifSx7ImlkIjoiVjBKTUIx + RWxKd0FEekd3OCIsImZvb2RfaWQiOiJjYWN0dXMtcmVzdGF1cmFudHMtc2Vh + dHRsZS0zIiwibXVzaWNfaWQiOiIwc0tDemJ0ck5YRkVJVTZweHpFeGM5Iiwi + bXVzaWNfdHlwZSI6InRyYWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdzki + LCJmb29kX2lkIjoiZm9uZGEtbGEtY2F0cmluYS1zZWF0dGxlIiwibXVzaWNf + aWQiOiIzNGEzSTNsQlo2Yks5UkpkMjVhcWpKIiwibXVzaWNfdHlwZSI6InRy + YWNrIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHdy0iLCJmb29kX2lkIjoidG9y + dGFzLWNvbmRlc2Etc2VhdHRsZSIsIm11c2ljX2lkIjoiMUZzWnc5eXlyZ3po + dVZKcVVWQnFTZSIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpN + QjFFbEp3QUR6R3dfIiwiZm9vZF9pZCI6ImVsLXJhbmNob24tc2VhdHRsZSIs + Im11c2ljX2lkIjoiM0szaDhTY2ZvbW82NVppMjJrR1NMWiIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hBIiwiZm9vZF9p + ZCI6InRhcXVlcmlhLWVsLW1lem9uLXNlYXR0bGUtMyIsIm11c2ljX2lkIjoi + MlBkdjdMTGMwWjNCZEJOMEt4ekkzMSIsIm11c2ljX3R5cGUiOiJhcnRpc3Qi + fSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4QiIsImZvb2RfaWQiOiJ0bnQtdGFx + dWVyaWEtc2VhdHRsZSIsIm11c2ljX2lkIjoiMWExS0x1OWxxM2Zrdk5OeWpj + V1l0SSIsIm11c2ljX3R5cGUiOiJhcnRpc3QifSx7ImlkIjoiVjBKTUIxRWxK + d0FEekd4QyIsImZvb2RfaWQiOiJiZWJhcy1hbmQtYW1pZ29zLXNlYXR0bGUi + LCJtdXNpY19pZCI6IjIwT21qQ2FQb1paZzNoUTlpT0ttcnEiLCJtdXNpY190 + eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FEekd4RCIsImZvb2Rf + aWQiOiJmb2fDs24tY29jaW5hLW1leGljYW5hLXNlYXR0bGUtMiIsIm11c2lj + X2lkIjoiM2dBb1hGUk9melpUVmltRWwxbUVkUyIsIm11c2ljX3R5cGUiOiJ0 + cmFjayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hFIiwiZm9vZF9pZCI6Imdy + YWNpYS1zZWF0dGxlIiwibXVzaWNfaWQiOiIweG11QXpLU211a0REbjlwZTVH + YU9HIiwibXVzaWNfdHlwZSI6ImFsYnVtIn0seyJpZCI6IlZ6M2ptSXZlOUFB + RFNFN20iLCJmb29kX2lkIjoibWFsZW5hcy10YWNvLXNob3Atc2VhdHRsZS0y + IiwibXVzaWNfaWQiOiIwZUZTaVk4emluS2k1eDJyRHpsbnV5IiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEYiLCJmb29k + X2lkIjoiYmFyLW5vcm9lc3RlLXNlYXR0bGUtMiIsIm11c2ljX2lkIjoiMWdF + dTJLdU1GQzNEZzBHNGViT3VQRiIsIm11c2ljX3R5cGUiOiJhbGJ1bSJ9LHsi + aWQiOiJWMEpNQjFFbEp3QUR6R3hHIiwiZm9vZF9pZCI6InRhcXVlcmlhLWxh + dGlub3MtaWktc2VhdHRsZSIsIm11c2ljX2lkIjoiNGFCR1VjWmc5aWNZa1E4 + SlAzSEYxRCIsIm11c2ljX3R5cGUiOiJ0cmFjayJ9LHsiaWQiOiJWMEpNQjFF + bEp3QUR6R3hIIiwiZm9vZF9pZCI6InRhY29zLWd1YXltYXMtc2VhdHRsZS02 + IiwibXVzaWNfaWQiOiIweGtYck56ODN4V0dhNEI3VFd6enJuIiwibXVzaWNf + dHlwZSI6ImFsYnVtIn0seyJpZCI6IlYwSk1CMUVsSndBRHpHeEkiLCJmb29k + X2lkIjoicmFuY2hvLWJyYXZvLXRhY29zLXNlYXR0bGUtMiIsIm11c2ljX2lk + IjoiNFFnTEtyclRNU3YzT1laa2ZWbml3UiIsIm11c2ljX3R5cGUiOiJ0cmFj + ayJ9LHsiaWQiOiJWMEpNQjFFbEp3QUR6R3hKIiwiZm9vZF9pZCI6InBvcXVp + dG9zLXNlYXR0bGUiLCJtdXNpY19pZCI6IjNvck1LMk44RTNQTHQxTktsRVhs + bUsiLCJtdXNpY190eXBlIjoiYWxidW0ifSx7ImlkIjoiVjBKTUIxRWxKd0FE + ekd4SyIsImZvb2RfaWQiOiJsYS1jYXJ0YS1kZS1vYXhhY2Etc2VhdHRsZSIs + Im11c2ljX2lkIjoiM2kzZjZObU1MQ3dTT24wcnd6S2E4eSIsIm11c2ljX3R5 + cGUiOiJ0cmFjayJ9XX0= + http_version: + recorded_at: Mon, 23 May 2016 00:17:19 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t + 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:17:19 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '221' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/Vz0KO4-RRwADbn9t","suggestion":{"id":"Vz0KO4-RRwADbn9t","food_id":"taqueria-la-pasadita-seattle-3","music_id":"0jEsVskTgxfybttvO9gnLK","music_type":"album"}}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:19 GMT +- request: + method: get + uri: https://tunes-takeout-api.herokuapp.com/v1/suggestions/top + 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:17:19 GMT + Connection: + - keep-alive + Content-Type: + - application/json + X-Content-Type-Options: + - nosniff + Content-Length: + - '474' + Via: + - 1.1 vegur + body: + encoding: UTF-8 + string: '{"href":"https://tunes-takeout-api.herokuapp.com/v1/suggestions/top?limit=20","suggestions":["Vz0KQY-RRwADboE-","Vz0KO4-RRwADbn9t","Vz0KQY-RRwADboEQ","Vz0KNY-RRwADbn29","Vz0KQY-RRwADboFP","Vz0KO4-RRwADbn9f","Vz0KO4-RRwADbn9c","Vz0KO4-RRwADbn9Q","Vz0KQY-RRwADboFN","Vz0KQY-RRwADboEq","Vz0KO4-RRwADbn9d","Vz0KO4-RRwADbn9V","Vz0KO4-RRwADbn9x","Vz0KO4-RRwADbn8Z","Vz0KO4-RRwADbn8x","Vz0KO4-RRwADbn9I","Vz0KO4-RRwADbn9U","Vz0KO4-RRwADbn85","Vz0KNY-RRwADbn2n","Vz0KO4-RRwADbn9b"]}' + http_version: + recorded_at: Mon, 23 May 2016 00:17:20 GMT +recorded_with: VCR 3.0.3 diff --git a/test/models/TunesTakeoutWrapper_test.rb b/test/models/TunesTakeoutWrapper_test.rb new file mode 100644 index 0000000..28409ea --- /dev/null +++ b/test/models/TunesTakeoutWrapper_test.rb @@ -0,0 +1,54 @@ +require 'test_helper' +require "TunesTakeoutWrapper" + +class TunesTakeoutWrapperTest < ActiveSupport::TestCase + + describe TunesTakeoutWrapper do + + it "uses v1 of the API" do + assert_equal "https://tunes-takeout-api.herokuapp.com/v1", TunesTakeoutWrapper::BASE_URL + end + + describe "API", :vcr do + before do + @search = TunesTakeoutWrapper.search("tacos") + @suggestion = TunesTakeoutWrapper.find("Vz0KO4-RRwADbn9t") + @top_suggestions = TunesTakeoutWrapper.top + end + + it "returns the suggestion hash when given a suggestion id", :vcr do + assert_kind_of Hash, @suggestion + end + + it "can retrieve the top favorited 20 suggestions", :vcr do + assert_equal 20, @top_suggestions["suggestions"].length + end + + it "can return 20 suggestions after user search", :vcr do + assert_equal 20, @search["suggestions"].length + end + + it "can return suggestions that include the search term", :vcr do + assert true, @search.include?("tacos") + end + + it "can add a favorite suggestion to a user", :vcr do + TunesTakeoutWrapper.add_favorite("user1", "Vz0KO4-RRwADbn9f") + user1_favorites = TunesTakeoutWrapper.favorites("user1") + + assert true, user1_favorites.include?("Vz0KO4-RRwADbn9f") + end + + it "can delete a favorite suggestion from a user", :vcr do + TunesTakeoutWrapper.add_favorite("user2", "Vz0KO4-RRwADbn9f") + user2_favorites = TunesTakeoutWrapper.favorites("user2")["suggestions"].count + TunesTakeoutWrapper.remove_favorite("user2", "Vz0KO4-RRwADbn9f") + user2_favorites_after_delete = TunesTakeoutWrapper.favorites("user2")["suggestions"].count + + assert_equal user2_favorites, 1 + assert_equal user2_favorites_after_delete, 0 + end + + end + end +end From bd70deb81eddc935a4d588f99f8f84168f97f16f Mon Sep 17 00:00:00 2001 From: Ania Gonzalez Date: Sun, 22 May 2016 20:53:14 -0700 Subject: [PATCH 13/13] Styling and showing favorite column only for known users --- app/assets/stylesheets/application.css | 34 ++++++++++++--------- app/controllers/suggestions_controller.rb | 8 +++-- app/models/music.rb | 4 +-- app/views/layouts/application.html.erb | 14 +++++++-- app/views/suggestions/_suggestions.html.erb | 27 +++++++++------- 5 files changed, 55 insertions(+), 32 deletions(-) diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index f9cd5b3..ee35ae5 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -1,15 +1,19 @@ -/* - * 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 - */ + +.avatar-container { + float: right; + padding: 1em; +} + +.avatar-image { + height: 25%; +} + +.suggestion-table { + padding: 15px; +} + +th, td { + padding: 15px; + text-align: center; + border-bottom: 1px solid #ddd; +} diff --git a/app/controllers/suggestions_controller.rb b/app/controllers/suggestions_controller.rb index 469ee74..a792904 100644 --- a/app/controllers/suggestions_controller.rb +++ b/app/controllers/suggestions_controller.rb @@ -20,14 +20,18 @@ def index spotify_id = suggestion["music_id"] spotify_type = suggestion["music_type"] - favorite = is_favorite?(suggestion["id"]) + if current_user + favorite = is_favorite?(suggestion["id"]) + end array = [] array << Food.find(yelp_id) #first thing in array is yelp array << Music.find(spotify_id, spotify_type) #second thing is music array << suggestion["id"] - array << favorite + if favorite + array << favorite + end @pairings << array end diff --git a/app/models/music.rb b/app/models/music.rb index f493116..517c8c2 100644 --- a/app/models/music.rb +++ b/app/models/music.rb @@ -18,9 +18,9 @@ def initialize(data) @name = data.name @url = data.external_urls["spotify"] if data.type == "album" || data.type == "artist" - @image_url = data.images.first["url"] if !data.images.empty? + @image_url = data.images.last["url"] if !data.images.empty? end - @image_url = data.album.images.first["url"] if data.type == "track" #first is widest image + @image_url = data.album.images.last["url"] if data.type == "track" #first is widest image end def self.find(id, type) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index b4ce464..ccc770c 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -3,6 +3,8 @@ TunesTakeout <%= stylesheet_link_tag 'application', media: 'all' %> + + <%= javascript_include_tag 'application' %> <%= csrf_meta_tags %> @@ -17,9 +19,17 @@
  • <%= link_to "Search", search_path if current_user%>
  • <%= link_to "My Favorites", favorites_path if current_user%>
  • +
    + <% if current_user %> + <%= link_to current_user.name, current_user.url%> + <%= link_to (image_tag current_user.image, class: "avatar_image", height: '60', width: '60'), current_user.url%> + <% else %> + <%= link_to "Guest", "/auth/spotify"%> + <%= image_tag "https://cypressinheritance.com/wp-content/uploads/MysteryAvatar.png", class: "avatar_image", height: '60', width: '60' %> + <% end %> +
    - <%= link_to current_user.name, current_user.url if current_user %> - <%= link_to (image_tag current_user.image), current_user.url if current_user %> + <%= yield %> diff --git a/app/views/suggestions/_suggestions.html.erb b/app/views/suggestions/_suggestions.html.erb index ef3e680..0c7f181 100644 --- a/app/views/suggestions/_suggestions.html.erb +++ b/app/views/suggestions/_suggestions.html.erb @@ -1,31 +1,36 @@ -
    +
    + <%if current_user %> + <% end%> <% @pairings.each do |pair| %> <%food = pair[0]%> <%music = pair[1]%> <%suggestion_id = pair[2]%> - <%favorite = pair[3]%> + <%favorite = pair[3] if current_user%> - + + <% if current_user %> + + <% end %> <% end %>
    Food MusicFavorite It
    - <%= image_tag food.image_url%> + <%= image_tag food.image_url%>
    <%= link_to food.name, food.url%>
    - <%= image_tag music.image_url%> + <%= image_tag music.image_url%>
    <%= link_to music.name, music.url%>
    - <% if !favorite%> - <%=link_to "Favorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> - <% elsif favorite%> - <%=link_to "Unfavorite", unfavorite_path(suggestion_id: suggestion_id), method: :delete if current_user%> - <% end %> - + <% if !favorite%> + <%=link_to "Favorite", favorite_path(suggestion_id: suggestion_id), method: :post if current_user%> + <% elsif favorite%> + <%=link_to "Unfavorite", unfavorite_path(suggestion_id: suggestion_id), method: :delete if current_user%> + <% end %> +