From 20e14a8bcbe0dd943d073481272130dd1635a8bc Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Mon, 27 Nov 2023 18:02:59 -0600 Subject: [PATCH 01/24] add PR template --- pull_request_template.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 pull_request_template.md diff --git a/pull_request_template.md b/pull_request_template.md new file mode 100644 index 000000000..53d6f119d --- /dev/null +++ b/pull_request_template.md @@ -0,0 +1,20 @@ +## Description + +Please include a description of what was changed + +## Type of change + +- [ ] fix +- [ ] feat +- [ ] test +- [ ] refactor +- [ ] docs + +## Checklist + +- [ ] code has been self reviewed +- [ ] code runs without any errors +- [ ] thorough testing has been implemented if adding feature +- [ ] all tests pass + +### Thanks! \ No newline at end of file From e6e953b9760a42367499e23764a76aaae0281882 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Mon, 27 Nov 2023 17:25:24 -0700 Subject: [PATCH 02/24] Added initial database setup --- Gemfile.lock | 192 +++++++++--------- db/migrate/20231128001844_create_users.rb | 10 + db/migrate/20231128001921_create_parties.rb | 13 ++ .../20231128001937_create_user_parties.rb | 12 ++ db/schema.rb | 46 +++++ 5 files changed, 178 insertions(+), 95 deletions(-) create mode 100644 db/migrate/20231128001844_create_users.rb create mode 100644 db/migrate/20231128001921_create_parties.rb create mode 100644 db/migrate/20231128001937_create_user_parties.rb create mode 100644 db/schema.rb diff --git a/Gemfile.lock b/Gemfile.lock index b54ee32ad..941d46e22 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,76 +1,76 @@ GEM remote: https://rubygems.org/ specs: - actioncable (7.0.6) - actionpack (= 7.0.6) - activesupport (= 7.0.6) + actioncable (7.0.8) + actionpack (= 7.0.8) + activesupport (= 7.0.8) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.6) - actionpack (= 7.0.6) - activejob (= 7.0.6) - activerecord (= 7.0.6) - activestorage (= 7.0.6) - activesupport (= 7.0.6) + actionmailbox (7.0.8) + actionpack (= 7.0.8) + activejob (= 7.0.8) + activerecord (= 7.0.8) + activestorage (= 7.0.8) + activesupport (= 7.0.8) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.6) - actionpack (= 7.0.6) - actionview (= 7.0.6) - activejob (= 7.0.6) - activesupport (= 7.0.6) + actionmailer (7.0.8) + actionpack (= 7.0.8) + actionview (= 7.0.8) + activejob (= 7.0.8) + activesupport (= 7.0.8) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp rails-dom-testing (~> 2.0) - actionpack (7.0.6) - actionview (= 7.0.6) - activesupport (= 7.0.6) + actionpack (7.0.8) + actionview (= 7.0.8) + activesupport (= 7.0.8) rack (~> 2.0, >= 2.2.4) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.6) - actionpack (= 7.0.6) - activerecord (= 7.0.6) - activestorage (= 7.0.6) - activesupport (= 7.0.6) + actiontext (7.0.8) + actionpack (= 7.0.8) + activerecord (= 7.0.8) + activestorage (= 7.0.8) + activesupport (= 7.0.8) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.6) - activesupport (= 7.0.6) + actionview (7.0.8) + activesupport (= 7.0.8) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) - activejob (7.0.6) - activesupport (= 7.0.6) + activejob (7.0.8) + activesupport (= 7.0.8) globalid (>= 0.3.6) - activemodel (7.0.6) - activesupport (= 7.0.6) - activerecord (7.0.6) - activemodel (= 7.0.6) - activesupport (= 7.0.6) - activestorage (7.0.6) - actionpack (= 7.0.6) - activejob (= 7.0.6) - activerecord (= 7.0.6) - activesupport (= 7.0.6) + activemodel (7.0.8) + activesupport (= 7.0.8) + activerecord (7.0.8) + activemodel (= 7.0.8) + activesupport (= 7.0.8) + activestorage (7.0.8) + actionpack (= 7.0.8) + activejob (= 7.0.8) + activerecord (= 7.0.8) + activesupport (= 7.0.8) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (7.0.6) + activesupport (7.0.8) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - addressable (2.8.4) + addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) bindex (0.8.1) - bootsnap (1.16.0) + bootsnap (1.17.0) msgpack (~> 1.2) builder (3.2.4) capybara (3.39.2) @@ -85,16 +85,17 @@ GEM coderay (1.1.3) concurrent-ruby (1.2.2) crass (1.0.6) - date (3.3.3) + date (3.3.4) diff-lcs (1.5.0) docile (1.4.0) erubi (1.12.0) - globalid (1.1.0) - activesupport (>= 5.0) + globalid (1.2.1) + activesupport (>= 6.1) i18n (1.14.1) concurrent-ruby (~> 1.0) - importmap-rails (1.2.1) + importmap-rails (1.2.3) actionpack (>= 6.0.0) + activesupport (>= 6.0.0) railties (>= 6.0.0) jbuilder (2.11.5) actionview (>= 5.0.0) @@ -103,7 +104,7 @@ GEM language_server-protocol (3.17.0.3) launchy (2.5.2) addressable (~> 2.8) - loofah (2.21.3) + loofah (2.22.0) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -114,79 +115,79 @@ GEM marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) - mini_mime (1.1.2) - minitest (5.18.1) - msgpack (1.7.1) - net-imap (0.3.6) + mini_mime (1.1.5) + minitest (5.20.0) + msgpack (1.7.2) + net-imap (0.4.6) date net-protocol net-pop (0.1.2) net-protocol - net-protocol (0.2.1) + net-protocol (0.2.2) timeout - net-smtp (0.3.3) + net-smtp (0.4.0) net-protocol - nio4r (2.5.9) - nokogiri (1.15.2-arm64-darwin) + nio4r (2.6.1) + nokogiri (1.15.5-arm64-darwin) racc (~> 1.4) - nokogiri (1.15.2-x86_64-darwin) + nokogiri (1.15.5-x86_64-darwin) racc (~> 1.4) parallel (1.23.0) - parser (3.2.2.3) + parser (3.2.2.4) ast (~> 2.4.1) racc - pg (1.5.3) + pg (1.5.4) pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - public_suffix (5.0.1) - puma (5.6.6) + public_suffix (5.0.4) + puma (5.6.7) nio4r (~> 2.0) - racc (1.7.1) - rack (2.2.7) + racc (1.7.3) + rack (2.2.8) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.6) - actioncable (= 7.0.6) - actionmailbox (= 7.0.6) - actionmailer (= 7.0.6) - actionpack (= 7.0.6) - actiontext (= 7.0.6) - actionview (= 7.0.6) - activejob (= 7.0.6) - activemodel (= 7.0.6) - activerecord (= 7.0.6) - activestorage (= 7.0.6) - activesupport (= 7.0.6) + rails (7.0.8) + actioncable (= 7.0.8) + actionmailbox (= 7.0.8) + actionmailer (= 7.0.8) + actionpack (= 7.0.8) + actiontext (= 7.0.8) + actionview (= 7.0.8) + activejob (= 7.0.8) + activemodel (= 7.0.8) + activerecord (= 7.0.8) + activestorage (= 7.0.8) + activesupport (= 7.0.8) bundler (>= 1.15.0) - railties (= 7.0.6) - rails-dom-testing (2.1.1) + railties (= 7.0.8) + rails-dom-testing (2.2.0) activesupport (>= 5.0.0) minitest nokogiri (>= 1.6) rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.0.6) - actionpack (= 7.0.6) - activesupport (= 7.0.6) + railties (7.0.8) + actionpack (= 7.0.8) + activesupport (= 7.0.8) method_source rake (>= 12.2) thor (~> 1.0) zeitwerk (~> 2.5) rainbow (3.1.1) - rake (13.0.6) - regexp_parser (2.8.1) - rexml (3.2.5) + rake (13.1.0) + regexp_parser (2.8.2) + rexml (3.2.6) rspec-core (3.12.2) rspec-support (~> 3.12.0) rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-mocks (3.12.5) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-rails (6.0.3) + rspec-rails (6.1.0) actionpack (>= 6.1) activesupport (>= 6.1) railties (>= 6.1) @@ -195,23 +196,24 @@ GEM rspec-mocks (~> 3.12) rspec-support (~> 3.12) rspec-support (3.12.1) - rubocop (1.54.0) + rubocop (1.57.2) json (~> 2.3) language_server-protocol (>= 3.17.0) parallel (~> 1.10) - parser (>= 3.2.2.3) + parser (>= 3.2.2.4) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.28.0, < 2.0) + rubocop-ast (>= 1.28.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 2.4.0, < 3.0) - rubocop-ast (1.29.0) + rubocop-ast (1.30.0) parser (>= 3.2.1.0) - rubocop-rails (2.20.2) + rubocop-rails (2.22.2) activesupport (>= 4.2.0) rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) + rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (1.13.0) simplecov (0.22.0) docile (~> 1.1) @@ -219,35 +221,35 @@ GEM simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) simplecov_json_formatter (0.1.4) - sprockets (4.2.0) + sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - stimulus-rails (1.2.1) + stimulus-rails (1.3.0) railties (>= 6.0.0) - thor (1.2.2) - timeout (0.4.0) - turbo-rails (1.4.0) + thor (1.3.0) + timeout (0.4.1) + turbo-rails (1.5.0) actionpack (>= 6.0.0) activejob (>= 6.0.0) railties (>= 6.0.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - unicode-display_width (2.4.2) - web-console (4.2.0) + unicode-display_width (2.5.0) + web-console (4.2.1) actionview (>= 6.0.0) activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) - websocket-driver (0.7.5) + websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.8) + zeitwerk (2.6.12) PLATFORMS arm64-darwin-22 diff --git a/db/migrate/20231128001844_create_users.rb b/db/migrate/20231128001844_create_users.rb new file mode 100644 index 000000000..88bc54750 --- /dev/null +++ b/db/migrate/20231128001844_create_users.rb @@ -0,0 +1,10 @@ +class CreateUsers < ActiveRecord::Migration[7.0] + def change + create_table :users do |t| + t.string :name + t.string :password_digest + + t.timestamps + end + end +end diff --git a/db/migrate/20231128001921_create_parties.rb b/db/migrate/20231128001921_create_parties.rb new file mode 100644 index 000000000..f7979d606 --- /dev/null +++ b/db/migrate/20231128001921_create_parties.rb @@ -0,0 +1,13 @@ +class CreateParties < ActiveRecord::Migration[7.0] + def change + create_table :parties do |t| + t.integer :movie_id + t.string :movie_title + t.integer :duration + t.date :date + t.time :start_time + + t.timestamps + end + end +end diff --git a/db/migrate/20231128001937_create_user_parties.rb b/db/migrate/20231128001937_create_user_parties.rb new file mode 100644 index 000000000..8bd41f0b6 --- /dev/null +++ b/db/migrate/20231128001937_create_user_parties.rb @@ -0,0 +1,12 @@ +class CreateUserParties < ActiveRecord::Migration[7.0] + def change + create_table :user_parties do |t| + t.boolean :is_host + + t.references :user, null: false, foreign_key: true + t.references :party, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..d32b0be61 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,46 @@ +# 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. +# +# This file is the source Rails uses to define your schema when running `bin/rails +# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to +# be faster and is potentially less error prone than running all of your +# migrations from scratch. Old migrations may fail to apply correctly if those +# migrations use external dependencies or application code. +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema[7.0].define(version: 2023_11_28_001937) do + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "parties", force: :cascade do |t| + t.integer "movie_id" + t.string "movie_title" + t.integer "duration" + t.date "date" + t.time "start_time" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "user_parties", force: :cascade do |t| + t.boolean "is_host" + t.bigint "user_id", null: false + t.bigint "party_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["party_id"], name: "index_user_parties_on_party_id" + t.index ["user_id"], name: "index_user_parties_on_user_id" + end + + create_table "users", force: :cascade do |t| + t.string "name" + t.string "password_digest" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_foreign_key "user_parties", "parties" + add_foreign_key "user_parties", "users" +end From 0f7d13a60e4f2f3100c66ce07bfce16f48db9286 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Mon, 27 Nov 2023 19:45:19 -0700 Subject: [PATCH 03/24] Add missing tests for db tables and relationships, updated gem file to run shoulda-matchers, simplecov, and initialized rspec. Will add faker later --- .gitignore | 1 + .rspec | 1 + Gemfile | 3 +- Gemfile.lock | 5 ++ app/models/party.rb | 10 ++++ app/models/user.rb | 9 ++++ app/models/user_party.rb | 4 ++ spec/models/party_spec.rb | 8 +++ spec/models/user_party_spec.rb | 8 +++ spec/models/user_spec.rb | 8 +++ spec/rails_helper.rb | 72 ++++++++++++++++++++++++++ spec/spec_helper.rb | 94 ++++++++++++++++++++++++++++++++++ spec/test_helper.rb | 16 ++++++ 13 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 .rspec create mode 100644 app/models/party.rb create mode 100644 app/models/user.rb create mode 100644 app/models/user_party.rb create mode 100644 spec/models/party_spec.rb create mode 100644 spec/models/user_party_spec.rb create mode 100644 spec/models/user_spec.rb create mode 100644 spec/rails_helper.rb create mode 100644 spec/spec_helper.rb create mode 100644 spec/test_helper.rb diff --git a/.gitignore b/.gitignore index e16dc71d2..140d178c5 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ /public/assets # Ignore master key for decrypting credentials and more. +coverage /config/master.key diff --git a/.rspec b/.rspec new file mode 100644 index 000000000..c99d2e739 --- /dev/null +++ b/.rspec @@ -0,0 +1 @@ +--require spec_helper diff --git a/Gemfile b/Gemfile index a8a68a722..34592153c 100644 --- a/Gemfile +++ b/Gemfile @@ -34,7 +34,7 @@ gem "jbuilder" # gem "kredis" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" +gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[ mingw mswin x64_mingw jruby ] @@ -69,5 +69,6 @@ group :test do gem "rspec-rails" gem "capybara" gem "launchy" + gem "shoulda-matchers" gem "simplecov" end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 941d46e22..a422d9e54 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -69,6 +69,7 @@ GEM addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) + bcrypt (3.1.20) bindex (0.8.1) bootsnap (1.17.0) msgpack (~> 1.2) @@ -215,6 +216,8 @@ GEM rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (1.13.0) + shoulda-matchers (5.3.0) + activesupport (>= 5.2.0) simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) @@ -256,6 +259,7 @@ PLATFORMS x86_64-darwin-21 DEPENDENCIES + bcrypt (~> 3.1.7) bootsnap capybara importmap-rails @@ -267,6 +271,7 @@ DEPENDENCIES rails (~> 7.0.4, >= 7.0.4.2) rspec-rails rubocop-rails + shoulda-matchers simplecov sprockets-rails stimulus-rails diff --git a/app/models/party.rb b/app/models/party.rb new file mode 100644 index 000000000..a395a048e --- /dev/null +++ b/app/models/party.rb @@ -0,0 +1,10 @@ +class Party < ApplicationRecord + has_many :user_parties + has_many :users, through: :user_parties + + validates_presence_of :movie_id + validates_presence_of :movie_title + validates_presence_of :duration + validates_presence_of :date + validates_presence_of :start_time +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 000000000..ee3d40cc1 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,9 @@ +class User < ApplicationRecord + has_many :user_parties + has_many :parties, through: :user_parties + + validates :name, uniqueness: true, presence: true + validates :email, presence: true, uniqueness: true + validates_presence_of :password + has_secure_password +end \ No newline at end of file diff --git a/app/models/user_party.rb b/app/models/user_party.rb new file mode 100644 index 000000000..1066c6cbb --- /dev/null +++ b/app/models/user_party.rb @@ -0,0 +1,4 @@ +class UserParty < ApplicationRecord + belongs_to :user + belongs_to :party +end \ No newline at end of file diff --git a/spec/models/party_spec.rb b/spec/models/party_spec.rb new file mode 100644 index 000000000..7df58ea16 --- /dev/null +++ b/spec/models/party_spec.rb @@ -0,0 +1,8 @@ +require "rails_helper" + +RSpec.describe Party, type: :model do + describe "relationships" do + it { should have_many :user_parties } + it { should have_many(:users).through(:user_parties) } + end +end \ No newline at end of file diff --git a/spec/models/user_party_spec.rb b/spec/models/user_party_spec.rb new file mode 100644 index 000000000..ac054f45c --- /dev/null +++ b/spec/models/user_party_spec.rb @@ -0,0 +1,8 @@ +require "rails_helper" + +RSpec.describe UserParty, type: :model do + describe "relationships" do + it {should belong_to :user} + it {should belong_to :party} + end +end \ No newline at end of file diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb new file mode 100644 index 000000000..be66877f0 --- /dev/null +++ b/spec/models/user_spec.rb @@ -0,0 +1,8 @@ +require "rails_helper" + +RSpec.describe User, type: :model do + describe "relationships" do + it { should have_many :user_parties } + it { should have_many(:parties).through(:user_parties) } + end +end \ No newline at end of file diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb new file mode 100644 index 000000000..cb9d9c091 --- /dev/null +++ b/spec/rails_helper.rb @@ -0,0 +1,72 @@ +# This file is copied to spec/ when you run 'rails generate rspec:install' +require "simplecov" +require 'spec_helper' +require 'test_helper' +SimpleCov.start +ENV['RAILS_ENV'] ||= 'test' +require_relative '../config/environment' +# Prevent database truncation if the environment is production +abort("The Rails environment is running in production mode!") if Rails.env.production? +require 'rspec/rails' +# Add additional requires below this line. Rails is not loaded until this point! + +# Requires supporting ruby files with custom matchers and macros, etc, in +# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are +# run as spec files by default. This means that files in spec/support that end +# in _spec.rb will both be required and run as specs, causing the specs to be +# run twice. It is recommended that you do not name files matching this glob to +# end with _spec.rb. You can configure this pattern with the --pattern +# option on the command line or in ~/.rspec, .rspec or `.rspec-local`. +# +# The following line is provided for convenience purposes. It has the downside +# of increasing the boot-up time by auto-requiring all files in the support +# directory. Alternatively, in the individual `*_spec.rb` files, manually +# require only the support files necessary. +# +# Rails.root.glob('spec/support/**/*.rb').sort.each { |f| require f } + +# Checks for pending migrations and applies them before tests are run. +# If you are not using ActiveRecord, you can remove these lines. +begin + ActiveRecord::Migration.maintain_test_schema! +rescue ActiveRecord::PendingMigrationError => e + abort e.to_s.strip +end +RSpec.configure do |config| + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures + config.fixture_path = Rails.root.join('spec/fixtures') + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, remove the following line or assign false + # instead of true. + config.use_transactional_fixtures = true + + # You can uncomment this line to turn off ActiveRecord support entirely. + # config.use_active_record = false + + # RSpec Rails can automatically mix in different behaviours to your tests + # based on their file location, for example enabling you to call `get` and + # `post` in specs under `spec/controllers`. + # + # You can disable this behaviour by removing the line below, and instead + # explicitly tag your specs with their type, e.g.: + # + # RSpec.describe UsersController, type: :controller do + # # ... + # end + # + # The different available types are documented in the features, such as in + # https://rspec.info/features/6-0/rspec-rails + config.infer_spec_type_from_file_location! + + # Filter lines from Rails gems in backtraces. + config.filter_rails_from_backtrace! + # arbitrary gems may also be filtered via: + # config.filter_gems_from_backtrace("gem name") + Shoulda::Matchers.configure do |config| + config.integrate do |with| + with.test_framework :rspec + with.library :rails + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb new file mode 100644 index 000000000..327b58ea1 --- /dev/null +++ b/spec/spec_helper.rb @@ -0,0 +1,94 @@ +# This file was generated by the `rails generate rspec:install` command. Conventionally, all +# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. +# The generated `.rspec` file contains `--require spec_helper` which will cause +# this file to always be loaded, without a need to explicitly require it in any +# files. +# +# Given that it is always loaded, you are encouraged to keep this file as +# light-weight as possible. Requiring heavyweight dependencies from this file +# will add to the boot time of your test suite on EVERY test run, even for an +# individual file that may not need all of that loaded. Instead, consider making +# a separate helper file that requires the additional dependencies and performs +# the additional setup, and require it from the spec files that actually need +# it. +# +# See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration +RSpec.configure do |config| + # rspec-expectations config goes here. You can use an alternate + # assertion/expectation library such as wrong or the stdlib/minitest + # assertions if you prefer. + config.expect_with :rspec do |expectations| + # This option will default to `true` in RSpec 4. It makes the `description` + # and `failure_message` of custom matchers include text for helper methods + # defined using `chain`, e.g.: + # be_bigger_than(2).and_smaller_than(4).description + # # => "be bigger than 2 and smaller than 4" + # ...rather than: + # # => "be bigger than 2" + expectations.include_chain_clauses_in_custom_matcher_descriptions = true + end + + # rspec-mocks config goes here. You can use an alternate test double + # library (such as bogus or mocha) by changing the `mock_with` option here. + config.mock_with :rspec do |mocks| + # Prevents you from mocking or stubbing a method that does not exist on + # a real object. This is generally recommended, and will default to + # `true` in RSpec 4. + mocks.verify_partial_doubles = true + end + + # This option will default to `:apply_to_host_groups` in RSpec 4 (and will + # have no way to turn it off -- the option exists only for backwards + # compatibility in RSpec 3). It causes shared context metadata to be + # inherited by the metadata hash of host groups and examples, rather than + # triggering implicit auto-inclusion in groups with matching metadata. + config.shared_context_metadata_behavior = :apply_to_host_groups + +# The settings below are suggested to provide a good initial experience +# with RSpec, but feel free to customize to your heart's content. +=begin + # This allows you to limit a spec run to individual examples or groups + # you care about by tagging them with `:focus` metadata. When nothing + # is tagged with `:focus`, all examples get run. RSpec also provides + # aliases for `it`, `describe`, and `context` that include `:focus` + # metadata: `fit`, `fdescribe` and `fcontext`, respectively. + config.filter_run_when_matching :focus + + # Allows RSpec to persist some state between runs in order to support + # the `--only-failures` and `--next-failure` CLI options. We recommend + # you configure your source control system to ignore this file. + config.example_status_persistence_file_path = "spec/examples.txt" + + # Limits the available syntax to the non-monkey patched syntax that is + # recommended. For more details, see: + # https://rspec.info/features/3-12/rspec-core/configuration/zero-monkey-patching-mode/ + config.disable_monkey_patching! + + # Many RSpec users commonly either run the entire suite or an individual + # file, and it's useful to allow more verbose output when running an + # individual spec file. + if config.files_to_run.one? + # Use the documentation formatter for detailed output, + # unless a formatter has already been configured + # (e.g. via a command-line flag). + config.default_formatter = "doc" + end + + # Print the 10 slowest examples and example groups at the + # end of the spec run, to help surface which specs are running + # particularly slow. + config.profile_examples = 10 + + # Run specs in random order to surface order dependencies. If you find an + # order dependency and want to debug it, you can fix the order by providing + # the seed, which is printed after each run. + # --seed 1234 + config.order = :random + + # Seed global randomization in this process using the `--seed` CLI option. + # Setting this allows you to use `--seed` to deterministically reproduce + # test failures related to randomization by passing the same `--seed` value + # as the one that triggered the failure. + Kernel.srand config.seed +=end +end diff --git a/spec/test_helper.rb b/spec/test_helper.rb new file mode 100644 index 000000000..858004e9d --- /dev/null +++ b/spec/test_helper.rb @@ -0,0 +1,16 @@ +def load_test_data + @user1 = User.create!(name: "Tom", email: "Tom@a_website.com", password: 'password123', password_confirmation: 'password123') + @user2 = User.create!(name: "Jerry", email: "Jerry@a_website.com", password: 'password123', password_confirmation: 'password123') + @user3 = User.create!(name: "Bob", email: "Bob@a_website.com", password: 'password123', password_confirmation: 'password123') + + @party1 = @user1.parties.create!(movie_id: 11, movie_title: "Star Wars", duration: 120, date: '2023/08/01', start_time: '10:00') + @party2 = @user2.parties.create!(movie_id: 120, movie_title: "LOTR", duration: 180, date: '2023/09/01', start_time: '11:00') + + @user_party1 = @user1.user_parties.create!(party_id: @party1.id, is_host: true) + @user_party2 = @user2.user_parties.create!(party_id: @party1.id) + @user_party3 = @user3.user_parties.create!(party_id: @party1.id) + @user_party4 = @user2.user_parties.create!(party_id: @party2.id, is_host: true) + @user_party5 = @user1.user_parties.create!(party_id: @party2.id) + @user_party6 = @user3.user_parties.create!(party_id: @party2.id) + +end \ No newline at end of file From 4cffe87ca90a43ebae5e95aa4fad5dd266f764f8 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Tue, 28 Nov 2023 10:53:20 -0700 Subject: [PATCH 04/24] Add api key encryption --- config/credentials.yml.enc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index 010ff4b02..53dc73ab9 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -IdUl8TW1RuV/hrFBOw2ofbe8+xWVzpTQtF36N+5vBKyWgaq4Juryc86xLP3lLDmJ8pVNpg/g8TYSAWeu+JUTlE4iCq31IZTknkB4BPLpz4ULj3UpYkEFRSB9ZdDufx9ccU4l+4GGtdv5KRqc105s0v09MDWYT+X6NHHUrFlSGepCEXzG7JuQziJCcYxDZccsb0qlsdcUnpWspc6GBBo451lm0YviUcWx3kNsSNqApQqtQENrruynV3UoKipateylgTlrUlOMbYyHIkY1daxdV4EcxSIF1mUy6UwciNIC9xa0WnAGb+oaki6mPvs+FpWz+o548lWRrz91opxNIBv8Zrh+ZwfnQVxByuI2Uqj4fYbETjhbRfu2IbjTk1sQGqZlgougYXtMmCTxe8PNP29bmaxa2s7r4i2dAb9P--jqBTwrKsjHULkBor--z3IhADU0xjCYptFz4QGfyw== \ No newline at end of file +ewst7aIZiyDCyR+GHzRW81uTpfcjoDmfZ+bMHKNMj3GJZtzDEX1QEKEUqSVT6Luxxqo3lukImB34852tjeNl/ScJZbPeR8/LmG2lJl632ioqGvTqtr5DEfKE3gl6ehBSMTtBi5sE5Ofydq1aFltvhkU/BHjiUd8INDx0dx2ref7NFQsLwtL5FMKAdB9kj6W6TcS2QLC0p5yR/h7bBbQjiUytdqHeKib2t6ikFKGpiSNkbdHR9D29FHwU81E/R/uB/MG9Q43Er8YspEeNqLOAfrSwhFbO7xNXYbLX1qsb5iya5FipcG9UOU693euNC2okADrM9DKVCUV3pGPj2lD+cX0Qj1qwW7wqp5MEIqeMED2ui+QJBsSdy+Gx6ck0FdZDgFrc+YVPK8qOKQ==--PM/zy8vOo1drkD15--x/JLU8FieW3+pLHjtB7k/w== \ No newline at end of file From 024d4803dab0b2ed0dfdd73093671c9997b7c956 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Tue, 28 Nov 2023 15:17:00 -0700 Subject: [PATCH 05/24] Add discover page and initial setup to facades --- app/controllers/discover_controller.rb | 5 ++ app/controllers/movies_controller.rb | 18 +++++++ app/views/discover/index.html.erb | 9 ++++ config/routes.rb | 5 ++ db/migrate/20231128001844_create_users.rb | 1 + db/schema.rb | 1 + spec/features/users/discover/index_spec.rb | 32 +++++++++++ spec/features/users/movies/index_spec.rb | 63 ++++++++++++++++++++++ spec/features/users/movies/show_spec.rb | 0 9 files changed, 134 insertions(+) create mode 100644 app/controllers/discover_controller.rb create mode 100644 app/controllers/movies_controller.rb create mode 100644 app/views/discover/index.html.erb create mode 100644 spec/features/users/discover/index_spec.rb create mode 100644 spec/features/users/movies/index_spec.rb create mode 100644 spec/features/users/movies/show_spec.rb diff --git a/app/controllers/discover_controller.rb b/app/controllers/discover_controller.rb new file mode 100644 index 000000000..6ef137b41 --- /dev/null +++ b/app/controllers/discover_controller.rb @@ -0,0 +1,5 @@ +class DiscoverController < ApplicationController + def index + + end +end \ No newline at end of file diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb new file mode 100644 index 000000000..b1575e12a --- /dev/null +++ b/app/controllers/movies_controller.rb @@ -0,0 +1,18 @@ +class MoviesController < ApplicationController + def index + if params[:Movie_Title].present? + facade = MovieFacade.new + @results = facade.search_movies(params[:Movie_Title]) + else + facade = MovieFacade.new + @results = facade.top_movies + end + end + + def show + facade = MovieFacade.new + @data = facade.movie_details(params[:id]) + @data2 = facade.movie_cast(params[:id]) + @data3 = facade.movie_reviews(params[:id]) + end +end \ No newline at end of file diff --git a/app/views/discover/index.html.erb b/app/views/discover/index.html.erb new file mode 100644 index 000000000..7e7e6425a --- /dev/null +++ b/app/views/discover/index.html.erb @@ -0,0 +1,9 @@ +<%= button_to 'Discover Top Rated Movies', "/users/#{params[:user_id]}/movies", method: :get %> + +<%= form_with url: "/users/#{params[:user_id]}/movies" , method: :get, local: true do |f| %> + + <%= f.label :Movie_Title %> + <%= f.text_field :Movie_Title %> + + <%= f.submit 'Search by Movie Title' %> +<% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 262ffd547..bac3be522 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,4 +3,9 @@ # Defines the root path route ("/") # root "articles#index" + + resources :users, only: [:new, :create, :show] do + resources :discover, only: [:index] + resources :movies, only: [:index, :show] + end end diff --git a/db/migrate/20231128001844_create_users.rb b/db/migrate/20231128001844_create_users.rb index 88bc54750..1c96c67ca 100644 --- a/db/migrate/20231128001844_create_users.rb +++ b/db/migrate/20231128001844_create_users.rb @@ -3,6 +3,7 @@ def change create_table :users do |t| t.string :name t.string :password_digest + t.string :email t.timestamps end diff --git a/db/schema.rb b/db/schema.rb index d32b0be61..e31e39284 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -37,6 +37,7 @@ create_table "users", force: :cascade do |t| t.string "name" t.string "password_digest" + t.string "email" t.datetime "created_at", null: false t.datetime "updated_at", null: false end diff --git a/spec/features/users/discover/index_spec.rb b/spec/features/users/discover/index_spec.rb new file mode 100644 index 000000000..f6b5b7ea8 --- /dev/null +++ b/spec/features/users/discover/index_spec.rb @@ -0,0 +1,32 @@ +require 'rails_helper' + +RSpec.describe 'Discover Movies Page' do + before(:each) do + load_test_data + end + + it 'When a user can get to movie results through movie title search' do + + visit "/users/#{@user1.id}/discover" + + expect(page).to have_button("Discover Top Rated Movies") + expect(page).to have_button("Search by Movie Title") + + fill_in 'Movie_Title', with: "Batman" + # click_button "Search by Movie Title" + + # expect(current_path).to eq("/users/#{@user1.id}/movies") + end + + it 'When a user can get to movie results through top rated movies button' do + + visit "/users/#{@user1.id}/discover" + + expect(page).to have_button("Discover Top Rated Movies") + expect(page).to have_button("Search by Movie Title") + + # click_button "Discover Top Rated Movies" + + # expect(current_path).to eq("/users/#{@user1.id}/movies") + end +end \ No newline at end of file diff --git a/spec/features/users/movies/index_spec.rb b/spec/features/users/movies/index_spec.rb new file mode 100644 index 000000000..f2ddd400d --- /dev/null +++ b/spec/features/users/movies/index_spec.rb @@ -0,0 +1,63 @@ +require 'rails_helper' + +RSpec.describe 'Movie Results' do + before(:each) do + load_test_data + end + describe 'happy path' do + it 'Get top 20 rated movies' do + visit "/users/#{@user1.id}/discover" + + expect(page).to have_button("Discover Top Rated Movies") + expect(page).to have_button("Search by Movie Title") + + # json_response = File.read('spec/fixtures/top_twenty_movies.json') + # stub_request(:get, "https://api.themoviedb.org/3/movie/popular?api_key=2c14ab06be3bfe4ca5fecd0f9b2c73fc"). + # with( + # headers: { + # 'Accept'=>'*/*', + # 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + # 'User-Agent'=>'Faraday v2.7.11' + # }). + # to_return(status: 200, body: json_response, headers: {}) + + click_button "Discover Top Rated Movies" + + expect(page.status_code).to eq 200 + + expect(page).to have_link("The Equalizer 3") + expect(page).to have_content(7.3) + + # save_and_open_page + + end + + it 'Get searched movies' do + visit "/users/#{@user1.id}/discover" + + expect(page).to have_button("Discover Top Rated Movies") + expect(page).to have_button("Search by Movie Title") + + # json_response = File.read('spec/fixtures/batman_movies.json') + # stub_request(:get, "https://api.themoviedb.org/3/search/movie?api_key=2c14ab06be3bfe4ca5fecd0f9b2c73fc&query=Batman"). + # with( + # headers: { + # 'Accept'=>'*/*', + # 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + # 'User-Agent'=>'Faraday v2.7.11' + # }). + # to_return(status: 200, body: json_response, headers: {}) + + fill_in 'Movie_Title', with: "Batman" + click_button "Search by Movie Title" + + expect(page.status_code).to eq 200 + + expect(page).to have_link("Batman Begins") + expect(page).to have_content(7.2) + + # save_and_open_page + + end + end +end \ No newline at end of file diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb new file mode 100644 index 000000000..e69de29bb From ef93fcf89e481f415158efa542133b71d7ff3766 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Tue, 28 Nov 2023 15:59:11 -0700 Subject: [PATCH 06/24] Added facades and tests with webmock --- Gemfile | 3 + Gemfile.lock | 19 ++ app/facades/movie_facade.rb | 34 ++ app/poros/movie_poro.rb | 15 + app/services/movie_service.rb | 32 ++ app/views/movies/index.html.erb | 7 + spec/features/users/movies/index_spec.rb | 44 ++- spec/fixtures/batman_movies.json | 418 +++++++++++++++++++++++ spec/fixtures/top_twenty_movies.json | 405 ++++++++++++++++++++++ spec/spec_helper.rb | 1 + 10 files changed, 953 insertions(+), 25 deletions(-) create mode 100644 app/facades/movie_facade.rb create mode 100644 app/poros/movie_poro.rb create mode 100644 app/services/movie_service.rb create mode 100644 app/views/movies/index.html.erb create mode 100644 spec/fixtures/batman_movies.json create mode 100644 spec/fixtures/top_twenty_movies.json diff --git a/Gemfile b/Gemfile index 34592153c..48524607b 100644 --- a/Gemfile +++ b/Gemfile @@ -47,6 +47,8 @@ gem "bootsnap", require: false # Use Active Storage variants [https://guides.rubyonrails.org/active_storage_overview.html#transforming-images] # gem "image_processing", "~> 1.2" +gem 'faraday' +gem 'figaro' group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem @@ -71,4 +73,5 @@ group :test do gem "launchy" gem "shoulda-matchers" gem "simplecov" + gem 'webmock' end \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index a422d9e54..6af843340 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -69,6 +69,7 @@ GEM addressable (2.8.5) public_suffix (>= 2.0.2, < 6.0) ast (2.4.2) + base64 (0.2.0) bcrypt (3.1.20) bindex (0.8.1) bootsnap (1.17.0) @@ -85,13 +86,23 @@ GEM xpath (~> 3.2) coderay (1.1.3) concurrent-ruby (1.2.2) + crack (0.4.5) + rexml crass (1.0.6) date (3.3.4) diff-lcs (1.5.0) docile (1.4.0) erubi (1.12.0) + faraday (2.7.12) + base64 + faraday-net_http (>= 2.0, < 3.1) + ruby2_keywords (>= 0.0.4) + faraday-net_http (3.0.2) + figaro (1.2.0) + thor (>= 0.14.0, < 2) globalid (1.2.1) activesupport (>= 6.1) + hashdiff (1.0.1) i18n (1.14.1) concurrent-ruby (~> 1.0) importmap-rails (1.2.3) @@ -216,6 +227,7 @@ GEM rubocop (>= 1.33.0, < 2.0) rubocop-ast (>= 1.30.0, < 2.0) ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) shoulda-matchers (5.3.0) activesupport (>= 5.2.0) simplecov (0.22.0) @@ -247,6 +259,10 @@ GEM activemodel (>= 6.0.0) bindex (>= 0.4.0) railties (>= 6.0.0) + webmock (3.19.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) websocket-driver (0.7.6) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -262,6 +278,8 @@ DEPENDENCIES bcrypt (~> 3.1.7) bootsnap capybara + faraday + figaro importmap-rails jbuilder launchy @@ -278,6 +296,7 @@ DEPENDENCIES turbo-rails tzinfo-data web-console + webmock RUBY VERSION ruby 3.2.2p53 diff --git a/app/facades/movie_facade.rb b/app/facades/movie_facade.rb new file mode 100644 index 000000000..64110283f --- /dev/null +++ b/app/facades/movie_facade.rb @@ -0,0 +1,34 @@ +class MovieFacade + def top_movies + service = MovieService.new + data = service.top_movies[:results] + limit = data[0..20] + @results = limit.map do |movie_data| + MoviePoro.new(movie_data) + end + end + + def search_movies(title) + service = MovieService.new + data = service.search_movies(title)[:results] + limit = data[0..20] + @results = limit.map do |movie_data| + MoviePoro.new(movie_data) + end + end + + def movie_details(id) + service = MovieService.new + service.movie_details(id) + end + + def movie_cast(id) + service = MovieService.new + service.movie_cast(id) + end + + def movie_reviews(id) + service = MovieService.new + service.movie_reviews(id) + end +end \ No newline at end of file diff --git a/app/poros/movie_poro.rb b/app/poros/movie_poro.rb new file mode 100644 index 000000000..061c399bd --- /dev/null +++ b/app/poros/movie_poro.rb @@ -0,0 +1,15 @@ +class MoviePoro + attr_reader :id, :title, :vote_average, :runtime, :genres, :overview, :cast, :results, :poster_path + + def initialize(data) + @id = data[:id] + @title = data[:title] + @vote_average = data[:vote_average] + @runtime = data[:runtime] + @genres = data[:genres] + @overview = data[:overview] + @cast = data[:cast] + @results = data[:results] + @poster_path = data[:poster_path] + end +end \ No newline at end of file diff --git a/app/services/movie_service.rb b/app/services/movie_service.rb new file mode 100644 index 000000000..9b3a69ac1 --- /dev/null +++ b/app/services/movie_service.rb @@ -0,0 +1,32 @@ +class MovieService + def get_url(url) + response = conn.get(url) + JSON.parse(response.body, symbolize_names: true) + end + + def top_movies + get_url('/3/movie/popular') + end + + def search_movies(title) + get_url("/3/search/movie?query=#{title}") + end + + def movie_details(id) + get_url("/3/movie/#{id}") + end + + def movie_cast(id) + get_url("/3/movie/#{id}/credits") + end + + def movie_reviews(id) + get_url("/3/movie/#{id}/reviews") + end + + def conn + Faraday.new(url: "https://api.themoviedb.org") do |faraday| + faraday.params['api_key'] = Rails.application.credentials.tmdb[:key] + end + end +end \ No newline at end of file diff --git a/app/views/movies/index.html.erb b/app/views/movies/index.html.erb new file mode 100644 index 000000000..850720d08 --- /dev/null +++ b/app/views/movies/index.html.erb @@ -0,0 +1,7 @@ +

Movie Results

+<% @results.each do |result| %> +
    +
  • <%= link_to "#{result.title}", "/users/#{params[:user_id]}/movies/#{result.id}" %>
  • +
  • <%= result.vote_average %>
  • +
+<% end %> \ No newline at end of file diff --git a/spec/features/users/movies/index_spec.rb b/spec/features/users/movies/index_spec.rb index f2ddd400d..c77ad3097 100644 --- a/spec/features/users/movies/index_spec.rb +++ b/spec/features/users/movies/index_spec.rb @@ -6,30 +6,27 @@ end describe 'happy path' do it 'Get top 20 rated movies' do + json_response = File.read('spec/fixtures/top_twenty_movies.json') + stub_request(:get, "https://api.themoviedb.org/3/movie/popular?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: json_response, headers: {}) + visit "/users/#{@user1.id}/discover" expect(page).to have_button("Discover Top Rated Movies") expect(page).to have_button("Search by Movie Title") - # json_response = File.read('spec/fixtures/top_twenty_movies.json') - # stub_request(:get, "https://api.themoviedb.org/3/movie/popular?api_key=2c14ab06be3bfe4ca5fecd0f9b2c73fc"). - # with( - # headers: { - # 'Accept'=>'*/*', - # 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - # 'User-Agent'=>'Faraday v2.7.11' - # }). - # to_return(status: 200, body: json_response, headers: {}) - click_button "Discover Top Rated Movies" expect(page.status_code).to eq 200 expect(page).to have_link("The Equalizer 3") expect(page).to have_content(7.3) - - # save_and_open_page - end it 'Get searched movies' do @@ -38,15 +35,15 @@ expect(page).to have_button("Discover Top Rated Movies") expect(page).to have_button("Search by Movie Title") - # json_response = File.read('spec/fixtures/batman_movies.json') - # stub_request(:get, "https://api.themoviedb.org/3/search/movie?api_key=2c14ab06be3bfe4ca5fecd0f9b2c73fc&query=Batman"). - # with( - # headers: { - # 'Accept'=>'*/*', - # 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', - # 'User-Agent'=>'Faraday v2.7.11' - # }). - # to_return(status: 200, body: json_response, headers: {}) + json_response = File.read('spec/fixtures/batman_movies.json') + stub_request(:get, "https://api.themoviedb.org/3/search/movie?api_key=#{Rails.application.credentials.tmdb[:key]}&query=Batman"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: json_response, headers: {}) fill_in 'Movie_Title', with: "Batman" click_button "Search by Movie Title" @@ -55,9 +52,6 @@ expect(page).to have_link("Batman Begins") expect(page).to have_content(7.2) - - # save_and_open_page - end end end \ No newline at end of file diff --git a/spec/fixtures/batman_movies.json b/spec/fixtures/batman_movies.json new file mode 100644 index 000000000..495a0fea8 --- /dev/null +++ b/spec/fixtures/batman_movies.json @@ -0,0 +1,418 @@ +{ + "page": 1, + "results": [ + { + "adult": false, + "backdrop_path": "/frDS8A5vIP927KYAxTVVKRIbqZw.jpg", + "genre_ids": [ + 14, + 28, + 80 + ], + "id": 268, + "original_language": "en", + "original_title": "Batman", + "overview": "Batman must face his most ruthless nemesis when a deformed madman calling himself \"The Joker\" seizes control of Gotham's criminal underworld.", + "popularity": 55.624, + "poster_path": "/cij4dd21v2Rk2YtUQbV5kW69WB2.jpg", + "release_date": "1989-06-21", + "title": "Batman", + "video": false, + "vote_average": 7.22, + "vote_count": 7237 + }, + { + "adult": false, + "backdrop_path": "/bxxupqG6TBLKC60M6L8iOvbQEr6.jpg", + "genre_ids": [ + 28, + 35, + 80 + ], + "id": 2661, + "original_language": "en", + "original_title": "Batman", + "overview": "The Dynamic Duo faces four super-villains who plan to hold the world for ransom with the help of a secret invention that instantly dehydrates people.", + "popularity": 29.989, + "poster_path": "/zzoPxWHnPa0eyfkMLgwbNvdEcVF.jpg", + "release_date": "1966-07-30", + "title": "Batman", + "video": false, + "vote_average": 6.301, + "vote_count": 791 + }, + { + "adult": false, + "backdrop_path": "/xEG5iP1qZCiDt4BefSpLy1d54zE.jpg", + "genre_ids": [ + 28, + 12, + 80, + 878, + 53, + 10752 + ], + "id": 125249, + "original_language": "en", + "original_title": "Batman", + "overview": "Japanese master spy Daka operates a covert espionage-sabotage organization located in Gotham City's now-deserted Little Tokyo, which turns American scientists into pliable zombies. The great crime-fighters Batman and Robin, with the help of their allies, are in pursuit.", + "popularity": 10.352, + "poster_path": "/AvzD3mrtokIzZOiV6zAG7geIo6F.jpg", + "release_date": "1943-07-16", + "title": "Batman", + "video": false, + "vote_average": 6.4, + "vote_count": 59 + }, + { + "adult": false, + "backdrop_path": "/p2aiSLQZx7AVZrY9cfOOPv1u5Zk.jpg", + "genre_ids": [ + 27, + 53, + 878 + ], + "id": 1160196, + "original_language": "en", + "original_title": "Batman", + "overview": "A young man learns the consequence of tempting with the underworld", + "popularity": 5.072, + "poster_path": "/qIvTMHX2MIYG2Ij4jP5dkKgMqUo.jpg", + "release_date": "2023-07-28", + "title": "Batman", + "video": false, + "vote_average": 6.0, + "vote_count": 3 + }, + { + "adult": false, + "backdrop_path": "/tRS6jvPM9qPrrnx2KRp3ew96Yot.jpg", + "genre_ids": [ + 80, + 9648, + 53 + ], + "id": 414906, + "original_language": "en", + "original_title": "The Batman", + "overview": "In his second year of fighting crime, Batman uncovers corruption in Gotham City that connects to his own family while facing a serial killer known as the Riddler.", + "popularity": 204.53, + "poster_path": "/74xTEgt7R36Fpooo50r9T25onhq.jpg", + "release_date": "2022-03-01", + "title": "The Batman", + "video": false, + "vote_average": 7.7, + "vote_count": 8819 + }, + { + "adult": false, + "backdrop_path": "/5fX1oSGuYdKgwWmUTAN5MNSQGzr.jpg", + "genre_ids": [ + 28, + 12, + 14 + ], + "id": 209112, + "original_language": "en", + "original_title": "Batman v Superman: Dawn of Justice", + "overview": "Fearing the actions of a god-like Super Hero left unchecked, Gotham City’s own formidable, forceful vigilante takes on Metropolis’s most revered, modern-day savior, while the world wrestles with what sort of hero it really needs. And with Batman and Superman at war with one another, a new threat quickly arises, putting mankind in greater danger than it’s ever known before.", + "popularity": 93.975, + "poster_path": "/5UsK3grJvtQrtzEgqNlDljJW96w.jpg", + "release_date": "2016-03-23", + "title": "Batman v Superman: Dawn of Justice", + "video": false, + "vote_average": 5.956, + "vote_count": 17210 + }, + { + "adult": false, + "backdrop_path": "/8pOUmMgVnl1tYNtTRTE5TeyGBGD.jpg", + "genre_ids": [ + 16, + 28, + 878 + ], + "id": 485942, + "original_language": "ja", + "original_title": "ニンジャバットマン", + "overview": "Batman, along with many of his allies and adversaries, finds himself transported to feudal Japan by Gorilla Grodd's time displacement machine.", + "popularity": 28.396, + "poster_path": "/5xSB0Npkc9Fd9kahKBsq9P4Cdzp.jpg", + "release_date": "2018-06-15", + "title": "Batman Ninja", + "video": false, + "vote_average": 5.8, + "vote_count": 785 + }, + { + "adult": false, + "backdrop_path": "/lh5lbisD4oDbEKgUxoRaZU8HVrk.jpg", + "genre_ids": [ + 28, + 80, + 18 + ], + "id": 272, + "original_language": "en", + "original_title": "Batman Begins", + "overview": "Driven by tragedy, billionaire Bruce Wayne dedicates his life to uncovering and defeating the corruption that plagues his home, Gotham City. Unable to work within the system, he instead creates a new identity, a symbol of fear for the criminal underworld - The Batman.", + "popularity": 79.782, + "poster_path": "/4MpN4kIEqUjW8OPtOQJXlTdHiJV.jpg", + "release_date": "2005-06-10", + "title": "Batman Begins", + "video": false, + "vote_average": 7.7, + "vote_count": 19783 + }, + { + "adult": false, + "backdrop_path": "/7eccX0xay9pDj6ZQvU4cu3whw18.jpg", + "genre_ids": [ + 16, + 14, + 27, + 28, + 9648 + ], + "id": 1003579, + "original_language": "en", + "original_title": "Batman: The Doom That Came to Gotham", + "overview": "Explorer Bruce Wayne accidentally unleashes an ancient evil, and returns to Gotham after being away for two decades. There, Batman battles Lovecraftian supernatural forces and encounters allies and enemies such as Green Arrow, Ra's al Ghul, Mr. Freeze, Killer Croc, Two-Face and James Gordon.", + "popularity": 46.754, + "poster_path": "/dzPNQXI8FlpXTGGp1082RJ8OQoT.jpg", + "release_date": "2023-03-10", + "title": "Batman: The Doom That Came to Gotham", + "video": false, + "vote_average": 6.726, + "vote_count": 157 + }, + { + "adult": false, + "backdrop_path": "/3WP0RObZ2t7ShHfqQpKPljF9B22.jpg", + "genre_ids": [ + 28, + 14 + ], + "id": 364, + "original_language": "en", + "original_title": "Batman Returns", + "overview": "While Batman deals with a deformed man calling himself the Penguin, an employee of a corrupt businessman transforms into the Catwoman.", + "popularity": 52.985, + "poster_path": "/jKBjeXM7iBBV9UkUcOXx3m7FSHY.jpg", + "release_date": "1992-06-19", + "title": "Batman Returns", + "video": false, + "vote_average": 6.919, + "vote_count": 6051 + }, + { + "adult": false, + "backdrop_path": "/tgPFZxhDuxWd4VXYaz8eAUznGTF.jpg", + "genre_ids": [ + 28, + 878, + 12 + ], + "id": 415, + "original_language": "en", + "original_title": "Batman & Robin", + "overview": "Batman and Robin deal with relationship issues while preventing Mr. Freeze and Poison Ivy from attacking Gotham City.", + "popularity": 45.997, + "poster_path": "/cGRDufDDSrFrv7VI4YnmWnslne0.jpg", + "release_date": "1997-06-20", + "title": "Batman & Robin", + "video": false, + "vote_average": 4.336, + "vote_count": 4667 + }, + { + "adult": false, + "backdrop_path": "/eoMushgujydxFplE9yPZ54lwOvo.jpg", + "genre_ids": [ + 16, + 28, + 35, + 10751 + ], + "id": 324849, + "original_language": "en", + "original_title": "The Lego Batman Movie", + "overview": "A cooler-than-ever Bruce Wayne must deal with the usual suspects as they plan to rule Gotham City, while discovering that he has accidentally adopted a teenage orphan who wishes to become his sidekick.", + "popularity": 73.499, + "poster_path": "/snGwr2gag4Fcgx2OGmH9otl6ofW.jpg", + "release_date": "2017-02-08", + "title": "The Lego Batman Movie", + "video": false, + "vote_average": 7.225, + "vote_count": 4639 + }, + { + "adult": false, + "backdrop_path": "/98kbLdg6rDqhYySxROTluRbLy5t.jpg", + "genre_ids": [ + 28, + 80, + 14 + ], + "id": 414, + "original_language": "en", + "original_title": "Batman Forever", + "overview": "Batman must battle a disfigured district attorney and a disgruntled former employee with help from an amorous psychologist and a young circus acrobat.", + "popularity": 38.719, + "poster_path": "/mzzNBVwTiiY94xAXDMWJpNPW2US.jpg", + "release_date": "1995-06-16", + "title": "Batman Forever", + "video": false, + "vote_average": 5.408, + "vote_count": 4826 + }, + { + "adult": false, + "backdrop_path": "/sA50fD5aLbYPRU0fMCHIZ88gc5g.jpg", + "genre_ids": [ + 16, + 28, + 10751 + ], + "id": 581997, + "original_language": "en", + "original_title": "Batman vs Teenage Mutant Ninja Turtles", + "overview": "Batman, Batgirl and Robin forge an alliance with the Teenage Mutant Ninja Turtles to fight against the Turtles' sworn enemy, The Shredder, who has apparently teamed up with Ra's Al Ghul and The League of Assassins.", + "popularity": 29.836, + "poster_path": "/yP3h0Pu8htyb9450mWJ9Vu1rU.jpg", + "release_date": "2019-03-31", + "title": "Batman vs Teenage Mutant Ninja Turtles", + "video": false, + "vote_average": 7.126, + "vote_count": 432 + }, + { + "adult": false, + "backdrop_path": "/iQJ1gC2p6yn5wnBEklhPaEFJ3n1.jpg", + "genre_ids": [ + 16, + 28, + 878 + ], + "id": 886396, + "original_language": "en", + "original_title": "Batman and Superman: Battle of the Super Sons", + "overview": "After discovering he has powers, 11-year-old Jonathan Kent and assassin-turned-Boy-Wonder Damian Wayne must join forces to rescue their fathers (Superman & Batman) and save the planet from the malevolent alien force known as Starro.", + "popularity": 31.009, + "poster_path": "/mvffaexT5kA3chOnGxwBSlRoshh.jpg", + "release_date": "2022-10-17", + "title": "Batman and Superman: Battle of the Super Sons", + "video": false, + "vote_average": 7.687, + "vote_count": 252 + }, + { + "adult": false, + "backdrop_path": "/niRgVCgvDVxD67u6gjKZnkBO1AD.jpg", + "genre_ids": [ + 878, + 16, + 28, + 80, + 53 + ], + "id": 13851, + "original_language": "en", + "original_title": "Batman: Gotham Knight", + "overview": "A chronicle of Bruce Wayne's establishment and progression into Gotham City’s legendary caped crusader through 6 standalone episodes.", + "popularity": 34.653, + "poster_path": "/3i1o0sHBP0VUpuSVmkdCRKYoDBC.jpg", + "release_date": "2008-07-08", + "title": "Batman: Gotham Knight", + "video": false, + "vote_average": 6.67, + "vote_count": 616 + }, + { + "adult": false, + "backdrop_path": "/bNMw3onveTYU7PpLQRK0HQK8JRb.jpg", + "genre_ids": [ + 28, + 16, + 80 + ], + "id": 69735, + "original_language": "en", + "original_title": "Batman: Year One", + "overview": "A wealthy playboy named Bruce Wayne and a Chicago cop named Jim Gordon both return to Gotham City where their lives unexpectedly intersect.", + "popularity": 32.523, + "poster_path": "/mLZRhulJcDsxZWTdfx0trtk6y07.jpg", + "release_date": "2011-09-27", + "title": "Batman: Year One", + "video": false, + "vote_average": 7.284, + "vote_count": 873 + }, + { + "adult": false, + "backdrop_path": "/74H4XXU0q22TSrkPmlqkcWoX5ZZ.jpg", + "genre_ids": [ + 878, + 28, + 12, + 16 + ], + "id": 45162, + "original_language": "en", + "original_title": "Superman/Batman: Apocalypse", + "overview": "Batman discovers a mysterious teen-aged girl with superhuman powers and a connection to Superman. When the girl comes to the attention of Darkseid, the evil overlord of Apokolips, events take a decidedly dangerous turn.", + "popularity": 20.1, + "poster_path": "/d7gHmsA2o5Z1MhcuspMyOSO48KB.jpg", + "release_date": "2010-09-28", + "title": "Superman/Batman: Apocalypse", + "video": false, + "vote_average": 7.2, + "vote_count": 639 + }, + { + "adult": false, + "backdrop_path": "/2Li2vaWeCIMYwcgC9yU3Z99LDVL.jpg", + "genre_ids": [ + 12, + 14, + 16, + 28, + 878 + ], + "id": 21683, + "original_language": "en", + "original_title": "Batman: Mystery of the Batwoman", + "overview": "As if the Penguin wasn't enough to contend with, a new vigilante has surfaced in Gotham City, and her strong-arm tactics give Batman cause for concern.", + "popularity": 34.176, + "poster_path": "/mlmhpUArJdpRPO211v3lETe3uzg.jpg", + "release_date": "2003-10-21", + "title": "Batman: Mystery of the Batwoman", + "video": false, + "vote_average": 6.687, + "vote_count": 352 + }, + { + "adult": false, + "backdrop_path": "/9Eh5xzWTpJeZM1FGCblWKZ8GTpw.jpg", + "genre_ids": [ + 878, + 28, + 16, + 9648 + ], + "id": 142061, + "original_language": "en", + "original_title": "Batman: The Dark Knight Returns, Part 2", + "overview": "Batman has stopped the reign of terror that The Mutants had cast upon his city. Now an old foe wants a reunion and the government wants The Man of Steel to put a stop to Batman.", + "popularity": 39.477, + "poster_path": "/arEZYd6uMOFTILne9Ux0A8qctMe.jpg", + "release_date": "2013-01-03", + "title": "Batman: The Dark Knight Returns, Part 2", + "video": false, + "vote_average": 7.923, + "vote_count": 1361 + } + ], + "total_pages": 8, + "total_results": 157 +} \ No newline at end of file diff --git a/spec/fixtures/top_twenty_movies.json b/spec/fixtures/top_twenty_movies.json new file mode 100644 index 000000000..858df9945 --- /dev/null +++ b/spec/fixtures/top_twenty_movies.json @@ -0,0 +1,405 @@ +{ + "page": 1, + "results": [ + { + "adult": false, + "backdrop_path": "/xgGGinKRL8xeRkaAR9RMbtyk60y.jpg", + "genre_ids": [ + 16, + 10751, + 10402, + 14, + 35 + ], + "id": 901362, + "original_language": "en", + "original_title": "Trolls Band Together", + "overview": "Rylan McFadden is awesome", + "popularity": 1839.78, + "poster_path": "/qV4fdXXUm5xNlEJ2jw7af3XxuQB.jpg", + "release_date": "2023-10-12", + "title": "Trolls Band Together", + "video": false, + "vote_average": 7.215, + "vote_count": 195 + }, + { + "adult": false, + "backdrop_path": "/fm6KqXpk3M2HVveHwCrBSSBaO0V.jpg", + "genre_ids": [ + 18, + 36 + ], + "id": 872585, + "original_language": "en", + "original_title": "Oppenheimer", + "overview": "The story of J. Robert Oppenheimer's role in the development of the atomic bomb during World War II.", + "popularity": 1672.982, + "poster_path": "/8Gxv8gSFCU0XGDykEGv7zR1n2ua.jpg", + "release_date": "2023-07-19", + "title": "Oppenheimer", + "video": false, + "vote_average": 8.163, + "vote_count": 4984 + }, + { + "adult": false, + "backdrop_path": "/kjQBrc00fB2RjHZB3PGR4w9ibpz.jpg", + "genre_ids": [ + 878, + 28, + 53 + ], + "id": 670292, + "original_language": "en", + "original_title": "The Creator", + "overview": "Amid a future war between the human race and the forces of artificial intelligence, a hardened ex-special forces agent grieving the disappearance of his wife, is recruited to hunt down and kill the Creator, the elusive architect of advanced AI who has developed a mysterious weapon with the power to end the war—and mankind itself.", + "popularity": 1335.428, + "poster_path": "/vBZ0qvaRxqEhZwl6LWmruJqWE8Z.jpg", + "release_date": "2023-09-27", + "title": "The Creator", + "video": false, + "vote_average": 7.153, + "vote_count": 1184 + }, + { + "adult": false, + "backdrop_path": "/9PqD3wSIjntyJDBzMNuxuKHwpUD.jpg", + "genre_ids": [ + 16, + 35, + 10751 + ], + "id": 1075794, + "original_language": "en", + "original_title": "Leo", + "overview": "Rylan McFadden is awesome", + "popularity": 1267.179, + "poster_path": "/pD6sL4vntUOXHmuvJPPZAgvyfd9.jpg", + "release_date": "2023-11-17", + "title": "Leo", + "video": false, + "vote_average": 7.943, + "vote_count": 237 + }, + { + "adult": false, + "backdrop_path": "/t5zCBSB5xMDKcDqe91qahCOUYVV.jpg", + "genre_ids": [ + 27, + 9648 + ], + "id": 507089, + "original_language": "en", + "original_title": "Five Nights at Freddy's", + "overview": "Recently fired and desperate for work, a troubled young man named Mike agrees to take a position as a night security guard at an abandoned theme restaurant: Freddy Fazbear's Pizzeria. But he soon discovers that nothing at Freddy's is what it seems.", + "popularity": 1077.066, + "poster_path": "/j9mH1pr3IahtraTWxVEMANmPSGR.jpg", + "release_date": "2023-10-25", + "title": "Five Nights at Freddy's", + "video": false, + "vote_average": 7.864, + "vote_count": 2564 + }, + { + "adult": false, + "backdrop_path": "/wl4NWiZwpzZH67HiDgpDImLyds9.jpg", + "genre_ids": [ + 28, + 12, + 53 + ], + "id": 299054, + "original_language": "en", + "original_title": "Expend4bles", + "overview": "Armed with every weapon they can get their hands on and the skills to use them, The Expendables are the world’s last line of defense and the team that gets called when all other options are off the table. But new team members with new styles and tactics are going to give “new blood” a whole new meaning.", + "popularity": 889.087, + "poster_path": "/iwsMu0ehRPbtaSxqiaUDQB9qMWT.jpg", + "release_date": "2023-09-15", + "title": "Expend4bles", + "video": false, + "vote_average": 6.431, + "vote_count": 810 + }, + { + "adult": false, + "backdrop_path": "/28er4p7B5zMSxUDQKPF1hBsgnys.jpg", + "genre_ids": [ + 28, + 12, + 53 + ], + "id": 872906, + "original_language": "hi", + "original_title": "जवान", + "overview": "An emotional journey of a prison warden, driven by a personal vendetta while keeping up to a promise made years ago, recruits inmates to commit outrageous crimes that shed light on corruption and injustice, in an attempt to get even with his past, and that leads him to an unexpected reunion.", + "popularity": 784.233, + "poster_path": "/jFt1gS4BGHlK8xt76Y81Alp4dbt.jpg", + "release_date": "2023-09-07", + "title": "Jawan", + "video": false, + "vote_average": 7.146, + "vote_count": 120 + }, + { + "adult": false, + "backdrop_path": "/4XM8DUTQb3lhLemJC51Jx4a2EuA.jpg", + "genre_ids": [ + 28, + 80, + 53 + ], + "id": 385687, + "original_language": "en", + "original_title": "Fast X", + "overview": "Over many missions and against impossible odds, Dom Toretto and his family have outsmarted, out-nerved and outdriven every foe in their path. Now, they confront the most lethal opponent they've ever faced: A terrifying threat emerging from the shadows of the past who's fueled by blood revenge, and who is determined to shatter this family and destroy everything—and everyone—that Dom loves, forever.", + "popularity": 759.254, + "poster_path": "/fiVW06jE7z9YnO4trhaMEdclSiC.jpg", + "release_date": "2023-05-17", + "title": "Fast X", + "video": false, + "vote_average": 7.203, + "vote_count": 4348 + }, + { + "adult": false, + "backdrop_path": "/628Dep6AxEtDxjZoGP78TsOxYbK.jpg", + "genre_ids": [ + 28, + 53 + ], + "id": 575264, + "original_language": "en", + "original_title": "Mission: Impossible - Dead Reckoning Part One", + "overview": "Ethan Hunt and his IMF team embark on their most dangerous mission yet: To track down a terrifying new weapon that threatens all of humanity before it falls into the wrong hands. With control of the future and the world's fate at stake and dark forces from Ethan's past closing in, a deadly race around the globe begins. Confronted by a mysterious, all-powerful enemy, Ethan must consider that nothing can matter more than his mission—not even the lives of those he cares about most.", + "popularity": 720.588, + "poster_path": "/NNxYkU70HPurnNCSiCjYAmacwm.jpg", + "release_date": "2023-07-08", + "title": "Mission: Impossible - Dead Reckoning Part One", + "video": false, + "vote_average": 7.6, + "vote_count": 2562 + }, + { + "adult": false, + "backdrop_path": "/f1AQhx6ZfGhPZFTVKgxG91PhEYc.jpg", + "genre_ids": [ + 18, + 36, + 10752 + ], + "id": 753342, + "original_language": "en", + "original_title": "Napoleon", + "overview": "An epic that details the checkered rise and fall of French Emperor Napoleon Bonaparte and his relentless journey to power through the prism of his addictive, volatile relationship with his wife, Josephine.", + "popularity": 670.48, + "poster_path": "/jE5o7y9K6pZtWNNMEw3IdpHuncR.jpg", + "release_date": "2023-11-22", + "title": "Napoleon", + "video": false, + "vote_average": 6.443, + "vote_count": 333 + }, + { + "adult": false, + "backdrop_path": "/7dCzb1oa7ACYi66VIrE1wqmftAa.jpg", + "genre_ids": [ + 28 + ], + "id": 660521, + "original_language": "en", + "original_title": "The Mercenary", + "overview": "When a mission in South America goes wrong a mercenary is left for dead, but he is nursed back to health and reborn with a new outlook on life. But his peaceful days are short-lived when mercenaries he used to work with cross his path again and he is forced to revisit and face his own demons.", + "popularity": 562.037, + "poster_path": "/p3wgefagejlefFEDsLRHiXU7NGu.jpg", + "release_date": "2020-01-07", + "title": "The Mercenary", + "video": false, + "vote_average": 6.25, + "vote_count": 22 + }, + { + "adult": false, + "backdrop_path": "/jAW3L7N5ePEnIsBQP5vnmhw1qbl.jpg", + "genre_ids": [ + 80, + 28, + 53 + ], + "id": 958263, + "original_language": "ko", + "original_title": "독전 2", + "overview": "A determined detective continues his search for the truth behind Asia's largest drug organization and its elusive boss he has unfinished business with.", + "popularity": 559.335, + "poster_path": "/g9aDZSqH5KmsHbMurhni5d2wq6q.jpg", + "release_date": "2023-10-05", + "title": "Believer 2", + "video": false, + "vote_average": 7.0, + "vote_count": 36 + }, + { + "adult": false, + "backdrop_path": "/tC78Pck2YCsUAtEdZwuHYUFYtOj.jpg", + "genre_ids": [ + 28, + 53, + 80 + ], + "id": 926393, + "original_language": "en", + "original_title": "The Equalizer 3", + "overview": "Robert McCall finds himself at home in Southern Italy but he discovers his friends are under the control of local crime bosses. As events turn deadly, McCall knows what he has to do: become his friends' protector by taking on the mafia.", + "popularity": 555.986, + "poster_path": "/b0Ej6fnXAP8fK75hlyi2jKqdhHz.jpg", + "release_date": "2023-08-30", + "title": "The Equalizer 3", + "video": false, + "vote_average": 7.424, + "vote_count": 1742 + }, + { + "adult": false, + "backdrop_path": "/5a4JdoFwll5DRtKMe7JLuGQ9yJm.jpg", + "genre_ids": [ + 28, + 12, + 878 + ], + "id": 695721, + "original_language": "en", + "original_title": "The Hunger Games: The Ballad of Songbirds & Snakes", + "overview": "64 years before he becomes the tyrannical president of Panem, Coriolanus Snow sees a chance for a change in fortunes when he mentors Lucy Gray Baird, the female tribute from District 12.", + "popularity": 553.155, + "poster_path": "/mBaXZ95R2OxueZhvQbcEWy2DqyO.jpg", + "release_date": "2023-11-15", + "title": "The Hunger Games: The Ballad of Songbirds & Snakes", + "video": false, + "vote_average": 7.297, + "vote_count": 454 + }, + { + "adult": false, + "backdrop_path": "/2X7BAu7x2oMB3cTMF38uJhGSqoB.jpg", + "genre_ids": [ + 36, + 28, + 18 + ], + "id": 606870, + "original_language": "en", + "original_title": "The Survivor", + "overview": "Harry Haft is a boxer who fought fellow prisoners in the concentration camps to survive. Haunted by the memories and his guilt, he attempts to use high-profile fights against boxing legends like Rocky Marciano as a way to find his first love again.", + "popularity": 503.03, + "poster_path": "/oZWJ20tGWZ5xO9CrTCVavmDRy7J.jpg", + "release_date": "2022-04-07", + "title": "The Survivor", + "video": false, + "vote_average": 7.215, + "vote_count": 114 + }, + { + "adult": false, + "backdrop_path": "/5mzr6JZbrqnqD8rCEvPhuCE5Fw2.jpg", + "genre_ids": [ + 28, + 878, + 27 + ], + "id": 615656, + "original_language": "en", + "original_title": "Meg 2: The Trench", + "overview": "An exploratory dive into the deepest depths of the ocean of a daring research team spirals into chaos when a malevolent mining operation threatens their mission and forces them into a high-stakes battle for survival.", + "popularity": 498.577, + "poster_path": "/4m1Au3YkjqsxF8iwQy0fPYSxE0h.jpg", + "release_date": "2023-08-02", + "title": "Meg 2: The Trench", + "video": false, + "vote_average": 6.744, + "vote_count": 2594 + }, + { + "adult": false, + "backdrop_path": "/3H9NA1KWEQN0ItL3Wl3SFZYP6yV.jpg", + "genre_ids": [ + 28, + 878, + 12 + ], + "id": 565770, + "original_language": "en", + "original_title": "Blue Beetle", + "overview": "Recent college grad Jaime Reyes returns home full of aspirations for his future, only to find that home is not quite as he left it. As he searches to find his purpose in the world, fate intervenes when Jaime unexpectedly finds himself in possession of an ancient relic of alien biotechnology: the Scarab.", + "popularity": 493.911, + "poster_path": "/mXLOHHc1Zeuwsl4xYKjKh2280oL.jpg", + "release_date": "2023-08-16", + "title": "Blue Beetle", + "video": false, + "vote_average": 6.945, + "vote_count": 1750 + }, + { + "adult": false, + "backdrop_path": "/feSiISwgEpVzR1v3zv2n2AU4ANJ.jpg", + "genre_ids": [ + 878, + 12, + 28 + ], + "id": 609681, + "original_language": "en", + "original_title": "The Marvels", + "overview": "Carol Danvers, aka Captain Marvel, has reclaimed her identity from the tyrannical Kree and taken revenge on the Supreme Intelligence. But unintended consequences see Carol shouldering the burden of a destabilized universe. When her duties send her to an anomalous wormhole linked to a Kree revolutionary, her powers become entangled with that of Jersey City super-fan Kamala Khan, aka Ms. Marvel, and Carol’s estranged niece, now S.A.B.E.R. astronaut Captain Monica Rambeau. Together, this unlikely trio must team up and learn to work in concert to save the universe.", + "popularity": 492.065, + "poster_path": "/Ag3D9qXjhJ2FUkrlJ0Cv1pgxqYQ.jpg", + "release_date": "2023-11-08", + "title": "The Marvels", + "video": false, + "vote_average": 6.582, + "vote_count": 564 + }, + { + "adult": false, + "backdrop_path": null, + "genre_ids": [ + 28, + 16 + ], + "id": 116776, + "original_language": "ja", + "original_title": "ドラゴンボール 魔訶不思議大冒険", + "overview": "Master Roshi has succeeded at the one mission he valued most: to train Goku and Krillin to become ultimate fighters. So, he arranges for them to test their mettle at a competition hosted by Emperor Chiaotzu. Not everyone's playing by the rules, however, as a member of the ruler's household schemes to use the Dragonballs to extort money and power from the royal.", + "popularity": 490.916, + "poster_path": "/5aXG0B3TYTpQsodXzvYCkKQfpB1.jpg", + "release_date": "1988-07-09", + "title": "Dragon Ball: Mystical Adventure", + "video": false, + "vote_average": 6.803, + "vote_count": 223 + }, + { + "adult": false, + "backdrop_path": "/9n2tJBplPbgR2ca05hS5CKXwP2c.jpg", + "genre_ids": [ + 16, + 10751, + 12, + 14, + 35 + ], + "id": 502356, + "original_language": "en", + "original_title": "The Super Mario Bros. Movie", + "overview": "While working underground to fix a water main, Brooklyn plumbers—and brothers—Mario and Luigi are transported down a mysterious pipe and wander into a magical new world. But when the brothers are separated, Mario embarks on an epic quest to find Luigi.", + "popularity": 490.291, + "poster_path": "/qNBAXBIQlnOThrVvA6mA2B5ggV6.jpg", + "release_date": "2023-04-05", + "title": "The Super Mario Bros. Movie", + "video": false, + "vote_average": 7.747, + "vote_count": 7265 + } + ], + "total_pages": 41539, + "total_results": 830768 +} \ No newline at end of file diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 327b58ea1..6352e7421 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -3,6 +3,7 @@ # The generated `.rspec` file contains `--require spec_helper` which will cause # this file to always be loaded, without a need to explicitly require it in any # files. +require 'webmock/rspec' # # Given that it is always loaded, you are encouraged to keep this file as # light-weight as possible. Requiring heavyweight dependencies from this file From be435f83d10b1125ec0e86788e948fe1404812dd Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Tue, 28 Nov 2023 16:30:32 -0700 Subject: [PATCH 07/24] Added check for data in top 20 fixture --- spec/features/users/movies/index_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/features/users/movies/index_spec.rb b/spec/features/users/movies/index_spec.rb index c77ad3097..2a0768f65 100644 --- a/spec/features/users/movies/index_spec.rb +++ b/spec/features/users/movies/index_spec.rb @@ -25,8 +25,8 @@ expect(page.status_code).to eq 200 - expect(page).to have_link("The Equalizer 3") - expect(page).to have_content(7.3) + expect(page).to have_link("Trolls Band Together") + expect(page).to have_content(7.215) end it 'Get searched movies' do From 539e132fe90502369840b384752224c3af955df5 Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Tue, 28 Nov 2023 20:59:05 -0600 Subject: [PATCH 08/24] add features and testing for the Landing Page --- app/controllers/home_controller.rb | 5 +++++ app/views/home/index.html.erb | 13 ++++++++++++ app/views/layouts/application.html.erb | 2 ++ config/routes.rb | 2 +- spec/features/home/index_spec.rb | 29 ++++++++++++++++++++++++++ 5 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 app/controllers/home_controller.rb create mode 100644 app/views/home/index.html.erb create mode 100644 spec/features/home/index_spec.rb diff --git a/app/controllers/home_controller.rb b/app/controllers/home_controller.rb new file mode 100644 index 000000000..bb916a9d1 --- /dev/null +++ b/app/controllers/home_controller.rb @@ -0,0 +1,5 @@ +class HomeController < ApplicationController + def index + @users = User.all + end +end \ No newline at end of file diff --git a/app/views/home/index.html.erb b/app/views/home/index.html.erb new file mode 100644 index 000000000..feed31e7f --- /dev/null +++ b/app/views/home/index.html.erb @@ -0,0 +1,13 @@ +

Viewing Party Lite

+ +<%= form_with url: new_user_path, method: :get do %> + <%= submit_tag 'Create New User', class: 'btn btn-primary' %> +<% end %> + +

List of Existing Users

+
    + <% @users.each do |user| %> +
  • <%= link_to user.name, user_path(user) %>
  • + <% end %> +
+ diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 552042a39..4810cad91 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -11,6 +11,8 @@ + <%= link_to 'Go back to Landing Page', root_path %> + <%= yield %> diff --git a/config/routes.rb b/config/routes.rb index bac3be522..ea8474b5a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ # Defines the root path route ("/") # root "articles#index" - + root 'home#index' resources :users, only: [:new, :create, :show] do resources :discover, only: [:index] resources :movies, only: [:index, :show] diff --git a/spec/features/home/index_spec.rb b/spec/features/home/index_spec.rb new file mode 100644 index 000000000..f89a01d95 --- /dev/null +++ b/spec/features/home/index_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +RSpec.describe 'Home', type: :feature do + before(:each) do + load_test_data + end + describe 'GET /' do + it 'displays the title of the application' do + visit '/' + expect(page).to have_content('Viewing Party Lite') + end + + it 'displays a button to create a new user' do + visit '/' + expect(page).to have_button('Create New User') + end + + it 'displays a list of existing users with links to their dashboards' do + visit '/' + expect(page).to have_link(@user1.name, href: user_path(@user1)) + expect(page).to have_link(@user2.name, href: user_path(@user2)) + end + + it 'displays a link to go back to the landing page' do + visit '/' + expect(page).to have_link('Go back to Landing Page', href: root_path) + end + end +end From 8c2c85378dd4534c0f5e602313c487416ad3bbcd Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Tue, 28 Nov 2023 22:11:24 -0600 Subject: [PATCH 09/24] add feature and tests for the user registration page --- .DS_Store | Bin 0 -> 6148 bytes app/controllers/users_controller.rb | 24 ++++++++++++++++++++++++ app/views/users/new.html.erb | 17 +++++++++++++++++ app/views/users/show.html.erb | 1 + config/routes.rb | 2 ++ spec/features/users/new_spec.rb | 25 +++++++++++++++++++++++++ 6 files changed, 69 insertions(+) create mode 100644 .DS_Store create mode 100644 app/controllers/users_controller.rb create mode 100644 app/views/users/new.html.erb create mode 100644 app/views/users/show.html.erb create mode 100644 spec/features/users/new_spec.rb diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..da07aa6853bb7b7687f6e861317c0d52c61a4ec7 GIT binary patch literal 6148 zcmeH~J!%6%427R!7lt%jx}3%b$PET#pTHN0A&|z{CXm!~^gR7ES*H$5cmnB-G%I%Z zD|S`@Z2$T80!#olbXV*=%*>dtaK;_?uhYl%a=X5>;#J@&VrHyNnC;iLL0pQvfVyTmjO&;ssLc!1UOG})p;=82 zR;?Ceh}WZ?+UmMqI#RP8R>OzYoz15hnq@nzF`-!xQ4j$Um=RcIKKc27r2jVm&svm< zfC&6E0=7P!4tu^-ovjbA=k?dB`g+i*aXG_}p8zI)6mRKa+;6_1_R^8c3Qa!(fk8n8 H{*=Hspa&6( literal 0 HcmV?d00001 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 000000000..575ed1ddf --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,24 @@ +class UsersController < ApplicationController + def new + @user = User.new + end + + def create + @user = User.new(user_params) + if @user.save + redirect_to user_path(@user) + else + render :new + end + end + + def show + @user = User.find(params[:id]) + end + + private + + def user_params + params.require(:user).permit(:name, :email, :password) + end +end diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 000000000..e2ca715cc --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,17 @@ +

Register

+ +<%= form_for @user do |f| %> +
+ <%= f.label :name %> + <%= f.text_field :name, class: 'form-control' %> +
+
+ <%= f.label :email %> + <%= f.email_field :email, class: 'form-control' %> +
+
+ <%= f.label :password %> + <%= f.password_field :password, class: 'form-control' %> +
+ <%= f.submit 'Register', class: 'btn btn-primary' %> + <%end%> \ No newline at end of file diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb new file mode 100644 index 000000000..7e16c2f7a --- /dev/null +++ b/app/views/users/show.html.erb @@ -0,0 +1 @@ +

Welcome, <%= @user.name %>!

\ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index ea8474b5a..6cdc14541 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,6 +4,8 @@ # Defines the root path route ("/") # root "articles#index" root 'home#index' + get '/register', to: 'users#new' + resources :users, only: [:new, :create, :show] do resources :discover, only: [:index] resources :movies, only: [:index, :show] diff --git a/spec/features/users/new_spec.rb b/spec/features/users/new_spec.rb new file mode 100644 index 000000000..015acc236 --- /dev/null +++ b/spec/features/users/new_spec.rb @@ -0,0 +1,25 @@ +require 'rails_helper' + +RSpec.describe 'User Registration', type: :feature do + before(:each) do + load_test_data + end + + it 'displays a registration form when visiting the "/register" path' do + visit '/register' + expect(page).to have_field('Name') + expect(page).to have_field('Email') + expect(page).to have_field('Password') + expect(page).to have_button('Register') + end + + it 'redirects to the user dashboard page after successful registration' do + visit '/register' + fill_in 'Name', with: 'John Doe' + fill_in 'Email', with: 'john@example.com' + fill_in 'Password', with: 'Sooners!2022' + click_button 'Register' + user = User.find_by(email: 'john@example.com') + expect(current_path).to eq("/users/#{user.id}") + end +end From dfec49670985faf8d1170b872dc865e745ee0512 Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Tue, 28 Nov 2023 22:47:08 -0600 Subject: [PATCH 10/24] add html for users show page and testing --- app/views/users/show.html.erb | 9 ++++++++- spec/features/users/new_spec.rb | 2 +- spec/features/users/show_spec.rb | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 spec/features/users/show_spec.rb diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 7e16c2f7a..965da8b24 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -1 +1,8 @@ -

Welcome, <%= @user.name %>!

\ No newline at end of file +

<%= @user.name %>'s Dashboard!

+ +<%= button_to 'Discover Movies', user_discover_index_path(@user), class: 'btn btn-primary' %> + +
+

Viewing Parties

+ +
\ No newline at end of file diff --git a/spec/features/users/new_spec.rb b/spec/features/users/new_spec.rb index 015acc236..16d89c415 100644 --- a/spec/features/users/new_spec.rb +++ b/spec/features/users/new_spec.rb @@ -22,4 +22,4 @@ user = User.find_by(email: 'john@example.com') expect(current_path).to eq("/users/#{user.id}") end -end +end \ No newline at end of file diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb new file mode 100644 index 000000000..93807d688 --- /dev/null +++ b/spec/features/users/show_spec.rb @@ -0,0 +1,23 @@ +require 'rails_helper' + +RSpec.describe 'User show page', type: :feature do + + before(:each) do + load_test_data + visit "/users/#{@user1.id}" + end + + it "displays the user's name and 'Dashboard' at the top of the page" do + expect(page).to have_content("#{@user1.name}'s Dashboard") + end + + it "displays a 'Discover Movies' button" do + expect(page).to have_button('Discover Movies') + end + + it 'displays a section that lists viewing parties' do + within('section.viewing-parties') do + expect(page).to have_css('h2', text: 'Viewing Parties') + end + end +end From ce6c5b8907fa53245d50e45932c3ab9e0e8aa58c Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Wed, 29 Nov 2023 11:15:32 -0700 Subject: [PATCH 11/24] Add test for movie details, include webmock and json fixtures. Also a utility class for getting movie runtime in minutes, hand rolled route for it; may change later. --- app/controllers/movies_controller.rb | 8 +- app/controllers/viewing_parties_controller.rb | 29 + app/models/utility.rb | 8 + app/views/layouts/application.html.erb | 1 + app/views/movies/show.html.erb | 39 + app/views/viewing_parties/new.html.erb | 0 config/routes.rb | 2 + spec/features/users/movies/show_spec.rb | 83 + spec/fixtures/specific_movie.json | 80 + spec/fixtures/specific_movie_credits.json | 2588 +++++++++++++++++ spec/fixtures/specific_movie_reviews.json | 120 + 11 files changed, 2954 insertions(+), 4 deletions(-) create mode 100644 app/controllers/viewing_parties_controller.rb create mode 100644 app/models/utility.rb create mode 100644 app/views/movies/show.html.erb create mode 100644 app/views/viewing_parties/new.html.erb create mode 100644 spec/fixtures/specific_movie.json create mode 100644 spec/fixtures/specific_movie_credits.json create mode 100644 spec/fixtures/specific_movie_reviews.json diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index b1575e12a..7ec8b85b9 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -11,8 +11,8 @@ def index def show facade = MovieFacade.new - @data = facade.movie_details(params[:id]) - @data2 = facade.movie_cast(params[:id]) - @data3 = facade.movie_reviews(params[:id]) - end + @movie_details = facade.movie_details(params[:id]) + @movie_cast = facade.movie_cast(params[:id]) + @movie_review = facade.movie_reviews(params[:id]) + end end \ No newline at end of file diff --git a/app/controllers/viewing_parties_controller.rb b/app/controllers/viewing_parties_controller.rb new file mode 100644 index 000000000..1d3c552ac --- /dev/null +++ b/app/controllers/viewing_parties_controller.rb @@ -0,0 +1,29 @@ +class ViewingPartiesController < ApplicationController + def new + facade = MovieFacade.new + @user = User.find(params[:user_id]) + @users = User.where("id != #{params[:user_id]}") + @movie = facade.movie_details(params[:movid_id]) + @party = @user.parties.new + end + + def create + facade = MovieFacade.new + @user = User.find(params[:user_id]) + @users = User.where("id != #{params[:user_id]}") + @movie = facade.movie_details(params[:movid_id]) + @party = @user.parties.new(movie_id: @movie[:id], movie_title: @movie[:title], duration: params[:duration], date: params[:date], start_time: params[:start_time]) + if @party.save + @user.user_parties.create!(user_id: @user.id, party_id: @party.id, is_host: true) + @users.each do |other_user| + if params[:"#{other_user.id}"].present? + other_user.user_parties.create!(party_id: @party.id) + end + end + redirect_to user_path(@user.id) + else + flash[:alert] = "Error: something is wrong with credentials" + redirect_to "/users/#{@user.id}/movies/#{@movie.id}/viewing-party/new" + end + end +end \ No newline at end of file diff --git a/app/models/utility.rb b/app/models/utility.rb new file mode 100644 index 000000000..2980ced91 --- /dev/null +++ b/app/models/utility.rb @@ -0,0 +1,8 @@ +class Utility + def self.runtime_in_min(data) + runtime_minutes = data[:runtime].to_i + hours = runtime_minutes / 60 + minutes = runtime_minutes % 60 + "#{hours} hours #{minutes} minutes" + end +end \ No newline at end of file diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 4810cad91..2ce9eb1c1 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -2,6 +2,7 @@ ViewingPartyLite7 + <%= link_to "Go to Landing Page", root_path, class: 'btn btn-primary' %> <%= csrf_meta_tags %> <%= csp_meta_tag %> diff --git a/app/views/movies/show.html.erb b/app/views/movies/show.html.erb new file mode 100644 index 000000000..ed34d6863 --- /dev/null +++ b/app/views/movies/show.html.erb @@ -0,0 +1,39 @@ +

<%= "#{@movie_details[:title]} Movie Details"%>

+ +<%= button_to 'Create a Viewing Party', "/users/#{params[:user_id]}/movies/#{params[:id]}/viewing-party/new", method: :get %> +<%= button_to 'Discover Movies', user_discover_index_path(params[:user_id]), method: :get %> + +

Movie Id: <%= "#{@movie_details[:id]}"%>

+

Vote Average: <%= "#{@movie_details[:vote_average]}"%>

+

Runtime: <%= Utility.runtime_in_min(@movie_details) %>

+

Genre(s):

+
    +<% @movie_details[:genres].each do |genre| %> +
  • <%= genre[:name] %>
  • +<% end %> +
+ +

Overview: <%= "#{@movie_details[:overview]}"%>

+ +

List the first 10 cast members:

+
    + <% @movie_cast[:cast].each_with_index do |member, index| %> + <% break if index >= 10 %> +
  • <%= member[:name] %>
  • + <% end %> +
+ +

Review Count: <%= "#{@movie_review[:results].count}"%>

+ +

Review's author and information:

+
    + <% @movie_review[:results].each do |reviewer| %> +
  • Name: <%= reviewer[:author] %>
  • +
  • Rating: <%= reviewer[:author_details][:rating] %>
  • +
  • ID: <%= reviewer[:id] %>
  • +
  • URL: <%= reviewer[:url] %>
  • +
    + <% end %> +
+ + diff --git a/app/views/viewing_parties/new.html.erb b/app/views/viewing_parties/new.html.erb new file mode 100644 index 000000000..e69de29bb diff --git a/config/routes.rb b/config/routes.rb index 6cdc14541..2272f6201 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,4 +10,6 @@ resources :discover, only: [:index] resources :movies, only: [:index, :show] end + + get "/users/:user_id/movies/:movid_id/viewing-party/new", to: "viewing_parties#new" end diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb index e69de29bb..ac0b1cf12 100644 --- a/spec/features/users/movies/show_spec.rb +++ b/spec/features/users/movies/show_spec.rb @@ -0,0 +1,83 @@ +require 'rails_helper' + +RSpec.describe 'Movie Results' do + before(:each) do + load_test_data + end + it 'When I go to a user dashbaord, and click "Discover Movies" button, I am redirected to a discover page /users/:id/discover' do + specific_movie_response = File.read('spec/fixtures/specific_movie.json') + credits_response = File.read('spec/fixtures/specific_movie_credits.json') + reviews_response = File.read('spec/fixtures/specific_movie_reviews.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: specific_movie_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/268/credits?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: credits_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/268/reviews?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: reviews_response, headers: {}) + + visit "/users/#{@user1.id}/movies/268" + click_link "Go to Landing Page" + expect(current_path).to eq("/") + + visit "/users/#{@user1.id}/movies/268" + click_button "Create a Viewing Party" + expect(current_path).to eq("/users/#{@user1.id}/movies/268/viewing-party/new") + + visit "/users/#{@user1.id}/movies/268" + click_button "Discover Movies" + expect(current_path).to eq(user_discover_index_path(user_id: @user1.id)) + + visit "/users/#{@user1.id}/movies/268" + + expect(page).to have_content("Movie Id: 268") + expect(page).to have_content("Vote Average: 7.2") + expect(page).to have_content("Runtime: 2 hours 6 minutes") + expect(page).to have_content("Fantasy") + expect(page).to have_content("Action") + expect(page).to have_content("Crime") + + expect(page).to have_content("Batman must face his most ruthless nemesis when a deformed madman calling himself") + + expect(page).to have_content("Michael Keaton") + expect(page).to have_content("Jack Nicholson") + expect(page).to have_content("Kim Basinger") + expect(page).to have_content("Michael Gough") + expect(page).to have_content("Jerry Hall") + expect(page).to have_content("Robert Wuhl") + expect(page).to have_content("Pat Hingle") + expect(page).to have_content("Billy Dee Williams") + expect(page).to have_content("Jack Palance") + expect(page).to have_content("Tracey Walter") + + expect(page).to have_content("Name: John Chard") + expect(page).to have_content("Rating: 8.0") + expect(page).to have_content("ID: 579b3420c3a3686e13000085") + expect(page).to have_content("URL: https://www.themoviedb.org/review/579b3420c3a3686e13000085") + + expect(page).to have_content("Name: Albert") + expect(page).to have_content("Rating: 4.0") + expect(page).to have_content("ID: 599b09dfc3a3681dde000414") + expect(page).to have_content("URL: https://www.themoviedb.org/review/599b09dfc3a3681dde000414") + end +end \ No newline at end of file diff --git a/spec/fixtures/specific_movie.json b/spec/fixtures/specific_movie.json new file mode 100644 index 000000000..d2fd23bd2 --- /dev/null +++ b/spec/fixtures/specific_movie.json @@ -0,0 +1,80 @@ +{ + "adult": false, + "backdrop_path": "/frDS8A5vIP927KYAxTVVKRIbqZw.jpg", + "belongs_to_collection": { + "id": 120794, + "name": "Batman Collection", + "poster_path": "/4AUoqt72CVP4UV902hmdDj4t5Q9.jpg", + "backdrop_path": "/4UHZWw5lV3ZoadTjXuVOakdH32L.jpg" + }, + "budget": 35000000, + "genres": [ + { + "id": 14, + "name": "Fantasy" + }, + { + "id": 28, + "name": "Action" + }, + { + "id": 80, + "name": "Crime" + } + ], + "homepage": "", + "id": 268, + "imdb_id": "tt0096895", + "original_language": "en", + "original_title": "Batman", + "overview": "Batman must face his most ruthless nemesis when a deformed madman calling himself \"The Joker\" seizes control of Gotham's criminal underworld.", + "popularity": 45.694, + "poster_path": "/cij4dd21v2Rk2YtUQbV5kW69WB2.jpg", + "production_companies": [ + { + "id": 4357, + "logo_path": null, + "name": "The Guber-Peters Company", + "origin_country": "" + }, + { + "id": 174, + "logo_path": "/IuAlhI9eVC9Z8UQWOIDdWRKSEJ.png", + "name": "Warner Bros. Pictures", + "origin_country": "US" + }, + { + "id": 67889, + "logo_path": null, + "name": "Polygram Pictures", + "origin_country": "US" + } + ], + "production_countries": [ + { + "iso_3166_1": "US", + "name": "United States of America" + } + ], + "release_date": "1989-06-21", + "revenue": 411348924, + "runtime": 126, + "spoken_languages": [ + { + "english_name": "English", + "iso_639_1": "en", + "name": "English" + }, + { + "english_name": "French", + "iso_639_1": "fr", + "name": "Français" + } + ], + "status": "Released", + "tagline": "Have you ever danced with the devil in the pale moonlight?", + "title": "Batman", + "video": false, + "vote_average": 7.22, + "vote_count": 7237 +} \ No newline at end of file diff --git a/spec/fixtures/specific_movie_credits.json b/spec/fixtures/specific_movie_credits.json new file mode 100644 index 000000000..8a8615996 --- /dev/null +++ b/spec/fixtures/specific_movie_credits.json @@ -0,0 +1,2588 @@ +{ + "id": 268, + "cast": [ + { + "adult": false, + "gender": 2, + "id": 2232, + "known_for_department": "Acting", + "name": "Michael Keaton", + "original_name": "Michael Keaton", + "popularity": 34.514, + "profile_path": "/82rxrGxOqQW2NjKsIiNbDYHFfmb.jpg", + "cast_id": 4, + "character": "Bruce Wayne / Batman", + "credit_id": "52fe422fc3a36847f800aa01", + "order": 0 + }, + { + "adult": false, + "gender": 2, + "id": 514, + "known_for_department": "Acting", + "name": "Jack Nicholson", + "original_name": "Jack Nicholson", + "popularity": 33.315, + "profile_path": "/6h12pZsgj3WWjMtykUgfLkLEBWz.jpg", + "cast_id": 5, + "character": "Jack Napier / The Joker", + "credit_id": "52fe422fc3a36847f800aa05", + "order": 1 + }, + { + "adult": false, + "gender": 1, + "id": 326, + "known_for_department": "Acting", + "name": "Kim Basinger", + "original_name": "Kim Basinger", + "popularity": 19.404, + "profile_path": "/iqQ4o2sRna7J1Z9KkB9Avp9CIsk.jpg", + "cast_id": 6, + "character": "Vicki Vale", + "credit_id": "52fe422fc3a36847f800aa09", + "order": 2 + }, + { + "adult": false, + "gender": 2, + "id": 3796, + "known_for_department": "Acting", + "name": "Michael Gough", + "original_name": "Michael Gough", + "popularity": 8.45, + "profile_path": "/owcwnV6dymBd9YIQKDPzVA5EtZX.jpg", + "cast_id": 7, + "character": "Alfred Pennyworth", + "credit_id": "52fe422fc3a36847f800aa0d", + "order": 3 + }, + { + "adult": false, + "gender": 1, + "id": 3800, + "known_for_department": "Acting", + "name": "Jerry Hall", + "original_name": "Jerry Hall", + "popularity": 3.069, + "profile_path": "/kInkl0xOfRhzA0x72JjIA5w2ugt.jpg", + "cast_id": 11, + "character": "Alicia Grissom", + "credit_id": "52fe422fc3a36847f800aa1d", + "order": 4 + }, + { + "adult": false, + "gender": 2, + "id": 4040, + "known_for_department": "Acting", + "name": "Robert Wuhl", + "original_name": "Robert Wuhl", + "popularity": 8.659, + "profile_path": "/e01JiHVW5cdBkLu7aVDhRilfCvY.jpg", + "cast_id": 24, + "character": "Alexander Knox", + "credit_id": "52fe4230c3a36847f800aa61", + "order": 5 + }, + { + "adult": false, + "gender": 2, + "id": 3798, + "known_for_department": "Acting", + "name": "Pat Hingle", + "original_name": "Pat Hingle", + "popularity": 6.16, + "profile_path": "/QBAxFVZQ0Hu6rxlFavhwUq0zug.jpg", + "cast_id": 8, + "character": "Commissioner James Gordon", + "credit_id": "52fe422fc3a36847f800aa11", + "order": 6 + }, + { + "adult": false, + "gender": 2, + "id": 3799, + "known_for_department": "Acting", + "name": "Billy Dee Williams", + "original_name": "Billy Dee Williams", + "popularity": 13.774, + "profile_path": "/dCiHLiCapPuRwKkM1ytVZ7PwYQY.jpg", + "cast_id": 9, + "character": "Harvey Dent", + "credit_id": "52fe422fc3a36847f800aa15", + "order": 7 + }, + { + "adult": false, + "gender": 2, + "id": 3785, + "known_for_department": "Acting", + "name": "Jack Palance", + "original_name": "Jack Palance", + "popularity": 8.833, + "profile_path": "/sRr2YPa1IElRE1vG1PQcgLrS9om.jpg", + "cast_id": 10, + "character": "Carl Grissom", + "credit_id": "52fe422fc3a36847f800aa19", + "order": 8 + }, + { + "adult": false, + "gender": 2, + "id": 3801, + "known_for_department": "Acting", + "name": "Tracey Walter", + "original_name": "Tracey Walter", + "popularity": 10.058, + "profile_path": "/brqhinzxGKzqfAhOq6Npi3GFVWW.jpg", + "cast_id": 12, + "character": "Bob the Goon", + "credit_id": "52fe422fc3a36847f800aa21", + "order": 9 + }, + { + "adult": false, + "gender": 2, + "id": 3802, + "known_for_department": "Acting", + "name": "Lee Wallace", + "original_name": "Lee Wallace", + "popularity": 2.543, + "profile_path": "/3ah3QRJXpvxrLWLZ7r31aqwnDH.jpg", + "cast_id": 13, + "character": "Mayor", + "credit_id": "52fe422fc3a36847f800aa25", + "order": 10 + }, + { + "adult": false, + "gender": 2, + "id": 663, + "known_for_department": "Acting", + "name": "William Hootkins", + "original_name": "William Hootkins", + "popularity": 4.371, + "profile_path": "/dav2i86GN0UvYIyoTwQmGE8Nweg.jpg", + "cast_id": 14, + "character": "Eckhardt", + "credit_id": "52fe422fc3a36847f800aa29", + "order": 11 + }, + { + "adult": false, + "gender": 2, + "id": 79502, + "known_for_department": "Acting", + "name": "Richard Strange", + "original_name": "Richard Strange", + "popularity": 2.26, + "profile_path": "/f7QFUkwkqyegwUIFKarU4ahz3Ku.jpg", + "cast_id": 27, + "character": "Goon", + "credit_id": "58932a45c3a3686d17004caf", + "order": 12 + }, + { + "adult": false, + "gender": 2, + "id": 127166, + "known_for_department": "Acting", + "name": "Carl Chase", + "original_name": "Carl Chase", + "popularity": 2.136, + "profile_path": null, + "cast_id": 95, + "character": "Goon", + "credit_id": "5bbe9fcbc3a3682b46003da4", + "order": 13 + }, + { + "adult": false, + "gender": 2, + "id": 33403, + "known_for_department": "Acting", + "name": "Mac McDonald", + "original_name": "Mac McDonald", + "popularity": 2.198, + "profile_path": "/gejehuptBzsJlPiWKU8B9TTrc7r.jpg", + "cast_id": 130, + "character": "Goon", + "credit_id": "5bbea4199251413d60004923", + "order": 14 + }, + { + "adult": false, + "gender": 2, + "id": 1806344, + "known_for_department": "Acting", + "name": "George Lane Cooper", + "original_name": "George Lane Cooper", + "popularity": 1.616, + "profile_path": null, + "cast_id": 97, + "character": "Goon", + "credit_id": "5bbea0059251413d51004839", + "order": 15 + }, + { + "adult": false, + "gender": 2, + "id": 1229878, + "known_for_department": "Acting", + "name": "Terence Plummer", + "original_name": "Terence Plummer", + "popularity": 7.274, + "profile_path": null, + "cast_id": 98, + "character": "Goon", + "credit_id": "5bbea0139251413d650042e8", + "order": 16 + }, + { + "adult": false, + "gender": 2, + "id": 702, + "known_for_department": "Acting", + "name": "Philip Tan", + "original_name": "Philip Tan", + "popularity": 4.437, + "profile_path": "/6cXDkOsHPbdsgiUUM7UIz6s8cXX.jpg", + "cast_id": 99, + "character": "Goon", + "credit_id": "5bbea020c3a36844fe001115", + "order": 17 + }, + { + "adult": false, + "gender": 2, + "id": 1231674, + "known_for_department": "Acting", + "name": "John Sterland", + "original_name": "John Sterland", + "popularity": 1.96, + "profile_path": null, + "cast_id": 100, + "character": "Accountant", + "credit_id": "5bbea08f0e0a26249c00118e", + "order": 18 + }, + { + "adult": false, + "gender": 0, + "id": 3803, + "known_for_department": "Acting", + "name": "Edwin Craig", + "original_name": "Edwin Craig", + "popularity": 1.379, + "profile_path": null, + "cast_id": 15, + "character": "Rotelli", + "credit_id": "52fe422fc3a36847f800aa2d", + "order": 19 + }, + { + "adult": false, + "gender": 2, + "id": 1257821, + "known_for_department": "Acting", + "name": "Vincent Wong", + "original_name": "Vincent Wong", + "popularity": 2.146, + "profile_path": "/lWPw6iMQKOSh4w099GkexZKkv4F.jpg", + "cast_id": 26, + "character": "Crimelord 1", + "credit_id": "57f8030e92514116aa000cc6", + "order": 20 + }, + { + "adult": false, + "gender": 2, + "id": 929078, + "known_for_department": "Acting", + "name": "Joel Cutrara", + "original_name": "Joel Cutrara", + "popularity": 1.727, + "profile_path": null, + "cast_id": 101, + "character": "Crimelord 2", + "credit_id": "5bbea0a30e0a26249c0011aa", + "order": 21 + }, + { + "adult": false, + "gender": 0, + "id": 1348858, + "known_for_department": "Acting", + "name": "John Dair", + "original_name": "John Dair", + "popularity": 0.98, + "profile_path": null, + "cast_id": 102, + "character": "Ricorso", + "credit_id": "5bbea0bc0e0a262366004bcf", + "order": 22 + }, + { + "adult": false, + "gender": 2, + "id": 8399, + "known_for_department": "Acting", + "name": "Christopher Fairbank", + "original_name": "Christopher Fairbank", + "popularity": 8.861, + "profile_path": "/eSOuf8dTGjwjlConY7d1FGgRNY7.jpg", + "cast_id": 28, + "character": "Nic", + "credit_id": "58932a649251416eeb0047de", + "order": 23 + }, + { + "adult": false, + "gender": 2, + "id": 2147290, + "known_for_department": "Acting", + "name": "George Roth", + "original_name": "George Roth", + "popularity": 1.176, + "profile_path": null, + "cast_id": 103, + "character": "Eddie", + "credit_id": "5bbea0cc0e0a26236f004e4f", + "order": 24 + }, + { + "adult": false, + "gender": 1, + "id": 1497048, + "known_for_department": "Acting", + "name": "Kate Harper", + "original_name": "Kate Harper", + "popularity": 7.857, + "profile_path": "/uN0CA2CsywCU3ZUbZBEOCwqS8lQ.jpg", + "cast_id": 104, + "character": "Anchorwoman", + "credit_id": "5bbea0da0e0a26236f004e6d", + "order": 25 + }, + { + "adult": false, + "gender": 2, + "id": 100654, + "known_for_department": "Acting", + "name": "Bruce McGuire", + "original_name": "Bruce McGuire", + "popularity": 2.89, + "profile_path": "/mdy1CIIAtvWvEsGY1qOook98VKb.jpg", + "cast_id": 166, + "character": "Anchorman", + "credit_id": "609ae7f4764841003ae384e9", + "order": 26 + }, + { + "adult": false, + "gender": 2, + "id": 120833, + "known_for_department": "Acting", + "name": "Richard Durden", + "original_name": "Richard Durden", + "popularity": 3.656, + "profile_path": "/eH5gdjtoCMFNs2OlSyWb0ha2yHn.jpg", + "cast_id": 29, + "character": "TV Director", + "credit_id": "58932a739251416ef8004e1f", + "order": 27 + }, + { + "adult": false, + "gender": 0, + "id": 2147293, + "known_for_department": "Acting", + "name": "Kit Hollerbach", + "original_name": "Kit Hollerbach", + "popularity": 0.98, + "profile_path": null, + "cast_id": 106, + "character": "Becky", + "credit_id": "5bbea17a9251413d5900462d", + "order": 28 + }, + { + "adult": false, + "gender": 1, + "id": 59088, + "known_for_department": "Acting", + "name": "Lachele Carl", + "original_name": "Lachele Carl", + "popularity": 4.001, + "profile_path": "/me1nkBO717RiYUeoHQht0VFNoYv.jpg", + "cast_id": 169, + "character": "TV Technician", + "credit_id": "626e0e3124b333006549cdb8", + "order": 29 + }, + { + "adult": false, + "gender": 2, + "id": 1717052, + "known_for_department": "Crew", + "name": "Del Baker", + "original_name": "Del Baker", + "popularity": 3.312, + "profile_path": "/qFfE9Dx3nimQdb0eDsfO1XTy05B.jpg", + "cast_id": 108, + "character": "Napier Hood", + "credit_id": "5bbea19a0e0a262366004d48", + "order": 30 + }, + { + "adult": false, + "gender": 2, + "id": 1534130, + "known_for_department": "Crew", + "name": "Jazzer Jeyes", + "original_name": "Jazzer Jeyes", + "popularity": 0.797, + "profile_path": null, + "cast_id": 109, + "character": "Napier Hood", + "credit_id": "5bbea1ae0e0a26249f001320", + "order": 31 + }, + { + "adult": false, + "gender": 2, + "id": 1469954, + "known_for_department": "Acting", + "name": "Wayne Michaels", + "original_name": "Wayne Michaels", + "popularity": 2.232, + "profile_path": null, + "cast_id": 110, + "character": "Napier Hood", + "credit_id": "5bbea1c20e0a26249f001337", + "order": 32 + }, + { + "adult": false, + "gender": 2, + "id": 1229882, + "known_for_department": "Acting", + "name": "Valentino Musetti", + "original_name": "Valentino Musetti", + "popularity": 2.188, + "profile_path": "/6IheLyxykYQFMWAlogumzfRAvEL.jpg", + "cast_id": 111, + "character": "Napier Hood", + "credit_id": "5bbea1d10e0a2624c6001241", + "order": 33 + }, + { + "adult": false, + "gender": 2, + "id": 40740, + "known_for_department": "Crew", + "name": "Rocky Taylor", + "original_name": "Rocky Taylor", + "popularity": 2.405, + "profile_path": "/l367aS36f5vHh0bn4NWeHExw9qd.jpg", + "cast_id": 112, + "character": "Napier Hood", + "credit_id": "5bbea1e69251413d59004810", + "order": 34 + }, + { + "adult": false, + "gender": 2, + "id": 2099757, + "known_for_department": "Acting", + "name": "Keith Edwards", + "original_name": "Keith Edwards", + "popularity": 1.383, + "profile_path": null, + "cast_id": 113, + "character": "Reporter", + "credit_id": "5bbea1f30e0a26236f004fcd", + "order": 35 + }, + { + "adult": false, + "gender": 2, + "id": 145536, + "known_for_department": "Acting", + "name": "Leon Herbert", + "original_name": "Leon Herbert", + "popularity": 3.479, + "profile_path": "/z1Ap0OjXrO8mwcTqCZt3ycZcfTm.jpg", + "cast_id": 114, + "character": "Reporter", + "credit_id": "5bbea2010e0a26249c001430", + "order": 36 + }, + { + "adult": false, + "gender": 2, + "id": 140148, + "known_for_department": "Acting", + "name": "Steve Plytas", + "original_name": "Steve Plytas", + "popularity": 1.696, + "profile_path": "/qFGSjfiC6qBEMCdpvZgI4YIUvE4.jpg", + "cast_id": 31, + "character": "Doctor", + "credit_id": "598643679251413d39006b53", + "order": 37 + }, + { + "adult": false, + "gender": 0, + "id": 2147295, + "known_for_department": "Acting", + "name": "Anthony Wellington", + "original_name": "Anthony Wellington", + "popularity": 0.6, + "profile_path": null, + "cast_id": 115, + "character": "Patrolman at Party", + "credit_id": "5bbea26a0e0a26249c0014a7", + "order": 38 + }, + { + "adult": false, + "gender": 2, + "id": 231299, + "known_for_department": "Acting", + "name": "Amir M. Korangy", + "original_name": "Amir M. Korangy", + "popularity": 1.596, + "profile_path": "/kMT5dZ2BN7pFz3Y9elSLRlthiWz.jpg", + "cast_id": 116, + "character": "Wine Steward", + "credit_id": "5bbea27b0e0a26249c0014ca", + "order": 39 + }, + { + "adult": false, + "gender": 2, + "id": 218373, + "known_for_department": "Production", + "name": "Hugo Blick", + "original_name": "Hugo Blick", + "popularity": 8.187, + "profile_path": null, + "cast_id": 32, + "character": "Young Jack Napier", + "credit_id": "5a497641c3a36805c5004c77", + "order": 40 + }, + { + "adult": false, + "gender": 0, + "id": 2147297, + "known_for_department": "Acting", + "name": "Charles Roskilly", + "original_name": "Charles Roskilly", + "popularity": 1.576, + "profile_path": null, + "cast_id": 117, + "character": "Young Bruce Wayne", + "credit_id": "5bbea28d92514179a4001219", + "order": 41 + }, + { + "adult": false, + "gender": 2, + "id": 987040, + "known_for_department": "Acting", + "name": "Philip O'Brien", + "original_name": "Philip O'Brien", + "popularity": 1.108, + "profile_path": null, + "cast_id": 118, + "character": "Maitre d'", + "credit_id": "5bbea29f9251413d590048ab", + "order": 42 + }, + { + "adult": false, + "gender": 2, + "id": 18763, + "known_for_department": "Acting", + "name": "Michael Balfour", + "original_name": "Michael Balfour", + "popularity": 2.729, + "profile_path": "/uLybbsWryAsc7gZ0CDIY8V34HRT.jpg", + "cast_id": 119, + "character": "Scientist", + "credit_id": "5bbea2af0e0a2624c60013d0", + "order": 43 + }, + { + "adult": false, + "gender": 2, + "id": 17356, + "known_for_department": "Acting", + "name": "Garrick Hagon", + "original_name": "Garrick Hagon", + "popularity": 5.302, + "profile_path": "/lDtVxw5eMfmexYgL6OZJTfSCRCN.jpg", + "cast_id": 94, + "character": "Dad", + "credit_id": "5b3199d79251413c890073ee", + "order": 44 + }, + { + "adult": false, + "gender": 1, + "id": 1738564, + "known_for_department": "Acting", + "name": "Liza Ross", + "original_name": "Liza Ross", + "popularity": 3.842, + "profile_path": null, + "cast_id": 120, + "character": "Mom", + "credit_id": "5bbea2ba9251413d51004c16", + "order": 45 + }, + { + "adult": false, + "gender": 0, + "id": 2147298, + "known_for_department": "Acting", + "name": "Adrian Meyers", + "original_name": "Adrian Meyers", + "popularity": 1.38, + "profile_path": null, + "cast_id": 121, + "character": "Jimmy", + "credit_id": "5bbea2c60e0a26235f0045ed", + "order": 46 + }, + { + "adult": false, + "gender": 0, + "id": 38651, + "known_for_department": "Acting", + "name": "David Baxt", + "original_name": "David Baxt", + "popularity": 3.963, + "profile_path": "/amzGafV7re5W1Xxnsj0L52eZiIy.jpg", + "cast_id": 122, + "character": "Dr Wayne", + "credit_id": "5bbea2d2c3a3682b3400578f", + "order": 47 + }, + { + "adult": false, + "gender": 0, + "id": 2147300, + "known_for_department": "Acting", + "name": "Sharon Holm", + "original_name": "Sharon Holm", + "popularity": 1.22, + "profile_path": null, + "cast_id": 123, + "character": "Mrs Wayne", + "credit_id": "5bbea32b0e0a26236f00511e", + "order": 48 + }, + { + "adult": false, + "gender": 2, + "id": 2147301, + "known_for_department": "Acting", + "name": "Clyde Gatell", + "original_name": "Clyde Gatell", + "popularity": 0.828, + "profile_path": null, + "cast_id": 124, + "character": "Other Mugger", + "credit_id": "5bbea3419251413d5900498e", + "order": 49 + }, + { + "adult": false, + "gender": 0, + "id": 2147302, + "known_for_department": "Acting", + "name": "Jon Soresi", + "original_name": "Jon Soresi", + "popularity": 0.6, + "profile_path": null, + "cast_id": 125, + "character": "Medic", + "credit_id": "5bbea34d0e0a262359004dc1", + "order": 50 + }, + { + "adult": false, + "gender": 2, + "id": 1164393, + "known_for_department": "Writing", + "name": "Elliott Stein", + "original_name": "Elliott Stein", + "popularity": 1.62, + "profile_path": null, + "cast_id": 126, + "character": "Man in Crowd", + "credit_id": "5bbea35e0e0a26232b001495", + "order": 51 + }, + { + "adult": false, + "gender": 2, + "id": 17072, + "known_for_department": "Acting", + "name": "Sam Douglas", + "original_name": "Sam Douglas", + "popularity": 5.974, + "profile_path": "/hGtVDo5BF4utyCbrEUm3RDNA28B.jpg", + "cast_id": 30, + "character": "Lawyer", + "credit_id": "58932a8bc3a3686d1c004b39", + "order": 52 + }, + { + "adult": false, + "gender": 2, + "id": 129452, + "known_for_department": "Acting", + "name": "Denis Lill", + "original_name": "Denis Lill", + "popularity": 4.251, + "profile_path": "/9tbJGo2OC4dzr8Mpk3QM0sMfdMb.jpg", + "cast_id": 127, + "character": "Bob the Cartoonist", + "credit_id": "5bbea370c3a3682b4b00480b", + "order": 53 + }, + { + "adult": false, + "gender": 2, + "id": 29617, + "known_for_department": "Acting", + "name": "Paul Birchard", + "original_name": "Paul Birchard", + "popularity": 3.078, + "profile_path": "/3A8JwCXwIE3qYwaFLFyaixUp070.jpg", + "cast_id": 128, + "character": "Reporter", + "credit_id": "5bbea3800e0a262359004e0a", + "order": 54 + }, + { + "adult": false, + "gender": 0, + "id": 1744217, + "known_for_department": "Acting", + "name": "Paul Michael", + "original_name": "Paul Michael", + "popularity": 0.6, + "profile_path": null, + "cast_id": 129, + "character": "Cop", + "credit_id": "5bbea39292514179a400138b", + "order": 55 + }, + { + "adult": false, + "gender": 2, + "id": 1230584, + "known_for_department": "Acting", + "name": "Pat Gorman", + "original_name": "Pat Gorman", + "popularity": 2.274, + "profile_path": "/heb2Bh2xLz5Q3oVtQndMOKv0nSH.jpg", + "cast_id": 168, + "character": "Cop at Axis Chemicals", + "credit_id": "61fb0b9b0c4c16006bc97ef2", + "order": 56 + }, + { + "adult": false, + "gender": 0, + "id": 1228432, + "known_for_department": "Acting", + "name": "Chris Andrews", + "original_name": "Chris Andrews", + "popularity": 0.84, + "profile_path": null, + "cast_id": 174, + "character": "Election Ceremony Patron", + "credit_id": "644cfdb75e14e504e6b882fb", + "order": 57 + }, + { + "adult": false, + "gender": 1, + "id": 4091766, + "known_for_department": "Acting", + "name": "Stephanie English", + "original_name": "Stephanie English", + "popularity": 1.214, + "profile_path": null, + "cast_id": 175, + "character": "Woman in Green Coat", + "credit_id": "6478a5ae93828e011623268d", + "order": 58 + } + ], + "crew": [ + { + "adult": false, + "gender": 2, + "id": 244, + "known_for_department": "Editing", + "name": "Ray Lovejoy", + "original_name": "Ray Lovejoy", + "popularity": 1.361, + "profile_path": null, + "credit_id": "52fe422fc3a36847f800aa4b", + "department": "Editing", + "job": "Editor" + }, + { + "adult": false, + "gender": 2, + "id": 293, + "known_for_department": "Camera", + "name": "Roger Pratt", + "original_name": "Roger Pratt", + "popularity": 3.335, + "profile_path": "/9vsOa0JDkaA3pjEf2r55goEktiN.jpg", + "credit_id": "52fe422fc3a36847f800aa3f", + "department": "Camera", + "job": "Director of Photography" + }, + { + "adult": false, + "gender": 2, + "id": 510, + "known_for_department": "Directing", + "name": "Tim Burton", + "original_name": "Tim Burton", + "popularity": 19.733, + "profile_path": "/oWZDgLRr4zgRiJEsOAtgntPd5bI.jpg", + "credit_id": "52fe422fc3a36847f800a9f1", + "department": "Directing", + "job": "Director" + }, + { + "adult": false, + "gender": 2, + "id": 531, + "known_for_department": "Sound", + "name": "Danny Elfman", + "original_name": "Danny Elfman", + "popularity": 10.047, + "profile_path": "/bcpur9bF56nLxzFzZowipA2wZhy.jpg", + "credit_id": "52fe422fc3a36847f800aa45", + "department": "Sound", + "job": "Original Music Composer" + }, + { + "adult": false, + "gender": 0, + "id": 913, + "known_for_department": "Writing", + "name": "Warren Skaaren", + "original_name": "Warren Skaaren", + "popularity": 5.619, + "profile_path": null, + "credit_id": "52fe422fc3a36847f800a9fd", + "department": "Writing", + "job": "Screenplay" + }, + { + "adult": false, + "gender": 2, + "id": 2530, + "known_for_department": "Costume & Make-Up", + "name": "Bob Ringwood", + "original_name": "Bob Ringwood", + "popularity": 0.617, + "profile_path": null, + "credit_id": "5abccddf9251411ea7022da4", + "department": "Costume & Make-Up", + "job": "Costume Design" + }, + { + "adult": false, + "gender": 2, + "id": 3794, + "known_for_department": "Writing", + "name": "Bob Kane", + "original_name": "Bob Kane", + "popularity": 8.102, + "profile_path": "/vuXwrlqaUydA4t5SFVdQkK9KsZL.jpg", + "credit_id": "52fe422fc3a36847f800a9f7", + "department": "Writing", + "job": "Characters" + }, + { + "adult": false, + "gender": 2, + "id": 3804, + "known_for_department": "Production", + "name": "Peter Guber", + "original_name": "Peter Guber", + "popularity": 2.062, + "profile_path": "/6QILn3KDqoJrRMz8rRzTYS3igCc.jpg", + "credit_id": "52fe422fc3a36847f800aa33", + "department": "Production", + "job": "Producer" + }, + { + "adult": false, + "gender": 2, + "id": 3805, + "known_for_department": "Production", + "name": "Jon Peters", + "original_name": "Jon Peters", + "popularity": 2.749, + "profile_path": "/ts4JBYG2LEbquRzExGHer1122AI.jpg", + "credit_id": "52fe422fc3a36847f800aa39", + "department": "Production", + "job": "Producer" + }, + { + "adult": false, + "gender": 1, + "id": 3806, + "known_for_department": "Production", + "name": "Marion Dougherty", + "original_name": "Marion Dougherty", + "popularity": 4.075, + "profile_path": null, + "credit_id": "52fe422fc3a36847f800aa51", + "department": "Production", + "job": "Casting" + }, + { + "adult": false, + "gender": 2, + "id": 3807, + "known_for_department": "Art", + "name": "Anton Furst", + "original_name": "Anton Furst", + "popularity": 0.6, + "profile_path": null, + "credit_id": "52fe4230c3a36847f800aa57", + "department": "Art", + "job": "Production Design" + }, + { + "adult": false, + "gender": 2, + "id": 3795, + "known_for_department": "Writing", + "name": "Sam Hamm", + "original_name": "Sam Hamm", + "popularity": 2.504, + "profile_path": null, + "credit_id": "52fe4230c3a36847f800aa5d", + "department": "Writing", + "job": "Screenplay" + }, + { + "adult": false, + "gender": 2, + "id": 3795, + "known_for_department": "Writing", + "name": "Sam Hamm", + "original_name": "Sam Hamm", + "popularity": 2.504, + "profile_path": null, + "credit_id": "61d672d335039800905b3b32", + "department": "Writing", + "job": "Story" + }, + { + "adult": false, + "gender": 2, + "id": 5021, + "known_for_department": "Art", + "name": "Leslie Tomkins", + "original_name": "Leslie Tomkins", + "popularity": 1.4, + "profile_path": null, + "credit_id": "5abccdb19251411e920245c4", + "department": "Art", + "job": "Supervising Art Director" + }, + { + "adult": false, + "gender": 2, + "id": 5132, + "known_for_department": "Sound", + "name": "Bob Badami", + "original_name": "Bob Badami", + "popularity": 1.494, + "profile_path": null, + "credit_id": "5abcd209c3a368435f022dcd", + "department": "Sound", + "job": "Music Editor" + }, + { + "adult": false, + "gender": 2, + "id": 10949, + "known_for_department": "Production", + "name": "Michael Uslan", + "original_name": "Michael Uslan", + "popularity": 2.207, + "profile_path": "/cXiiH0SSk5UHCvHOVAhHX7tNuls.jpg", + "credit_id": "570ede8992514102af000bff", + "department": "Production", + "job": "Executive Producer" + }, + { + "adult": false, + "gender": 2, + "id": 10951, + "known_for_department": "Production", + "name": "Benjamin Melniker", + "original_name": "Benjamin Melniker", + "popularity": 2.069, + "profile_path": null, + "credit_id": "5abccd54c3a36843620244ec", + "department": "Production", + "job": "Executive Producer" + }, + { + "adult": false, + "gender": 0, + "id": 8418, + "known_for_department": "Production", + "name": "Suzie F. Wiesmann", + "original_name": "Suzie F. Wiesmann", + "popularity": 0.664, + "profile_path": null, + "credit_id": "5cef09f6c3a368637f1e3ca3", + "department": "Visual Effects", + "job": "Visual Effects Production Manager" + }, + { + "adult": false, + "gender": 2, + "id": 9817, + "known_for_department": "Art", + "name": "Nigel Phelps", + "original_name": "Nigel Phelps", + "popularity": 1.604, + "profile_path": null, + "credit_id": "5abccd929251411ea0023ffc", + "department": "Art", + "job": "Art Direction" + }, + { + "adult": false, + "gender": 2, + "id": 9823, + "known_for_department": "Art", + "name": "Peter Young", + "original_name": "Peter Young", + "popularity": 2.588, + "profile_path": null, + "credit_id": "5abccdc70e0a2609de02578c", + "department": "Art", + "job": "Set Decoration" + }, + { + "adult": false, + "gender": 2, + "id": 11173, + "known_for_department": "Costume & Make-Up", + "name": "Nick Dudman", + "original_name": "Nick Dudman", + "popularity": 1.4, + "profile_path": null, + "credit_id": "5abccf3a9251411ea7022ecd", + "department": "Costume & Make-Up", + "job": "Makeup Designer" + }, + { + "adult": false, + "gender": 1, + "id": 11348, + "known_for_department": "Costume & Make-Up", + "name": "Lynda Armstrong", + "original_name": "Lynda Armstrong", + "popularity": 1.045, + "profile_path": null, + "credit_id": "5abccf270e0a2609d20251f3", + "department": "Costume & Make-Up", + "job": "Makeup Artist" + }, + { + "adult": false, + "gender": 2, + "id": 10200, + "known_for_department": "Art", + "name": "Terry Ackland-Snow", + "original_name": "Terry Ackland-Snow", + "popularity": 2.823, + "profile_path": null, + "credit_id": "5abccd7dc3a368436202450f", + "department": "Art", + "job": "Art Direction" + }, + { + "adult": false, + "gender": 2, + "id": 10213, + "known_for_department": "Acting", + "name": "Tip Tipping", + "original_name": "Tip Tipping", + "popularity": 3.575, + "profile_path": "/vf6pIofI1U77O1GGk2I8yLEWgXL.jpg", + "credit_id": "64d63788db4ed600e2b66893", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 40693, + "known_for_department": "Crew", + "name": "Stuart Clark", + "original_name": "Stuart Clark", + "popularity": 0.989, + "profile_path": "/xKCSITjTOko5egpTuoaQ9RMEkqY.jpg", + "credit_id": "64d638b9f14dad013a8b45f8", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 11459, + "known_for_department": "Production", + "name": "Sally Osoba", + "original_name": "Sally Osoba", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef0a6892514109b5b896bf", + "department": "Production", + "job": "Casting Assistant" + }, + { + "adult": false, + "gender": 2, + "id": 12761, + "known_for_department": "Sound", + "name": "Eddy Joseph", + "original_name": "Eddy Joseph", + "popularity": 0.95, + "profile_path": "/mvYjNzo1G0FyQnj0Ka6yLbDqjPZ.jpg", + "credit_id": "5abcd2640e0a2609d5026f70", + "department": "Sound", + "job": "Sound Editor" + }, + { + "adult": false, + "gender": 2, + "id": 16589, + "known_for_department": "Directing", + "name": "Peter MacDonald", + "original_name": "Peter MacDonald", + "popularity": 3.79, + "profile_path": "/sulOWgN2WZKDOlg8JMpTv8TUSHh.jpg", + "credit_id": "5c8afee10e0a260420c55d8e", + "department": "Directing", + "job": "Second Unit Director" + }, + { + "adult": false, + "gender": 2, + "id": 18775, + "known_for_department": "Acting", + "name": "Marc Boyle", + "original_name": "Marc Boyle", + "popularity": 1.823, + "profile_path": null, + "credit_id": "64d638c7f495ee028f638792", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 18759, + "known_for_department": "Crew", + "name": "Charles Staffell", + "original_name": "Charles Staffell", + "popularity": 1.4, + "profile_path": null, + "credit_id": "5abccf969251411e92024755", + "department": "Crew", + "job": "Projection" + }, + { + "adult": false, + "gender": 0, + "id": 20110, + "known_for_department": "Sound", + "name": "Don Sharpe", + "original_name": "Don Sharpe", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5abcd2890e0a2609e4025911", + "department": "Sound", + "job": "Supervising Sound Editor" + }, + { + "adult": false, + "gender": 2, + "id": 21037, + "known_for_department": "Acting", + "name": "Prince", + "original_name": "Prince", + "popularity": 5.32, + "profile_path": "/5HPqjSXEQukk6ta8v1i9mPHUeqk.jpg", + "credit_id": "5e49ba1f35811d001948b72a", + "department": "Sound", + "job": "Songs" + }, + { + "adult": false, + "gender": 2, + "id": 23607, + "known_for_department": "Crew", + "name": "Nick Hobbs", + "original_name": "Nick Hobbs", + "popularity": 4.035, + "profile_path": "/7rAiPLhbOA0ihQw9Si6KULOPUSU.jpg", + "credit_id": "64d637e1d100b600c5d0a214", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 24278, + "known_for_department": "Acting", + "name": "Bill Weston", + "original_name": "Bill Weston", + "popularity": 2.557, + "profile_path": "/mQtWjSvfDlgI42NrE5E3nfICGbE.jpg", + "credit_id": "64d6379cbf31f201ca8b9bfe", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 26981, + "known_for_department": "Sound", + "name": "Shirley Walker", + "original_name": "Shirley Walker", + "popularity": 1.4, + "profile_path": "/xvjsJLILyUn2Rqr8nsLccPDoLv6.jpg", + "credit_id": "5cef0aa792514109b5b8987d", + "department": "Sound", + "job": "Conductor" + }, + { + "adult": false, + "gender": 2, + "id": 38335, + "known_for_department": "Sound", + "name": "Steve Bartek", + "original_name": "Steve Bartek", + "popularity": 1.205, + "profile_path": null, + "credit_id": "5abcd230c3a3687cb701c93a", + "department": "Sound", + "job": "Orchestrator" + }, + { + "adult": false, + "gender": 0, + "id": 71130, + "known_for_department": "Sound", + "name": "Michael Dilbeck", + "original_name": "Michael Dilbeck", + "popularity": 1.501, + "profile_path": null, + "credit_id": "5abcd21bc3a36843790263ec", + "department": "Sound", + "job": "Music Supervisor" + }, + { + "adult": false, + "gender": 2, + "id": 63064, + "known_for_department": "Camera", + "name": "Ali Asad", + "original_name": "Ali Asad", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5cef0a2d9251410fe2b9fec7", + "department": "Camera", + "job": "Assistant Camera" + }, + { + "adult": false, + "gender": 2, + "id": 71579, + "known_for_department": "Art", + "name": "David Allday", + "original_name": "David Allday", + "popularity": 1.18, + "profile_path": null, + "credit_id": "5cef097e0e0a264555ca103b", + "department": "Art", + "job": "Draughtsman" + }, + { + "adult": false, + "gender": 0, + "id": 75783, + "known_for_department": "Production", + "name": "Gordon Arnell", + "original_name": "Gordon Arnell", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5abcd1cd9251411e9a02395b", + "department": "Production", + "job": "Publicist" + }, + { + "adult": false, + "gender": 2, + "id": 188773, + "known_for_department": "Acting", + "name": "David Lea", + "original_name": "David Lea", + "popularity": 1.893, + "profile_path": "/9nZ8al0c6iosGQSljrbkBqGxjqc.jpg", + "credit_id": "64d63852b6c2641155f09dd9", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 227557, + "known_for_department": "Visual Effects", + "name": "Derek Meddings", + "original_name": "Derek Meddings", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5e2f0a01fd140b00196bd3d5", + "department": "Visual Effects", + "job": "Visual Effects" + }, + { + "adult": false, + "gender": 2, + "id": 1077325, + "known_for_department": "Crew", + "name": "Eddie Powell", + "original_name": "Eddie Powell", + "popularity": 3.688, + "profile_path": "/rdrJbQxIokXxiBHCJuAsqTKFbXH.jpg", + "credit_id": "5f3059b9f1b5710036eba48c", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1106167, + "known_for_department": "Crew", + "name": "Terry Forrestal", + "original_name": "Terry Forrestal", + "popularity": 2.8, + "profile_path": null, + "credit_id": "64d6384bbf31f201cb69a13d", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1185530, + "known_for_department": "Crew", + "name": "Eddie Stacey", + "original_name": "Eddie Stacey", + "popularity": 1.799, + "profile_path": null, + "credit_id": "5abcd011c3a368435f022c41", + "department": "Crew", + "job": "Stunt Coordinator" + }, + { + "adult": false, + "gender": 2, + "id": 1205484, + "known_for_department": "Crew", + "name": "Clive Curtis", + "original_name": "Clive Curtis", + "popularity": 1.72, + "profile_path": null, + "credit_id": "64d63893f495ee02935419d7", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1292437, + "known_for_department": "Crew", + "name": "Dave Holland", + "original_name": "Dave Holland", + "popularity": 0.974, + "profile_path": null, + "credit_id": "64d63746b6c264115958f175", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1323295, + "known_for_department": "Costume & Make-Up", + "name": "Graham Churchyard", + "original_name": "Graham Churchyard", + "popularity": 0.836, + "profile_path": null, + "credit_id": "5abccedfc3a3684388027ce6", + "department": "Costume & Make-Up", + "job": "Assistant Costume Designer" + }, + { + "adult": false, + "gender": 1, + "id": 1326461, + "known_for_department": "Costume & Make-Up", + "name": "Annie Crawford", + "original_name": "Annie Crawford", + "popularity": 1.698, + "profile_path": null, + "credit_id": "5cef0a940e0a2615b5cb92ca", + "department": "Costume & Make-Up", + "job": "Wardrobe Supervisor" + }, + { + "adult": false, + "gender": 0, + "id": 1342592, + "known_for_department": "Crew", + "name": "Brian Bishop", + "original_name": "Brian Bishop", + "popularity": 1.62, + "profile_path": null, + "credit_id": "5abccfd90e0a2609e1026e57", + "department": "Crew", + "job": "Scenic Artist" + }, + { + "adult": false, + "gender": 2, + "id": 1373728, + "known_for_department": "Lighting", + "name": "Chuck Finch", + "original_name": "Chuck Finch", + "popularity": 2.216, + "profile_path": null, + "credit_id": "5abcd14e0e0a2609de025acf", + "department": "Lighting", + "job": "Gaffer" + }, + { + "adult": false, + "gender": 2, + "id": 1380899, + "known_for_department": "Crew", + "name": "Paul Heasman", + "original_name": "Paul Heasman", + "popularity": 6.54, + "profile_path": "/iacF04EnwvChYz2p247hNwf4rnV.jpg", + "credit_id": "64d637c2d100b6011c81084b", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1388877, + "known_for_department": "Crew", + "name": "Steve Dent", + "original_name": "Steve Dent", + "popularity": 2.111, + "profile_path": "/KqTlsFdksLraqd4HBvGUemwfhe.jpg", + "credit_id": "64d6387cf14dad01004b3883", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 1392245, + "known_for_department": "Camera", + "name": "Murray Close", + "original_name": "Murray Close", + "popularity": 3.436, + "profile_path": null, + "credit_id": "5abccec9c3a368435c02665a", + "department": "Camera", + "job": "Still Photographer" + }, + { + "adult": false, + "gender": 0, + "id": 1393300, + "known_for_department": "Sound", + "name": "Jack Stew", + "original_name": "Jack Stew", + "popularity": 1.176, + "profile_path": null, + "credit_id": "5cef09bb0e0a2613cdcb8f70", + "department": "Sound", + "job": "Foley Artist" + }, + { + "adult": false, + "gender": 2, + "id": 1393335, + "known_for_department": "Lighting", + "name": "Billy Merrell", + "original_name": "Billy Merrell", + "popularity": 1.788, + "profile_path": null, + "credit_id": "5abcd11f9251411e9a0238bd", + "department": "Lighting", + "job": "Best Boy Electric" + }, + { + "adult": false, + "gender": 0, + "id": 1394777, + "known_for_department": "Art", + "name": "Charles Torbett", + "original_name": "Charles Torbett", + "popularity": 1.292, + "profile_path": null, + "credit_id": "5abccfc69251411ea3024963", + "department": "Art", + "job": "Property Master" + }, + { + "adult": false, + "gender": 0, + "id": 1395729, + "known_for_department": "Sound", + "name": "Tony Dawe", + "original_name": "Tony Dawe", + "popularity": 1.056, + "profile_path": null, + "credit_id": "5abcd244c3a3684379026417", + "department": "Sound", + "job": "Production Sound Mixer" + }, + { + "adult": false, + "gender": 2, + "id": 1401306, + "known_for_department": "Acting", + "name": "Rick Lester", + "original_name": "Rick Lester", + "popularity": 1.214, + "profile_path": null, + "credit_id": "64d637d0b6c26411569b3c80", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1402919, + "known_for_department": "Crew", + "name": "Graeme Crowther", + "original_name": "Graeme Crowther", + "popularity": 5.19, + "profile_path": null, + "credit_id": "64d6389ed100b600ada09c39", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 1406920, + "known_for_department": "Visual Effects", + "name": "Eddie Butler", + "original_name": "Eddie Butler", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5abcce649251411ea00240cf", + "department": "Art", + "job": "Sculptor" + }, + { + "adult": false, + "gender": 0, + "id": 1408796, + "known_for_department": "Production", + "name": "Chris Brock", + "original_name": "Chris Brock", + "popularity": 1.672, + "profile_path": null, + "credit_id": "5abcd1840e0a2609db026ace", + "department": "Production", + "job": "Location Manager" + }, + { + "adult": false, + "gender": 2, + "id": 1415957, + "known_for_department": "Crew", + "name": "Jim Dowdall", + "original_name": "Jim Dowdall", + "popularity": 2.419, + "profile_path": null, + "credit_id": "64d63886d100b601395c9b77", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 1417831, + "known_for_department": "Crew", + "name": "Sy Holland", + "original_name": "Sy Holland", + "popularity": 1.96, + "profile_path": null, + "credit_id": "62ca103764de35004dd284d7", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 1417831, + "known_for_department": "Crew", + "name": "Sy Holland", + "original_name": "Sy Holland", + "popularity": 1.96, + "profile_path": null, + "credit_id": "5cef0a0d925141099fb89c2e", + "department": "Crew", + "job": "Stunt Double" + }, + { + "adult": false, + "gender": 2, + "id": 1419427, + "known_for_department": "Crew", + "name": "Sean McCabe", + "original_name": "Sean McCabe", + "popularity": 2.268, + "profile_path": null, + "credit_id": "64d637a2f14dad013a8b4583", + "department": "Crew", + "job": "Stunt Double" + }, + { + "adult": false, + "gender": 2, + "id": 1424180, + "known_for_department": "Camera", + "name": "Jonathan Taylor", + "original_name": "Jonathan Taylor", + "popularity": 0.962, + "profile_path": null, + "credit_id": "5cef0a560e0a2636a5cb818c", + "department": "Camera", + "job": "Focus Puller" + }, + { + "adult": false, + "gender": 2, + "id": 1452480, + "known_for_department": "Acting", + "name": "Eddie Eddon", + "original_name": "Eddie Eddon", + "popularity": 1.62, + "profile_path": null, + "credit_id": "64d63873db4ed600ad250a8d", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1469629, + "known_for_department": "Acting", + "name": "Romo Gorrara", + "original_name": "Romo Gorrara", + "popularity": 1.76, + "profile_path": "/xh91P3yRv3ymhHQzACXUfRNMGEO.jpg", + "credit_id": "64d63862db4ed600ad250a85", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1513635, + "known_for_department": "Directing", + "name": "Derek Cracknell", + "original_name": "Derek Cracknell", + "popularity": 1.527, + "profile_path": "/6rrEbuX2hc5SrsKQICFiKKTWoAE.jpg", + "credit_id": "5abcd050c3a3684379026245", + "department": "Directing", + "job": "First Assistant Director" + }, + { + "adult": false, + "gender": 0, + "id": 1524299, + "known_for_department": "Directing", + "name": "Cheryl Leigh", + "original_name": "Cheryl Leigh", + "popularity": 0.732, + "profile_path": null, + "credit_id": "5abcd0d2c3a36843a6026f90", + "department": "Directing", + "job": "Script Supervisor" + }, + { + "adult": false, + "gender": 0, + "id": 1543759, + "known_for_department": "Lighting", + "name": "Bernie Hagadorn", + "original_name": "Bernie Hagadorn", + "popularity": 1.335, + "profile_path": null, + "credit_id": "5abcd175c3a3684396026d20", + "department": "Lighting", + "job": "Rigging Grip" + }, + { + "adult": false, + "gender": 0, + "id": 1592616, + "known_for_department": "Production", + "name": "Brenda Coxon", + "original_name": "Brenda Coxon", + "popularity": 0.968, + "profile_path": null, + "credit_id": "5abcd19b9251411ea002435d", + "department": "Production", + "job": "Production Accountant" + }, + { + "adult": false, + "gender": 2, + "id": 1593072, + "known_for_department": "Art", + "name": "Michael Boone", + "original_name": "Michael Boone", + "popularity": 1.4, + "profile_path": null, + "credit_id": "5abcce36c3a3687cb701c5a4", + "department": "Art", + "job": "Assistant Art Director" + }, + { + "adult": false, + "gender": 2, + "id": 1602727, + "known_for_department": "Crew", + "name": "Gerry Crampton", + "original_name": "Gerry Crampton", + "popularity": 3.179, + "profile_path": null, + "credit_id": "64d637b4bf31f201ca8b9c0e", + "department": "Crew", + "job": "Stunt Double" + }, + { + "adult": false, + "gender": 0, + "id": 1603859, + "known_for_department": "Visual Effects", + "name": "John Evans", + "original_name": "John Evans", + "popularity": 1.094, + "profile_path": null, + "credit_id": "5abcd34a0e0a2609de025c98", + "department": "Visual Effects", + "job": "Special Effects Supervisor" + }, + { + "adult": false, + "gender": 2, + "id": 1616303, + "known_for_department": "Acting", + "name": "Richard Graydon", + "original_name": "Richard Graydon", + "popularity": 4.78, + "profile_path": "/8T9i8DUKbk8pco4UG5KjzKWLnZX.jpg", + "credit_id": "64c6d0ce30f79c013bd2a27f", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 1645445, + "known_for_department": "Crew", + "name": "Sarah Franzl", + "original_name": "Sarah Franzl", + "popularity": 2.671, + "profile_path": null, + "credit_id": "62ca1051e8d028004f18cb15", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 1651253, + "known_for_department": "Art", + "name": "Richard Morrison", + "original_name": "Richard Morrison", + "popularity": 1.22, + "profile_path": null, + "credit_id": "5cef09a80e0a26346dc9eaa2", + "department": "Art", + "job": "Title Designer" + }, + { + "adult": false, + "gender": 1, + "id": 1700809, + "known_for_department": "Costume & Make-Up", + "name": "Jan Jamison", + "original_name": "Jan Jamison", + "popularity": 1.336, + "profile_path": null, + "credit_id": "5abccef40e0a2609e1026d8c", + "department": "Costume & Make-Up", + "job": "Hairstylist" + }, + { + "adult": false, + "gender": 0, + "id": 1712266, + "known_for_department": "Lighting", + "name": "Maurice Gillett", + "original_name": "Maurice Gillett", + "popularity": 1.336, + "profile_path": null, + "credit_id": "5abcd1649251411e920248c5", + "department": "Lighting", + "job": "Rigging Gaffer" + }, + { + "adult": false, + "gender": 2, + "id": 1836071, + "known_for_department": "Crew", + "name": "Roy Clarke", + "original_name": "Roy Clarke", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5cef0b030e0a263878c9eda9", + "department": "Production", + "job": "Production Driver" + }, + { + "adult": false, + "gender": 2, + "id": 1846759, + "known_for_department": "Lighting", + "name": "Fred Brown", + "original_name": "Fred Brown", + "popularity": 0.609, + "profile_path": null, + "credit_id": "5abcd1359251411e9a0238cb", + "department": "Lighting", + "job": "Electrician" + }, + { + "adult": false, + "gender": 2, + "id": 1902347, + "known_for_department": "Crew", + "name": "Chris Webb", + "original_name": "Chris Webb", + "popularity": 2.793, + "profile_path": "/ynXbiAuNnQ7VrZOX0P1mkdG2l9E.jpg", + "credit_id": "64d63782b6c26411569b3c54", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1951618, + "known_for_department": "Acting", + "name": "Peter Brace", + "original_name": "Peter Brace", + "popularity": 2.223, + "profile_path": null, + "credit_id": "64d638b4f14dad00e3b808e2", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1960037, + "known_for_department": "Crew", + "name": "Mark Anthony Newman", + "original_name": "Mark Anthony Newman", + "popularity": 1.215, + "profile_path": null, + "credit_id": "64d6376eb6c264115752f725", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 1978859, + "known_for_department": "Editing", + "name": "Russ Woolnough", + "original_name": "Russ Woolnough", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5e2f0a2b1685da0019e909e5", + "department": "Crew", + "job": "Visual Effects Editor" + }, + { + "adult": false, + "gender": 0, + "id": 1991276, + "known_for_department": "Production", + "name": "Barbara Kalish", + "original_name": "Barbara Kalish", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abccd3c9251411ea3024703", + "department": "Production", + "job": "Associate Producer" + }, + { + "adult": false, + "gender": 2, + "id": 2010286, + "known_for_department": "Production", + "name": "Chris Kenny", + "original_name": "Chris Kenny", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abccd2dc3a3684379025f43", + "department": "Production", + "job": "Co-Producer" + }, + { + "adult": false, + "gender": 0, + "id": 2010287, + "known_for_department": "Costume & Make-Up", + "name": "Tony Dunsterville", + "original_name": "Tony Dunsterville", + "popularity": 0.618, + "profile_path": null, + "credit_id": "5abccdf6c3a368435f022ab9", + "department": "Costume & Make-Up", + "job": "Costume Design" + }, + { + "adult": false, + "gender": 0, + "id": 2010288, + "known_for_department": "Art", + "name": "Jenny Chartres", + "original_name": "Jenny Chartres", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abcce289251411e9a023647", + "department": "Art", + "job": "Art Department Assistant" + }, + { + "adult": false, + "gender": 0, + "id": 2010289, + "known_for_department": "Art", + "name": "Roy Martin", + "original_name": "Roy Martin", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5abcce800e0a2609db02680d", + "department": "Art", + "job": "Standby Painter" + }, + { + "adult": false, + "gender": 0, + "id": 2010290, + "known_for_department": "Camera", + "name": "John Campbell", + "original_name": "John Campbell", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5abcce970e0a2609db026825", + "department": "Camera", + "job": "Camera Operator" + }, + { + "adult": false, + "gender": 0, + "id": 2010291, + "known_for_department": "Camera", + "name": "Stuart Godfrey", + "original_name": "Stuart Godfrey", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5abccea9c3a3687cb701c608", + "department": "Camera", + "job": "Key Grip" + }, + { + "adult": false, + "gender": 0, + "id": 2010292, + "known_for_department": "Camera", + "name": "Patricia Gregory", + "original_name": "Patricia Gregory", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abccebb9251411ea002410f", + "department": "Camera", + "job": "Grip" + }, + { + "adult": false, + "gender": 0, + "id": 2010294, + "known_for_department": "Costume & Make-Up", + "name": "Suzanne Reynolds", + "original_name": "Suzanne Reynolds", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abccf4b0e0a2609d8029d27", + "department": "Costume & Make-Up", + "job": "Prosthetic Makeup Artist" + }, + { + "adult": false, + "gender": 0, + "id": 2010295, + "known_for_department": "Crew", + "name": "Jamie White", + "original_name": "Jamie White", + "popularity": 0.972, + "profile_path": null, + "credit_id": "5abccf6d0e0a2609d8029d5b", + "department": "Crew", + "job": "Carpenter" + }, + { + "adult": false, + "gender": 2, + "id": 2010297, + "known_for_department": "Crew", + "name": "Richard Brierley", + "original_name": "Richard Brierley", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef0a479251410769b89cf8", + "department": "Camera", + "job": "Clapper Loader" + }, + { + "adult": false, + "gender": 0, + "id": 2010298, + "known_for_department": "Crew", + "name": "Victor Anderson", + "original_name": "Victor Anderson", + "popularity": 0.828, + "profile_path": null, + "credit_id": "5abccfb90e0a2609e402567f", + "department": "Crew", + "job": "Propmaker" + }, + { + "adult": false, + "gender": 0, + "id": 2010303, + "known_for_department": "Sound", + "name": "Paul Smith", + "original_name": "Paul Smith", + "popularity": 0.716, + "profile_path": null, + "credit_id": "5abcd0f60e0a2609db026a49", + "department": "Sound", + "job": "Dialogue Editor" + }, + { + "adult": false, + "gender": 2, + "id": 2010304, + "known_for_department": "Editing", + "name": "Simon Harris", + "original_name": "Simon Harris", + "popularity": 1.62, + "profile_path": null, + "credit_id": "5abcd1090e0a2609de025aa1", + "department": "Editing", + "job": "First Assistant Editor" + }, + { + "adult": false, + "gender": 0, + "id": 2010306, + "known_for_department": "Production", + "name": "Margaret Adams", + "original_name": "Margaret Adams", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5abcd1c1c3a36843620248b7", + "department": "Production", + "job": "Production Coordinator" + }, + { + "adult": false, + "gender": 0, + "id": 2010307, + "known_for_department": "Sound", + "name": "John Samworth", + "original_name": "John Samworth", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5abcd1dd9251411e9c024469", + "department": "Sound", + "job": "Boom Operator" + }, + { + "adult": false, + "gender": 1, + "id": 2010308, + "known_for_department": "Sound", + "name": "Paula Connor", + "original_name": "Paula Connor", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5abcd1eb9251411ea3024b47", + "department": "Sound", + "job": "Assistant Sound Editor" + }, + { + "adult": false, + "gender": 0, + "id": 2010309, + "known_for_department": "Sound", + "name": "Rocky Phelan", + "original_name": "Rocky Phelan", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abcd1f99251411e95025980", + "department": "Sound", + "job": "Foley Editor" + }, + { + "adult": false, + "gender": 0, + "id": 2010310, + "known_for_department": "Sound", + "name": "Eric Tomlinson", + "original_name": "Eric Tomlinson", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5abcd2569251411ea3024b8e", + "department": "Sound", + "job": "Scoring Mixer" + }, + { + "adult": false, + "gender": 0, + "id": 2010317, + "known_for_department": "Visual Effects", + "name": "Peter Watson", + "original_name": "Peter Watson", + "popularity": 0.828, + "profile_path": null, + "credit_id": "5abcd35fc3a368435c026ac1", + "department": "Visual Effects", + "job": "Visual Effects Coordinator" + }, + { + "adult": false, + "gender": 0, + "id": 2010318, + "known_for_department": "Production", + "name": "Pat Harrison", + "original_name": "Pat Harrison", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5abcd393c3a36843a6027232", + "department": "Production", + "job": "Unit Manager" + }, + { + "adult": false, + "gender": 2, + "id": 2029625, + "known_for_department": "Art", + "name": "Michael White", + "original_name": "Michael White", + "popularity": 1.96, + "profile_path": null, + "credit_id": "5ae05f0fc3a3683dd50100dd", + "department": "Art", + "job": "Production Illustrator" + }, + { + "adult": false, + "gender": 2, + "id": 2064618, + "known_for_department": "Crew", + "name": "Terry Cade", + "original_name": "Terry Cade", + "popularity": 2.236, + "profile_path": null, + "credit_id": "64d63730f14dad011dfc7de8", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 2067045, + "known_for_department": "Crew", + "name": "Tracey Eddon", + "original_name": "Tracey Eddon", + "popularity": 3.444, + "profile_path": null, + "credit_id": "62ca108405f9cf004fde50f8", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 2067233, + "known_for_department": "Sound", + "name": "John Falcini", + "original_name": "John Falcini", + "popularity": 0.98, + "profile_path": null, + "credit_id": "5cef09ce925141099fb89bdc", + "department": "Sound", + "job": "Second Assistant Sound" + }, + { + "adult": false, + "gender": 0, + "id": 2071819, + "known_for_department": "Crew", + "name": "Tim Hegarty", + "original_name": "Tim Hegarty", + "popularity": 0.828, + "profile_path": null, + "credit_id": "64d637cbb6c2641154f88535", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 0, + "id": 2143263, + "known_for_department": "Crew", + "name": "Nick Powell", + "original_name": "Nick Powell", + "popularity": 1.154, + "profile_path": null, + "credit_id": "64d63769b6c2641154f88506", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 2158645, + "known_for_department": "Crew", + "name": "Tony van Silva", + "original_name": "Tony van Silva", + "popularity": 0.84, + "profile_path": "/jOB4aZDeTrQ68f1oWhkrlLgr3PB.jpg", + "credit_id": "64d6378df14dad00e3b8082d", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 2191782, + "known_for_department": "Art", + "name": "Les Benson", + "original_name": "Les Benson", + "popularity": 1.22, + "profile_path": null, + "credit_id": "5c28617992514138e1c00c28", + "department": "Art", + "job": "Dressing Prop" + }, + { + "adult": false, + "gender": 0, + "id": 2230776, + "known_for_department": "Crew", + "name": "Robin Demetriou", + "original_name": "Robin Demetriou", + "popularity": 1.532, + "profile_path": null, + "credit_id": "5cef0adc0e0a264555ca1214", + "department": "Crew", + "job": "Catering" + }, + { + "adult": false, + "gender": 0, + "id": 2238043, + "known_for_department": "Directing", + "name": "Melvin Lind", + "original_name": "Melvin Lind", + "popularity": 0.697, + "profile_path": null, + "credit_id": "5cef0948925141099fb89aea", + "department": "Directing", + "job": "Second Assistant Director" + }, + { + "adult": false, + "gender": 0, + "id": 2240466, + "known_for_department": "Production", + "name": "Chrissie Richardson", + "original_name": "Chrissie Richardson", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5cef0ab70e0a263878c9ed0b", + "department": "Production", + "job": "Assistant Accountant" + }, + { + "adult": false, + "gender": 0, + "id": 2324786, + "known_for_department": "Costume & Make-Up", + "name": "Tommy Nutter", + "original_name": "Tommy Nutter", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef093bc3a36863ba1e4146", + "department": "Costume & Make-Up", + "job": "Tailor" + }, + { + "adult": false, + "gender": 0, + "id": 2324787, + "known_for_department": "Directing", + "name": "Steve Millson", + "original_name": "Steve Millson", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef095dc3a3685e881e4905", + "department": "Directing", + "job": "Third Assistant Director" + }, + { + "adult": false, + "gender": 0, + "id": 2324788, + "known_for_department": "Art", + "name": "Michael King", + "original_name": "Michael King", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef096e92514109b5b89552", + "department": "Art", + "job": "Construction Buyer" + }, + { + "adult": false, + "gender": 0, + "id": 2324790, + "known_for_department": "Art", + "name": "Les Andrews", + "original_name": "Les Andrews", + "popularity": 1.4, + "profile_path": null, + "credit_id": "5cef099a0e0a264146ca1719", + "department": "Art", + "job": "Dressing Prop" + }, + { + "adult": false, + "gender": 0, + "id": 2324791, + "known_for_department": "Crew", + "name": "Philip Clark", + "original_name": "Philip Clark", + "popularity": 0.694, + "profile_path": null, + "credit_id": "5cef09e5c3a36863ba1e4285", + "department": "Crew", + "job": "Special Effects Technician" + }, + { + "adult": false, + "gender": 2, + "id": 2324793, + "known_for_department": "Crew", + "name": "Christian Wolf-La'Moy", + "original_name": "Christian Wolf-La'Moy", + "popularity": 1.171, + "profile_path": null, + "credit_id": "5cef0a200e0a261bbbd4c652", + "department": "Crew", + "job": "Stunt Driver" + }, + { + "adult": false, + "gender": 0, + "id": 2324796, + "known_for_department": "Costume & Make-Up", + "name": "Len Alexander", + "original_name": "Len Alexander", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef0a830e0a263878c9ec8c", + "department": "Costume & Make-Up", + "job": "Wardrobe Assistant" + }, + { + "adult": false, + "gender": 0, + "id": 2324797, + "known_for_department": "Crew", + "name": "Maggie Choyce", + "original_name": "Maggie Choyce", + "popularity": 0.84, + "profile_path": null, + "credit_id": "5cef0ac90e0a263878c9ed16", + "department": "Crew", + "job": "Assistant Script" + }, + { + "adult": false, + "gender": 0, + "id": 2324799, + "known_for_department": "Crew", + "name": "Terry Shane", + "original_name": "Terry Shane", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef0aed0e0a26346dc9ec82", + "department": "Crew", + "job": "Floor Runner" + }, + { + "adult": false, + "gender": 0, + "id": 2324800, + "known_for_department": "Production", + "name": "Max Brown", + "original_name": "Max Brown", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef0b1d0e0a2613cdcb9181", + "department": "Production", + "job": "Production Runner" + }, + { + "adult": false, + "gender": 0, + "id": 2324801, + "known_for_department": "Visual Effects", + "name": "Janice Body", + "original_name": "Janice Body", + "popularity": 0.6, + "profile_path": null, + "credit_id": "5cef0b280e0a2636a5cb8269", + "department": "Visual Effects", + "job": "Rotoscoping Artist" + }, + { + "adult": false, + "gender": 2, + "id": 2442990, + "known_for_department": "Acting", + "name": "Ken Barker", + "original_name": "Ken Barker", + "popularity": 0.856, + "profile_path": null, + "credit_id": "5abcd0269251411e9c0242e9", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 1, + "id": 2451270, + "known_for_department": "Crew", + "name": "Dorothy Ford", + "original_name": "Dorothy Ford", + "popularity": 0.6, + "profile_path": null, + "credit_id": "62ca106d4b9bae0a50ca6eb5", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 2660356, + "known_for_department": "Acting", + "name": "Steve Whyment", + "original_name": "Steve Whyment", + "popularity": 1.176, + "profile_path": null, + "credit_id": "64d637a7f14dad01004b3818", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 2689239, + "known_for_department": "Crew", + "name": "Mark McBride", + "original_name": "Mark McBride", + "popularity": 0.732, + "profile_path": null, + "credit_id": "64d6374ddb4ed600c5608239", + "department": "Crew", + "job": "Stunts" + }, + { + "adult": false, + "gender": 2, + "id": 2725757, + "known_for_department": "Crew", + "name": "Jeff Hewitt-Davis", + "original_name": "Jeff Hewitt-Davis", + "popularity": 1.4, + "profile_path": null, + "credit_id": "64d63752f14dad00e3b8080f", + "department": "Crew", + "job": "Stunts" + } + ] +} \ No newline at end of file diff --git a/spec/fixtures/specific_movie_reviews.json b/spec/fixtures/specific_movie_reviews.json new file mode 100644 index 000000000..f8756d9a0 --- /dev/null +++ b/spec/fixtures/specific_movie_reviews.json @@ -0,0 +1,120 @@ +{ + "id": 268, + "page": 1, + "results": [ + { + "author": "John Chard", + "author_details": { + "name": "", + "username": "John Chard", + "avatar_path": "/utEXl2EDiXBK6f41wCLsvprvMg4.jpg", + "rating": 8.0 + }, + "content": "Vision not fully realised, but still a template of sorts.\r\n\r\nIt could never have lived up to the hype back in 1989, it was hailed as the film to rival the impact of \"Jaws\" & \"Star Wars\" as regards historical cinema conventions, it was, we were led to believe, a new age in cinema, or so it seemed. As it was, the film went down a treat for the modern cinema going audience, it raked in cash galore and spawned a raft of very inferior sequels, even though ultimately critics of the time were less than impressed.\r\n\r\nSo it makes for something of an interesting experience viewing it again as each decade passes. More so in light of Christopher Nolan's bank busting \"Dark Knight\" series of films. I remember the hype and marketing campaign (T-Shirts and toys bonanza) that ensured that the film could never live up to the gargantuan hype, and I'm honest enough to say that I was a little underwhelmed on first viewing. Yet time has been very kind to it, now showing that Burton had the nous and foresight to reignite a genre without going purely for kiddie like appeasements. \r\n\r\nVisually the film still stands up with the best that today's genre pieces can offer, the sets are incredible, with Anton Furst rightly winning the big award for his work here, whilst Burton's dark and deep tone captures the essence of Gotham City and Bruce Wayne's troubled mind perfectly, but does the cast fully realise the potential on offer?. Michael Keaton as the troubled and vengeful Bruce Wayne, is a fine actor and it would only be in time where his take on Wayne the man would be appreciated, as the caped crusader he is outstanding and he set the bar high for all those that followed him. \r\n\r\nJack Nicholson has the time of his life camping it up as The Joker, and he steals the film for sure. This is not because he is acting with great poise and class, but purely because in a film calling for the battle of two unhinged characters, he is the one awash in colour and overacting the maniacal side of the character to the max. Kim Basinger looks great but doesn't have to do much as Vicki Vale except say her lines right, pout, look scared when required and scream with conviction, and she does all of these. But really any other actress could have done the same thing - though I'm personally relieved that Sean Young dropped out of the film and thus allowed some other actress to step in. \r\n\r\nThe supporting cast do OK, and the soundtrack by Prince pushes the boundaries of annoying caricature indulgence. Ultimately it's a fun ride, respectful of the source material and giving the comic book genre of fil a shot in the arm. Yet you can't help feeling that there is some great Burton vision here that never got fully realised. And that is a damn shame, and something that Burton himself would come to admit down the line. 8/10", + "created_at": "2016-07-29T10:46:56.656Z", + "id": "579b3420c3a3686e13000085", + "updated_at": "2021-06-23T15:57:49.682Z", + "url": "https://www.themoviedb.org/review/579b3420c3a3686e13000085" + }, + { + "author": "Albert", + "author_details": { + "name": "Albert", + "username": "KingStradivarius", + "avatar_path": "/lONgEpLBCbaA7DDKvFQuT0dNlAK.jpg", + "rating": 4.0 + }, + "content": "This movie is so bad I couldn't even finish it.", + "created_at": "2017-08-21T16:27:11.549Z", + "id": "599b09dfc3a3681dde000414", + "updated_at": "2021-06-23T15:58:00.333Z", + "url": "https://www.themoviedb.org/review/599b09dfc3a3681dde000414" + }, + { + "author": "Jakeflix", + "author_details": { + "name": "Jakeflix", + "username": "JakeWarren", + "avatar_path": "/oFnkgH7tRRTyafb6ngKtWZvlJu4.jpg", + "rating": 10.0 + }, + "content": "Yeah, it's good.", + "created_at": "2019-05-14T18:30:33.779Z", + "id": "5cdb094992514121dad3bb44", + "updated_at": "2021-06-23T15:58:22.232Z", + "url": "https://www.themoviedb.org/review/5cdb094992514121dad3bb44" + }, + { + "author": "Wuchak", + "author_details": { + "name": "", + "username": "Wuchak", + "avatar_path": "/4KVM1VkqmXLOuwj1jjaSdxbvBDk.jpg", + "rating": 4.0 + }, + "content": "_**Looks good, but surreal and tedious**_\r\n\r\nTim Burton's \"Batman\" (1989) is _so_ disappointing! Yeah, the costumes, sets, cast, cinematography and music are great, but the story is unrealistic, goofy and, worst of all, dull; in other words, it siphoned! Tim Burton is outstanding with visuals, but he failed to incorporate an interesting story. What good is a BORING film that looks great and doesn't take its subject seriously? This is a quintessential example of style over substance.\r\n\r\nMost of the high ratings are from people who saw it when they were kids and they're just nostalgic. If they viewed the film objectively as an adult, with respect to the true Batman of the silver/bronze/modern age of comics, they'd have to admit that it's not a good interpretation.\r\n\r\nSure, it could be accepted as a sort of an ALTERNATIVE Batman; a friend of mine who's in the comic business said this was the only way he could appreciate it. But if you want to see a serious Batman flick, true to the legend of the Dark Knight, catch \"Batman Begins\" (2005) and its sequels, they blow this overrated soporific dud out of the water.\r\n\r\nThe movie's overlong at 2 hours, 6 minutes. \r\n\r\nGRADE: C", + "created_at": "2020-07-21T17:39:21.396Z", + "id": "5f17284978570e00346bb954", + "updated_at": "2021-06-23T15:58:41.034Z", + "url": "https://www.themoviedb.org/review/5f17284978570e00346bb954" + }, + { + "author": "The Movie Mob", + "author_details": { + "name": "The Movie Mob", + "username": "mooney240", + "avatar_path": "/blEC280vq31MVaDcsWBXuGOsYnB.jpg", + "rating": 7.0 + }, + "content": "**Batman 1989 burst on the scene shattering the box office and rewriting the rules of comic book films with dark characters and high stakes in ways no superhero movie had seen before.**\r\n\r\nSuperhero movies of the 70s and 80s were bright and colorful, goofy and optimistic, champions of truth, Justice, and the American Way. Movies like Superman, Supergirl, the original Captain America, and even Adam West’s Batman all fit this vibe and aesthetic, with many overly campy but charming. This made Tim Burton’s darker, more violent Batman a huge gamble. Warner Bros literally sank every last penny they had into the movie as the studio was collapsing and going out of business. A dark superhero film with murder and blood? Michael Keaton? Mr. Mom himself as Batman? It was a massive risk with a tremendous payoff! Warner Bros survived and thrived off the enormous box office profits, and Batman reinvented the superhero genre showing that adults could enjoy superhero movies too. Even though Batman 1989 is a little dated and campy now, it broke every mold when it was released. Michael Keaton proved himself as the incredible star and bankable actor that he is. Jack Nicholson’s Joker stood as the iconic standard for villains for decades. Kim Basinger’s Vicki Vale is still one of the best Batman love interests to date. Tim Burton saved superheroes and movie studios with this dark reinvention of the comic book genre. It’s a true superhero classic.", + "created_at": "2023-02-11T03:23:32.381Z", + "id": "63e70a34d388ae0080612dc8", + "updated_at": "2023-02-11T03:23:32.456Z", + "url": "https://www.themoviedb.org/review/63e70a34d388ae0080612dc8" + }, + { + "author": "Andre Gonzales", + "author_details": { + "name": "Andre Gonzales", + "username": "SoSmooth1982", + "avatar_path": "/ast1oGYDI7Li9daLuOV4UxGiXj.jpg", + "rating": 10.0 + }, + "content": "There will never be a greater batman or movie ever. The original is still the only good batman movie out there. They keep trying but they had it right the 1st time, and they messed it up now.", + "created_at": "2023-04-25T05:13:57.256Z", + "id": "64476195397df004404bcc01", + "updated_at": "2023-04-25T05:13:57.326Z", + "url": "https://www.themoviedb.org/review/64476195397df004404bcc01" + }, + { + "author": "Rob", + "author_details": { + "name": "Rob", + "username": "Arcanum101", + "avatar_path": "/w7CFzleuBl2EMBEl08fSA14aUOy.jpg", + "rating": 8.0 + }, + "content": "Probably one of the first serious attempts at bringing a comic to the big screen with a decent budget. The vision of the world is brilliant. Keaton's Batman is spot on and the Prince soundtrack ties the whole thing together perfectly. Unfortunately, Tim Burton's flamboyance lets things down in the end. But still the most memorable Batman to date. Although Ben Affleck's jaded, grumpy and bulked-out depiction of the character in Batman V Superman is my favourite.", + "created_at": "2023-05-28T10:58:57.048Z", + "id": "647333f1dd731b2d78b98be6", + "updated_at": "2023-05-28T10:58:57.129Z", + "url": "https://www.themoviedb.org/review/647333f1dd731b2d78b98be6" + }, + { + "author": "CinemaSerf", + "author_details": { + "name": "CinemaSerf", + "username": "Geronimo1967", + "avatar_path": "/1kks3YnVkpyQxzw36CObFPvhL5f.jpg", + "rating": 6.0 + }, + "content": "\"Batman\" never was my favourite superhero, and although Michael Keaton tries hard here to inject a little soul into the character, I'm afraid I found Jack Nicholson's totally over-the-top \"Joker\" to be just annoying and the whole film to be little underwhelming. \"Gotham City\" is essentially an urban jungle under the boot of the menacing \"Grissom\" (Jack Palance). He and his sidekick \"Napier\" (Nicholson) - who only has a limited grasp on his sanity - have a bit of a falling out, though, and the latter man is soon swimming in a vat of deadly chemicals... The result? Well his madness is now completely unleashed on his former boss then on the entire city as he attempts to gain complete control. Luckily for DA \"Harvey Dent\" (Billy Dee Williams) and Police Commissioner \"Gordon\" (Pat Hingle) the city might just have a chance of salvation in the form of our eponymous, black leather-caped, crusader. Equipped with a bullet-proof car, a super-charged motor bike and some heavy duty kevlar body armour he vows to take on the criminal element and restore some sort of order. He, too, has his demons - which we learn about as the story develops, and it seems they can only be tempered by his loyal retainer \"Alfred\" (Michael Gough). As the stakes rise, it soon becomes a man-to-man combat scenario that I found all rather too theatrical. The visual effects are solid, the audio and lighting also work well to create an at times intimidating atmosphere, but I just found myself missing the point. There can be no doubt that Nicholson's performance as an actor is outstanding, but for me it created a relentless, almost pantomime-style, character that as it persisted just rather left me looking around the cinema wondering what Burt Ward was doing nowadays. Groundbreaking it was in 1989. In 2023 - well I'm not at all sure. It does look good, though!", + "created_at": "2023-10-22T10:06:31.581Z", + "id": "6534f42742d83700eac60156", + "updated_at": "2023-10-22T10:06:31.691Z", + "url": "https://www.themoviedb.org/review/6534f42742d83700eac60156" + } + ], + "total_pages": 1, + "total_results": 8 +} \ No newline at end of file From 805a184c11da030cf133515b9968d925af7fe517 Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Wed, 29 Nov 2023 12:54:00 -0600 Subject: [PATCH 12/24] add feature for discover movies dashboard --- app/controllers/discover_controller.rb | 2 +- app/views/users/discover/index.html.erb | 1 + app/views/users/show.html.erb | 2 +- spec/features/users/discover/index_spec.rb | 50 +++++++++++++++++----- 4 files changed, 42 insertions(+), 13 deletions(-) create mode 100644 app/views/users/discover/index.html.erb diff --git a/app/controllers/discover_controller.rb b/app/controllers/discover_controller.rb index 6ef137b41..cac480693 100644 --- a/app/controllers/discover_controller.rb +++ b/app/controllers/discover_controller.rb @@ -1,5 +1,5 @@ class DiscoverController < ApplicationController def index - + @user = User.find(params[:user_id]) end end \ No newline at end of file diff --git a/app/views/users/discover/index.html.erb b/app/views/users/discover/index.html.erb new file mode 100644 index 000000000..46a668283 --- /dev/null +++ b/app/views/users/discover/index.html.erb @@ -0,0 +1 @@ +

Discover Movies for <%= @user.name %>

diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 965da8b24..35f17bbf1 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -1,6 +1,6 @@

<%= @user.name %>'s Dashboard!

-<%= button_to 'Discover Movies', user_discover_index_path(@user), class: 'btn btn-primary' %> +<%= button_to 'Discover Movies', user_discover_index_path(@user), method: :get, class: 'btn btn-primary' %>

Viewing Parties

diff --git a/spec/features/users/discover/index_spec.rb b/spec/features/users/discover/index_spec.rb index f6b5b7ea8..22feb3247 100644 --- a/spec/features/users/discover/index_spec.rb +++ b/spec/features/users/discover/index_spec.rb @@ -1,32 +1,60 @@ require 'rails_helper' -RSpec.describe 'Discover Movies Page' do +RSpec.describe 'Discover Movies Page' do before(:each) do load_test_data end - it 'When a user can get to movie results through movie title search' do + it 'redirects to discover page when "Discover Movies" button is clicked' do + visit user_path(@user1) + click_button 'Discover Movies' + + expect(current_path).to eq(user_discover_path(@user1)) + end + + it 'displays "Discover Top Rated Movies" and "Search by Movie Title" buttons on discover page' do + visit user_discover_index_path(@user1) + expect(page).to have_button('Discover Top Rated Movies') + expect(page).to have_button('Search by Movie Title') + end + + it 'redirects to movie results page when "Search by Movie Title" button is clicked' do + visit user_discover_index_path(@user1) + + fill_in 'Movie_Title', with: 'Batman' + click_button 'Search by Movie Title' + + expect(current_path).to eq(user_movies_path(@user1)) + end + it 'redirects to movie results page when "Discover Top Rated Movies" button is clicked' do + visit user_discover_index_path(@user1) + + click_button 'Discover Top Rated Movies' + + expect(current_path).to eq(user_movies_path(@user1)) + end + + it 'When a user can get to movie results through movie title search' do visit "/users/#{@user1.id}/discover" - - expect(page).to have_button("Discover Top Rated Movies") - expect(page).to have_button("Search by Movie Title") - fill_in 'Movie_Title', with: "Batman" + expect(page).to have_button('Discover Top Rated Movies') + expect(page).to have_button('Search by Movie Title') + + fill_in 'Movie_Title', with: 'Batman' # click_button "Search by Movie Title" # expect(current_path).to eq("/users/#{@user1.id}/movies") end it 'When a user can get to movie results through top rated movies button' do - visit "/users/#{@user1.id}/discover" - - expect(page).to have_button("Discover Top Rated Movies") - expect(page).to have_button("Search by Movie Title") + + expect(page).to have_button('Discover Top Rated Movies') + expect(page).to have_button('Search by Movie Title') # click_button "Discover Top Rated Movies" # expect(current_path).to eq("/users/#{@user1.id}/movies") end -end \ No newline at end of file +end From 055a9e04d225e4854dd0fb2a7cdb618c52bad583 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Wed, 29 Nov 2023 14:17:01 -0700 Subject: [PATCH 13/24] Removed a redundant landing page link, also removed id and url from details and replaced it with the actual review, makes more sense --- app/views/layouts/application.html.erb | 1 - app/views/movies/show.html.erb | 3 +-- spec/features/users/movies/show_spec.rb | 11 ++++------- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 2ce9eb1c1..4810cad91 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -2,7 +2,6 @@ ViewingPartyLite7 - <%= link_to "Go to Landing Page", root_path, class: 'btn btn-primary' %> <%= csrf_meta_tags %> <%= csp_meta_tag %> diff --git a/app/views/movies/show.html.erb b/app/views/movies/show.html.erb index ed34d6863..0d2bcbd9f 100644 --- a/app/views/movies/show.html.erb +++ b/app/views/movies/show.html.erb @@ -30,8 +30,7 @@ <% @movie_review[:results].each do |reviewer| %>
  • Name: <%= reviewer[:author] %>
  • Rating: <%= reviewer[:author_details][:rating] %>
  • -
  • ID: <%= reviewer[:id] %>
  • -
  • URL: <%= reviewer[:url] %>
  • +
  • Review: <%= reviewer[:content] %>

  • <% end %> diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb index ac0b1cf12..63a6cf7c1 100644 --- a/spec/features/users/movies/show_spec.rb +++ b/spec/features/users/movies/show_spec.rb @@ -37,7 +37,7 @@ to_return(status: 200, body: reviews_response, headers: {}) visit "/users/#{@user1.id}/movies/268" - click_link "Go to Landing Page" + click_link "Go back to Landing Page" expect(current_path).to eq("/") visit "/users/#{@user1.id}/movies/268" @@ -71,13 +71,10 @@ expect(page).to have_content("Tracey Walter") expect(page).to have_content("Name: John Chard") - expect(page).to have_content("Rating: 8.0") - expect(page).to have_content("ID: 579b3420c3a3686e13000085") - expect(page).to have_content("URL: https://www.themoviedb.org/review/579b3420c3a3686e13000085") + expect(page).to have_content("Rating: 8.0") + expect(page).to have_content("Review: There will never be a greater batman or movie ever. The original is still the only good batman movie out there. They keep trying but they had it right the 1st time, and they messed it up now.") expect(page).to have_content("Name: Albert") - expect(page).to have_content("Rating: 4.0") - expect(page).to have_content("ID: 599b09dfc3a3681dde000414") - expect(page).to have_content("URL: https://www.themoviedb.org/review/599b09dfc3a3681dde000414") + expect(page).to have_content("Rating: 4.0") end end \ No newline at end of file From 7e01c96ce461c98acc40282cb0a20c531921733c Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Wed, 29 Nov 2023 17:27:56 -0600 Subject: [PATCH 14/24] add tests for dashboard discover movies and edit rubocop to ignore specs --- .rubocop.yml | 6 +++ spec/features/users/discover/index_spec.rb | 30 ----------- spec/features/users/movies/show_spec.rb | 58 ++++++++++++++++++++++ 3 files changed, 64 insertions(+), 30 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 000000000..4ec05cdc7 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,6 @@ +Style/FrozenStringLiteralComment: + Enabled: false + +Metrics/BlockLength: + IgnoredMethods: + - RSpec.describe \ No newline at end of file diff --git a/spec/features/users/discover/index_spec.rb b/spec/features/users/discover/index_spec.rb index 22feb3247..591c73d75 100644 --- a/spec/features/users/discover/index_spec.rb +++ b/spec/features/users/discover/index_spec.rb @@ -5,36 +5,6 @@ load_test_data end - it 'redirects to discover page when "Discover Movies" button is clicked' do - visit user_path(@user1) - click_button 'Discover Movies' - - expect(current_path).to eq(user_discover_path(@user1)) - end - - it 'displays "Discover Top Rated Movies" and "Search by Movie Title" buttons on discover page' do - visit user_discover_index_path(@user1) - expect(page).to have_button('Discover Top Rated Movies') - expect(page).to have_button('Search by Movie Title') - end - - it 'redirects to movie results page when "Search by Movie Title" button is clicked' do - visit user_discover_index_path(@user1) - - fill_in 'Movie_Title', with: 'Batman' - click_button 'Search by Movie Title' - - expect(current_path).to eq(user_movies_path(@user1)) - end - - it 'redirects to movie results page when "Discover Top Rated Movies" button is clicked' do - visit user_discover_index_path(@user1) - - click_button 'Discover Top Rated Movies' - - expect(current_path).to eq(user_movies_path(@user1)) - end - it 'When a user can get to movie results through movie title search' do visit "/users/#{@user1.id}/discover" diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb index e69de29bb..1baee5fce 100644 --- a/spec/features/users/movies/show_spec.rb +++ b/spec/features/users/movies/show_spec.rb @@ -0,0 +1,58 @@ +RSpec.describe 'Discover Movies Page' do + before(:each) do + load_test_data + end + + it 'redirects to discover page when "Discover Movies" button is clicked' do + visit user_path(@user1) + click_button 'Discover Movies' + + expect(current_path).to eq(user_discover_index_path(@user1)) + end + + it 'displays "Discover Top Rated Movies" and "Search by Movie Title" buttons on discover page' do + visit user_discover_index_path(@user1) + expect(page).to have_button('Discover Top Rated Movies') + expect(page).to have_button('Search by Movie Title') + end + + it 'redirects to movie results page when "Search by Movie Title" button is clicked' do + batman_movie_response = File.read('spec/fixtures/batman_movies.json') + + stub_request(:get, "https://api.themoviedb.org/3/search/movie?api_key=#{Rails.application.credentials.tmdb[:key]}&query=Batman") + .with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Faraday v2.7.12' + } + ) + .to_return(status: 200, body: batman_movie_response, headers: {}) + visit user_discover_index_path(@user1) + + fill_in 'Movie_Title', with: 'Batman' + click_button 'Search by Movie Title' + + expect(current_path).to eq(user_movies_path(@user1)) + end + + it 'redirects to movie results page when "Discover Top Rated Movies" button is clicked' do + popular_movie_response = File.read('spec/fixtures/batman_movies.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/popular?api_key=#{Rails.application.credentials.tmdb[:key]}") + .with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Faraday v2.7.12' + } + ) + .to_return(status: 200, body: popular_movie_response, headers: {}) + + visit user_discover_index_path(@user1) + + click_button 'Discover Top Rated Movies' + + expect(current_path).to eq(user_movies_path(@user1)) + end +end From a4c69dca3e0321f09006b9a0a0b34903bb45fa3f Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Wed, 29 Nov 2023 17:32:33 -0600 Subject: [PATCH 15/24] fix tests for dashboard discover movies --- spec/features/users/movies/show_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb index 1baee5fce..3e4dfada6 100644 --- a/spec/features/users/movies/show_spec.rb +++ b/spec/features/users/movies/show_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe 'Discover Movies Page' do +RSpec.describe 'Discover Movies Show Page Page' do before(:each) do load_test_data end From cf5d5a78e413e549784dca4b7c5de65e8df27d82 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Wed, 29 Nov 2023 16:54:02 -0700 Subject: [PATCH 16/24] Add creation of viewing parties and add the flag that shows which user is the host and which is the guest/attendee --- app/views/layouts/application.html.erb | 1 - app/views/viewing_parties/new.html.erb | 15 +++++++ config/routes.rb | 1 + spec/features/users/movies/show_spec.rb | 2 +- .../users/movies/viewing-party/new_spec.rb | 43 +++++++++++++++++++ 5 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 spec/features/users/movies/viewing-party/new_spec.rb diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 2ce9eb1c1..4810cad91 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -2,7 +2,6 @@ ViewingPartyLite7 - <%= link_to "Go to Landing Page", root_path, class: 'btn btn-primary' %> <%= csrf_meta_tags %> <%= csp_meta_tag %> diff --git a/app/views/viewing_parties/new.html.erb b/app/views/viewing_parties/new.html.erb index e69de29bb..3cc79764f 100644 --- a/app/views/viewing_parties/new.html.erb +++ b/app/views/viewing_parties/new.html.erb @@ -0,0 +1,15 @@ +

    <%= @movie[:title] %>

    + +<%= form_with url: "/users/#{@user.id}/movies/#{@movie[:id]}/viewing-party/create", method: :post, local: true do |form| %> + <%= form.number_field :duration, value: @movie[:runtime], min: @movie[:runtime] %> + <%= form.label "Duration of Party in minutes" %> + <%= form.date_field :date, data: {provide: "datepicker"} %> + <%= form.label :date, "Date of Party" %> + <%= form.time_field :start_time %> + <%= form.label :start_time, "Start of Party" %> + <%= form.hidden_field :status, value: "host" %> + <% @users.each do |user| %> +

    <%= check_box_tag(user.id, hidden_field: :status, value: "attending #{user.id}") %> <%= form.label "#{user.id}", "#{user.name} (#{user.email})" %>

    + <% end %>
    + <%= form.submit "Create Party" %> +<% end%> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 2272f6201..9a0cf2ab7 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -12,4 +12,5 @@ end get "/users/:user_id/movies/:movid_id/viewing-party/new", to: "viewing_parties#new" + post "/users/:user_id/movies/:movid_id/viewing-party/create", to: "viewing_parties#create" end diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb index ac0b1cf12..012cd362e 100644 --- a/spec/features/users/movies/show_spec.rb +++ b/spec/features/users/movies/show_spec.rb @@ -37,7 +37,7 @@ to_return(status: 200, body: reviews_response, headers: {}) visit "/users/#{@user1.id}/movies/268" - click_link "Go to Landing Page" + click_link "Go back to Landing Page" expect(current_path).to eq("/") visit "/users/#{@user1.id}/movies/268" diff --git a/spec/features/users/movies/viewing-party/new_spec.rb b/spec/features/users/movies/viewing-party/new_spec.rb new file mode 100644 index 000000000..805c949d7 --- /dev/null +++ b/spec/features/users/movies/viewing-party/new_spec.rb @@ -0,0 +1,43 @@ +require 'rails_helper' + +RSpec.describe 'New Viewing Party Page' do + before(:each) do + load_test_data + end + + it 'When I visit the new viewing party page it contains movie title, duration of party, when date, start time, checkboxes next to each user' do + specific_movie_response = File.read('spec/fixtures/specific_movie.json') + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: specific_movie_response, headers: {}) + + visit "/users/#{@user1.id}/movies/268/viewing-party/new" + expect(page).to have_field(:duration, with:126) + expect(page).to have_field(:date) + expect(page).to have_field(:start_time) + expect(page).to have_button('Create Party') + expect(page).to have_content('Batman') + + expect(@user2.user_parties.count).to eq(3) + expect(@user3.user_parties.count).to eq(2) + + fill_in :duration, with: 180 + fill_in :start_time, with: '10:00' + fill_in :date, with: '2023/08/01' + check "#{@user2.name} (#{@user2.email})" + check "#{@user3.name} (#{@user3.email})" + click_button 'Create Party' + + expect(current_path).to eq(user_path(@user1.id)) + # save_and_open_page + # expect(page).to have_content('Batman') + + # expect(@user2.user_parties.count).to eq(4) + # expect(@user3.user_parties.count).to eq(3) + end +end \ No newline at end of file From ce7c00e8ddfd64957c6ab2c95335ddda76491149 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Thu, 30 Nov 2023 15:34:00 -0700 Subject: [PATCH 17/24] Added in display for current user to see when parties they are host and attending, updated tests to include the poros, services, and facades. Also added units tests for models to get the host name and user names of a party. Tests still use web mock and can be run off line --- app/controllers/users_controller.rb | 8 +- app/models/party.rb | 7 ++ app/models/user_party.rb | 4 + app/views/users/show.html.erb | 51 +++++++- spec/facades/movie_facade_spec.rb | 95 ++++++++++++++ spec/features/users/movies/show_spec.rb | 21 ++++ .../users/movies/viewing-party/new_spec.rb | 21 ++++ spec/features/users/show_spec.rb | 45 ++++++- spec/fixtures/lotr_collection.json | 79 ++++++++++++ spec/fixtures/search_movie_by_id.json | 43 +++++++ spec/fixtures/starwars_collection.json | 69 +++++++++++ spec/models/party_spec.rb | 8 ++ spec/models/user_party_spec.rb | 8 ++ spec/models/utility_spec.rb | 10 ++ spec/poros/movie_poros_spec.rb | 30 +++++ spec/services/movie_services_spec.rb | 116 ++++++++++++++++++ 16 files changed, 610 insertions(+), 5 deletions(-) create mode 100644 spec/facades/movie_facade_spec.rb create mode 100644 spec/fixtures/lotr_collection.json create mode 100644 spec/fixtures/search_movie_by_id.json create mode 100644 spec/fixtures/starwars_collection.json create mode 100644 spec/models/utility_spec.rb create mode 100644 spec/poros/movie_poros_spec.rb create mode 100644 spec/services/movie_services_spec.rb diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 575ed1ddf..d04f579ed 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -12,8 +12,14 @@ def create end end - def show + def show + facade = MovieFacade.new @user = User.find(params[:id]) + @movies = [] + @user.parties.uniq.each do |party| + @movies << facade.movie_details(party.movie_id) + @movies + end end private diff --git a/app/models/party.rb b/app/models/party.rb index a395a048e..35485dcd1 100644 --- a/app/models/party.rb +++ b/app/models/party.rb @@ -7,4 +7,11 @@ class Party < ApplicationRecord validates_presence_of :duration validates_presence_of :date validates_presence_of :start_time + + def get_host_name + host = user_parties.find do |up| + up.is_host == true + end + User.find(host.user_id).name + end end \ No newline at end of file diff --git a/app/models/user_party.rb b/app/models/user_party.rb index 1066c6cbb..440ea09c2 100644 --- a/app/models/user_party.rb +++ b/app/models/user_party.rb @@ -1,4 +1,8 @@ class UserParty < ApplicationRecord belongs_to :user belongs_to :party + + def get_user_name + User.find(self.user_id).name + end end \ No newline at end of file diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 35f17bbf1..2b4ddcb0c 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -2,7 +2,54 @@ <%= button_to 'Discover Movies', user_discover_index_path(@user), method: :get, class: 'btn btn-primary' %> -
    -

    Viewing Parties

    +
    +

    Attending Parties

    + <% @user.parties.uniq.each do |party| %> + <% if party.get_host_name != @user.name %> + <% @movies.each do |movie| %> + <% if party.movie_id == movie[:id] %> +
  • Movie Image: <%= image_tag "https://image.tmdb.org/t/p/w92#{movie[:poster_path]}" %>
  • +
  • Movie Title: <%= "#{movie[:title]}" %>
  • +
  • Date and Time: <%= "Starts on #{party.date} at #{party.start_time}" %>
  • + <% party.user_parties.each do |us| %> + <% if us.is_host == true %> +
  • Hosted By: <%= "#{us.get_user_name}" %>
  • + <% end %> + <% end %> +
  • Other users attending: + <% party.user_parties.uniq.each do |other_user| %> + <% if party.get_host_name != other_user.get_user_name %> + <%= "#{other_user.get_user_name}" %> + <% end %> + <% end %>
  • + <% end %> + <% end %> + <% end %> + <% end %> +
    +
    +

    Hosting Parties

    + <% @user.parties.uniq.each do |party| %> + <% if party.get_host_name == @user.name %> + <% @movies.each do |movie| %> + <% if party.movie_id == movie[:id] %> +
  • Movie Image: <%= image_tag "https://image.tmdb.org/t/p/w92#{movie[:poster_path]}" %>
  • +
  • Movie Title: <%= "#{movie[:title]}" %>
  • +
  • Date and Time: <%= "Starts on #{party.date} at #{party.start_time}" %>
  • + <% party.user_parties.each do |us| %> + <% if us.is_host == true %> +
  • Hosted By: <%= "#{us.get_user_name}" %>
  • + <% end %> + <% end %> +
  • Other users attending: + <% party.user_parties.uniq.each do |other_user| %> + <% if @user.name != other_user.get_user_name %> + <%= "#{other_user.get_user_name}" %> + <% end %> + <% end %>
  • + <% end %> + <% end %> + <% end %> + <% end %>
    \ No newline at end of file diff --git a/spec/facades/movie_facade_spec.rb b/spec/facades/movie_facade_spec.rb new file mode 100644 index 000000000..de9284363 --- /dev/null +++ b/spec/facades/movie_facade_spec.rb @@ -0,0 +1,95 @@ +require "rails_helper" + +RSpec.describe MovieFacade do + context "Instance methods" do + context "#top_movie" do + it "returns facade" do + json_response = File.read('spec/fixtures/top_twenty_movies.json') + stub_request(:get, "https://api.themoviedb.org/3/movie/popular?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: json_response, headers: {}) + + facade = MovieFacade.new + result = facade.top_movies + expect(result.first.title).to be_a(String) + end + end + + context "#search_movies" do + it "returns facade" do + json_response = File.read('spec/fixtures/batman_movies.json') + stub_request(:get, "https://api.themoviedb.org/3/search/movie?api_key=#{Rails.application.credentials.tmdb[:key]}&query=Batman"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: json_response, headers: {}) + facade = MovieFacade.new + result = facade.search_movies("Batman") + expect(result.first.title).to be_a(String) + end + end + + context "#movie_details" do + it "returns facade" do + specific_movie_response = File.read('spec/fixtures/specific_movie.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: specific_movie_response, headers: {}) + + facade = MovieFacade.new + result = facade.movie_details(268) + expect(result).to be_a Hash + end + end + + context "#movie_cast" do + it "returns facade" do + credits_response = File.read('spec/fixtures/specific_movie_credits.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268/credits?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: credits_response, headers: {}) + + movie_data = MovieService.new.movie_cast(268) + expect(movie_data).to be_a Hash + end + end + + context "#movie_reviews" do + it "returns facade" do + reviews_response = File.read('spec/fixtures/specific_movie_reviews.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268/reviews?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: reviews_response, headers: {}) + + movie_data = MovieService.new.movie_reviews(268) + expect(movie_data).to be_a Hash + end + end + end +end \ No newline at end of file diff --git a/spec/features/users/movies/show_spec.rb b/spec/features/users/movies/show_spec.rb index cecb529e6..c5d7dd214 100644 --- a/spec/features/users/movies/show_spec.rb +++ b/spec/features/users/movies/show_spec.rb @@ -4,6 +4,27 @@ end it 'redirects to discover page when "Discover Movies" button is clicked' do + starwars_response = File.read('spec/fixtures/starwars_collection.json') + lotr_response = File.read('spec/fixtures/lotr_collection.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/11?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: starwars_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/120?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: lotr_response, headers: {}) + visit user_path(@user1) click_button 'Discover Movies' diff --git a/spec/features/users/movies/viewing-party/new_spec.rb b/spec/features/users/movies/viewing-party/new_spec.rb index 805c949d7..3b628616f 100644 --- a/spec/features/users/movies/viewing-party/new_spec.rb +++ b/spec/features/users/movies/viewing-party/new_spec.rb @@ -7,6 +7,27 @@ it 'When I visit the new viewing party page it contains movie title, duration of party, when date, start time, checkboxes next to each user' do specific_movie_response = File.read('spec/fixtures/specific_movie.json') + starwars_response = File.read('spec/fixtures/starwars_collection.json') + lotr_response = File.read('spec/fixtures/lotr_collection.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/11?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: starwars_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/120?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: lotr_response, headers: {}) + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}"). with( headers: { diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index 93807d688..1987ca877 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -4,6 +4,36 @@ before(:each) do load_test_data + specific_movie_response = File.read('spec/fixtures/specific_movie.json') + starwars_response = File.read('spec/fixtures/starwars_collection.json') + lotr_response = File.read('spec/fixtures/lotr_collection.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/11?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: starwars_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/120?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: lotr_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: specific_movie_response, headers: {}) visit "/users/#{@user1.id}" end @@ -16,8 +46,19 @@ end it 'displays a section that lists viewing parties' do - within('section.viewing-parties') do - expect(page).to have_css('h2', text: 'Viewing Parties') + within('section.attending-parties') do + expect(page).to have_css('h2', text: 'Attending Parties') + expect(page).to have_content("Movie Title: The Lord of the Rings: The Fellowship of the Ring") + expect(page).to have_content("Date and Time: Starts on 2023-09-01 at 2000-01-01 11:00:00 UTC") + expect(page).to have_content("Hosted By: Jerry") + expect(page).to have_content("Other users attending: Tom Bob") + end + within('section.hosting-parties') do + expect(page).to have_css('h2', text: 'Hosting Parties') + expect(page).to have_content("Movie Title: Star Wars") + expect(page).to have_content("Date and Time: Starts on 2023-08-01 at 2000-01-01 10:00:00 UTC") + expect(page).to have_content("Hosted By: Tom") + expect(page).to have_content("Other users attending: Jerry Bob") end end end diff --git a/spec/fixtures/lotr_collection.json b/spec/fixtures/lotr_collection.json new file mode 100644 index 000000000..951d61caa --- /dev/null +++ b/spec/fixtures/lotr_collection.json @@ -0,0 +1,79 @@ +{ + "adult": false, + "backdrop_path": "/x2RS3uTcsJJ9IfjNPcgDmukoEcQ.jpg", + "belongs_to_collection": { + "id": 119, + "name": "The Lord of the Rings Collection", + "poster_path": "/oENY593nKRVL2PnxXsMtlh8izb4.jpg", + "backdrop_path": "/bccR2CGTWVVSZAG0yqmy3DIvhTX.jpg" + }, + "budget": 93000000, + "genres": [ + { + "id": 12, + "name": "Adventure" + }, + { + "id": 14, + "name": "Fantasy" + }, + { + "id": 28, + "name": "Action" + } + ], + "homepage": "http://www.lordoftherings.net/", + "id": 120, + "imdb_id": "tt0120737", + "original_language": "en", + "original_title": "The Lord of the Rings: The Fellowship of the Ring", + "overview": "Young hobbit Frodo Baggins, after inheriting a mysterious ring from his uncle Bilbo, must leave his home in order to keep it from falling into the hands of its evil creator. Along the way, a fellowship is formed to protect the ringbearer and make sure that the ring arrives at its final destination: Mt. Doom, the only place where it can be destroyed.", + "popularity": 116.203, + "poster_path": "/6oom5QYQ2yQTMJIbnvbkBL9cHo6.jpg", + "production_companies": [ + { + "id": 12, + "logo_path": "/mevhneWSqbjU22D1MXNd4H9x0r0.png", + "name": "New Line Cinema", + "origin_country": "US" + }, + { + "id": 11, + "logo_path": "/6FAuASQHybRkZUk08p9PzSs9ezM.png", + "name": "WingNut Films", + "origin_country": "NZ" + }, + { + "id": 5237, + "logo_path": null, + "name": "The Saul Zaentz Company", + "origin_country": "US" + } + ], + "production_countries": [ + { + "iso_3166_1": "NZ", + "name": "New Zealand" + }, + { + "iso_3166_1": "US", + "name": "United States of America" + } + ], + "release_date": "2001-12-18", + "revenue": 871368364, + "runtime": 179, + "spoken_languages": [ + { + "english_name": "English", + "iso_639_1": "en", + "name": "English" + } + ], + "status": "Released", + "tagline": "One ring to rule them all", + "title": "The Lord of the Rings: The Fellowship of the Ring", + "video": false, + "vote_average": 8.405, + "vote_count": 23590 +} \ No newline at end of file diff --git a/spec/fixtures/search_movie_by_id.json b/spec/fixtures/search_movie_by_id.json new file mode 100644 index 000000000..3b4960066 --- /dev/null +++ b/spec/fixtures/search_movie_by_id.json @@ -0,0 +1,43 @@ +{ + "page": 1, + "results": [ + { + "adult": false, + "backdrop_path": "/fC8kp9O1U2pGZlR9fKgxXriA7pU.jpg", + "genre_ids": [ + 28 + ], + "id": 888826, + "original_language": "en", + "original_title": "UFC 268: Usman vs. Covington 2", + "overview": "UFC 268: Usman vs. Covington 2 was a mixed martial arts event produced by the Ultimate Fighting Championship that took place on November 6, 2021, at Madison Square Garden in New York City, New York, United States. A UFC Welterweight Championship rematch between the current champion Kamaru Usman (also The Ultimate Fighter: American Top Team vs. Blackzilians welterweight winner) and former interim champion Colby Covington headlined the event.", + "popularity": 1.737, + "poster_path": "/r5qCPAZCMYmvGyJJm9csGuCM9Nq.jpg", + "release_date": "2021-11-06", + "title": "UFC 268: Usman vs. Covington 2", + "video": true, + "vote_average": 2.0, + "vote_count": 1 + }, + { + "adult": false, + "backdrop_path": "/6kdApOG1hK8YFPfjBpGCM3BiRZr.jpg", + "genre_ids": [ + 28 + ], + "id": 883257, + "original_language": "en", + "original_title": "Bellator 268: Nemkov vs. Anglickas", + "overview": "Vadim Nemkov vs. Julius Anglickas (Light Heavyweight) Ryan Bader vs. Corey Andersion (Light Heavyweight) Benson Henderson vs. Brent Primus (Lightweight) Henry Corrales vs. Vladyslav Parubchenko (Featherweight)", + "popularity": 2.031, + "poster_path": "/hcANB303dwg7GIiXBqcouxcXASX.jpg", + "release_date": "2021-10-16", + "title": "Bellator 268: Nemkov vs. Anglickas", + "video": true, + "vote_average": 0.0, + "vote_count": 0 + } + ], + "total_pages": 1, + "total_results": 2 +} \ No newline at end of file diff --git a/spec/fixtures/starwars_collection.json b/spec/fixtures/starwars_collection.json new file mode 100644 index 000000000..3fa0da82b --- /dev/null +++ b/spec/fixtures/starwars_collection.json @@ -0,0 +1,69 @@ +{ + "adult": false, + "backdrop_path": "/4qCqAdHcNKeAHcK8tJ8wNJZa9cx.jpg", + "belongs_to_collection": { + "id": 10, + "name": "Star Wars Collection", + "poster_path": "/gq5Wi7i4SF3lo4HHkJasDV95xI9.jpg", + "backdrop_path": "/zZDkgOmFMVYpGAkR9Tkxw0CRnxX.jpg" + }, + "budget": 11000000, + "genres": [ + { + "id": 12, + "name": "Adventure" + }, + { + "id": 28, + "name": "Action" + }, + { + "id": 878, + "name": "Science Fiction" + } + ], + "homepage": "http://www.starwars.com/films/star-wars-episode-iv-a-new-hope", + "id": 11, + "imdb_id": "tt0076759", + "original_language": "en", + "original_title": "Star Wars", + "overview": "Princess Leia is captured and held hostage by the evil Imperial forces in their effort to take over the galactic Empire. Venturesome Luke Skywalker and dashing captain Han Solo team together with the loveable robot duo R2-D2 and C-3PO to rescue the beautiful princess and restore peace and justice in the Empire.", + "popularity": 103.073, + "poster_path": "/6FfCtAuVAW8XJjZ7eWeLibRLWTw.jpg", + "production_companies": [ + { + "id": 1, + "logo_path": "/o86DbpburjxrqAzEDhXZcyE8pDb.png", + "name": "Lucasfilm Ltd.", + "origin_country": "US" + }, + { + "id": 25, + "logo_path": "/qZCc1lty5FzX30aOCVRBLzaVmcp.png", + "name": "20th Century Fox", + "origin_country": "US" + } + ], + "production_countries": [ + { + "iso_3166_1": "US", + "name": "United States of America" + } + ], + "release_date": "1977-05-25", + "revenue": 775398007, + "runtime": 121, + "spoken_languages": [ + { + "english_name": "English", + "iso_639_1": "en", + "name": "English" + } + ], + "status": "Released", + "tagline": "A long time ago in a galaxy far, far away...", + "title": "Star Wars", + "video": false, + "vote_average": 8.2, + "vote_count": 19351 +} \ No newline at end of file diff --git a/spec/models/party_spec.rb b/spec/models/party_spec.rb index 7df58ea16..46628cc7d 100644 --- a/spec/models/party_spec.rb +++ b/spec/models/party_spec.rb @@ -5,4 +5,12 @@ it { should have_many :user_parties } it { should have_many(:users).through(:user_parties) } end + + before(:each) do + load_test_data + end + + it "#get_host_name" do + expect(@party1.get_host_name).to eq("Tom") + end end \ No newline at end of file diff --git a/spec/models/user_party_spec.rb b/spec/models/user_party_spec.rb index ac054f45c..f6e5c7f50 100644 --- a/spec/models/user_party_spec.rb +++ b/spec/models/user_party_spec.rb @@ -5,4 +5,12 @@ it {should belong_to :user} it {should belong_to :party} end + + before(:each) do + load_test_data + end + + it "#get_user_name" do + expect(@user_party1.get_user_name).to eq("Tom") + end end \ No newline at end of file diff --git a/spec/models/utility_spec.rb b/spec/models/utility_spec.rb new file mode 100644 index 000000000..7ab9c0be4 --- /dev/null +++ b/spec/models/utility_spec.rb @@ -0,0 +1,10 @@ +require "rails_helper" + +RSpec.describe Utility, type: :model do + describe "#runtime_in_min" do + it "can return runtime in hourse and minutes" do + data = { runtime: "126" } + expect(Utility.runtime_in_min(data)).to eq("2 hours 6 minutes") + end + end +end \ No newline at end of file diff --git a/spec/poros/movie_poros_spec.rb b/spec/poros/movie_poros_spec.rb new file mode 100644 index 000000000..b0a60f823 --- /dev/null +++ b/spec/poros/movie_poros_spec.rb @@ -0,0 +1,30 @@ +require "rails_helper" + +RSpec.describe MoviePoro do + it "exists" do + attrs = { + id: 1, + title: "test", + vote_average: 2, + runtime: 3, + genres: "gen", + overview: "simple", + cast: "alot", + results: "good", + poster_path: "somewhere" + } + + mp = MoviePoro.new(attrs) + + expect(mp).to be_a MoviePoro + expect(mp.id).to eq(1) + expect(mp.title).to eq("test") + expect(mp.vote_average).to eq(2) + expect(mp.runtime).to eq(3) + expect(mp.genres).to eq("gen") + expect(mp.overview).to eq("simple") + expect(mp.cast).to eq("alot") + expect(mp.results).to eq("good") + expect(mp.poster_path).to eq("somewhere") + end +end \ No newline at end of file diff --git a/spec/services/movie_services_spec.rb b/spec/services/movie_services_spec.rb new file mode 100644 index 000000000..6fbbc6b2f --- /dev/null +++ b/spec/services/movie_services_spec.rb @@ -0,0 +1,116 @@ +require 'rails_helper' + +describe MovieService do + context "class methods" do + context "#top_movies" do + it "returns movie data" do + json_response = File.read('spec/fixtures/top_twenty_movies.json') + stub_request(:get, "https://api.themoviedb.org/3/movie/popular?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: json_response, headers: {}) + search = MovieService.new.top_movies + expect(search).to be_a Hash + expect(search[:results]).to be_an Array + movie_data = search[:results].first + expect(movie_data).to have_key :id + expect(movie_data[:id]).to be_a(Integer) + + expect(movie_data).to have_key :poster_path + expect(movie_data[:poster_path]).to be_a(String) + end + end + + context "#search_movies" do + it "returns movie data" do + specific_movie_response = File.read('spec/fixtures/search_movie_by_id.json') + + stub_request(:get, "https://api.themoviedb.org/3/search/movie?api_key=#{Rails.application.credentials.tmdb[:key]}&query=268"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: specific_movie_response, headers: {}) + + + search = MovieService.new.search_movies(268) + expect(search).to be_a Hash + expect(search[:results]).to be_an Array + movie_data = search[:results].first + expect(movie_data).to have_key :id + expect(movie_data[:id]).to be_a(Integer) + + expect(movie_data).to have_key :poster_path + expect(movie_data[:poster_path]).to be_a(String) + end + end + + context "#movie_details" do + it "returns movie details" do + specific_movie_response = File.read('spec/fixtures/specific_movie.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: specific_movie_response, headers: {}) + + movie_data = MovieService.new.movie_details(268) + expect(movie_data).to be_a Hash + expect(movie_data).to have_key :id + expect(movie_data[:id]).to be_a(Integer) + expect(movie_data).to have_key :poster_path + expect(movie_data[:poster_path]).to be_a(String) + end + end + + context "#movie_cast" do + it "returns movie cast" do + credits_response = File.read('spec/fixtures/specific_movie_credits.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268/credits?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: credits_response, headers: {}) + + movie_data = MovieService.new.movie_cast(268) + expect(movie_data).to be_a Hash + expect(movie_data[:cast].first).to have_key :id + expect(movie_data[:cast].first[:id]).to be_a(Integer) + end + end + + context "#movie_reviews" do + it "returns movie reviews" do + reviews_response = File.read('spec/fixtures/specific_movie_reviews.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/268/reviews?api_key=#{Rails.application.credentials.tmdb[:key]}"). + with( + headers: { + 'Accept'=>'*/*', + 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent'=>'Faraday v2.7.12' + }). + to_return(status: 200, body: reviews_response, headers: {}) + + movie_data = MovieService.new.movie_reviews(268) + expect(movie_data).to be_a Hash + expect(movie_data[:results].first).to have_key :id + expect(movie_data[:results].first[:id]).to be_a(String) + end + end + end +end \ No newline at end of file From df1083f87f7aefa81cb9d24e31da8ce995a2daac Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Fri, 1 Dec 2023 09:39:42 -0700 Subject: [PATCH 18/24] Add missing link to movies in viewing party --- app/views/users/show.html.erb | 4 ++-- spec/features/users/show_spec.rb | 5 +++++ spec/models/user_spec.rb | 13 +++++++++++++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 2b4ddcb0c..8f1823743 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -9,7 +9,7 @@ <% @movies.each do |movie| %> <% if party.movie_id == movie[:id] %>
  • Movie Image: <%= image_tag "https://image.tmdb.org/t/p/w92#{movie[:poster_path]}" %>
  • -
  • Movie Title: <%= "#{movie[:title]}" %>
  • +
  • Movie Title: <%= link_to "#{movie[:title]}", "/users/#{@user.id}/movies/#{movie[:id]}" %>
  • Date and Time: <%= "Starts on #{party.date} at #{party.start_time}" %>
  • <% party.user_parties.each do |us| %> <% if us.is_host == true %> @@ -35,7 +35,7 @@ <% @movies.each do |movie| %> <% if party.movie_id == movie[:id] %>
  • Movie Image: <%= image_tag "https://image.tmdb.org/t/p/w92#{movie[:poster_path]}" %>
  • -
  • Movie Title: <%= "#{movie[:title]}" %>
  • +
  • Movie Title: <%= link_to "#{movie[:title]}", "/users/#{@user.id}/movies/#{movie[:id]}" %>
  • Date and Time: <%= "Starts on #{party.date} at #{party.start_time}" %>
  • <% party.user_parties.each do |us| %> <% if us.is_host == true %> diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index 1987ca877..515376172 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -45,6 +45,11 @@ expect(page).to have_button('Discover Movies') end + it "displays a 'Discover Movies' movie links" do + expect(page).to have_link('The Lord of the Rings: The Fellowship of the Ring') + expect(page).to have_link('Star Wars') + end + it 'displays a section that lists viewing parties' do within('section.attending-parties') do expect(page).to have_css('h2', text: 'Attending Parties') diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index be66877f0..8c9dbecb1 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -5,4 +5,17 @@ it { should have_many :user_parties } it { should have_many(:parties).through(:user_parties) } end + + describe "validations" do + it {should validate_presence_of(:name)} + it {should validate_presence_of(:email)} + it { should validate_presence_of(:password)} + it { should have_secure_password} + + it "create user with validations" do + user = User.create(name: 'Joe', email: 'joe@test.com', password: 'password123', password_confirmation: 'password123') + expect(user).to_not have_attribute(:password) + expect(user.password_digest).to_not eq('password123') + end + end end \ No newline at end of file From b6bb0b7beedd007d0725fd6919a5780ff5dc8fd6 Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Fri, 1 Dec 2023 10:06:42 -0700 Subject: [PATCH 19/24] Added check for duration and tests --- app/controllers/viewing_parties_controller.rb | 25 ++++++---- .../users/movies/viewing-party/new_spec.rb | 50 ++++++++++++++++--- 2 files changed, 58 insertions(+), 17 deletions(-) diff --git a/app/controllers/viewing_parties_controller.rb b/app/controllers/viewing_parties_controller.rb index 1d3c552ac..b9f34257b 100644 --- a/app/controllers/viewing_parties_controller.rb +++ b/app/controllers/viewing_parties_controller.rb @@ -12,18 +12,23 @@ def create @user = User.find(params[:user_id]) @users = User.where("id != #{params[:user_id]}") @movie = facade.movie_details(params[:movid_id]) - @party = @user.parties.new(movie_id: @movie[:id], movie_title: @movie[:title], duration: params[:duration], date: params[:date], start_time: params[:start_time]) - if @party.save - @user.user_parties.create!(user_id: @user.id, party_id: @party.id, is_host: true) - @users.each do |other_user| - if params[:"#{other_user.id}"].present? - other_user.user_parties.create!(party_id: @party.id) + if @movie[:runtime].to_i > params[:duration].to_i + flash[:alert] = "Error: duration cannot be less that movie runtime" + redirect_to "/users/#{@user.id}/movies/#{@movie[:id]}/viewing-party/new" + else + @party = @user.parties.new(movie_id: @movie[:id], movie_title: @movie[:title], duration: params[:duration], date: params[:date], start_time: params[:start_time]) + if @party.save + @user.user_parties.create!(user_id: @user.id, party_id: @party.id, is_host: true) + @users.each do |other_user| + if params[:"#{other_user.id}"].present? + other_user.user_parties.create!(party_id: @party.id) + end end + redirect_to user_path(@user.id) + else + flash[:alert] = "Error: something is wrong with credentials" + redirect_to "/users/#{@user.id}/movies/#{@movie[:id]}/viewing-party/new" end - redirect_to user_path(@user.id) - else - flash[:alert] = "Error: something is wrong with credentials" - redirect_to "/users/#{@user.id}/movies/#{@movie.id}/viewing-party/new" end end end \ No newline at end of file diff --git a/spec/features/users/movies/viewing-party/new_spec.rb b/spec/features/users/movies/viewing-party/new_spec.rb index 3b628616f..08d631b90 100644 --- a/spec/features/users/movies/viewing-party/new_spec.rb +++ b/spec/features/users/movies/viewing-party/new_spec.rb @@ -3,9 +3,6 @@ RSpec.describe 'New Viewing Party Page' do before(:each) do load_test_data - end - - it 'When I visit the new viewing party page it contains movie title, duration of party, when date, start time, checkboxes next to each user' do specific_movie_response = File.read('spec/fixtures/specific_movie.json') starwars_response = File.read('spec/fixtures/starwars_collection.json') lotr_response = File.read('spec/fixtures/lotr_collection.json') @@ -36,7 +33,9 @@ 'User-Agent'=>'Faraday v2.7.12' }). to_return(status: 200, body: specific_movie_response, headers: {}) + end + it 'When I visit the new viewing party page it contains movie title, duration of party, when date, start time, checkboxes next to each user' do visit "/users/#{@user1.id}/movies/268/viewing-party/new" expect(page).to have_field(:duration, with:126) expect(page).to have_field(:date) @@ -55,10 +54,47 @@ click_button 'Create Party' expect(current_path).to eq(user_path(@user1.id)) - # save_and_open_page - # expect(page).to have_content('Batman') + end + + it 'sad path for creating a party: Empty duration' do + visit "/users/#{@user1.id}/movies/268/viewing-party/new" + expect(page).to have_field(:duration, with:126) + expect(page).to have_field(:date) + expect(page).to have_field(:start_time) + expect(page).to have_button('Create Party') + expect(page).to have_content('Batman') + + expect(@user2.user_parties.count).to eq(3) + expect(@user3.user_parties.count).to eq(2) + + fill_in :duration, with: "" + fill_in :start_time, with: '10:00' + fill_in :date, with: '2023/08/01' + check "#{@user2.name} (#{@user2.email})" + check "#{@user3.name} (#{@user3.email})" + click_button 'Create Party' + + expect(current_path).to eq("/users/#{@user1.id}/movies/268/viewing-party/new") + end + + it 'sad path for creating a party: Bad duration' do + visit "/users/#{@user1.id}/movies/268/viewing-party/new" + expect(page).to have_field(:duration, with:126) + expect(page).to have_field(:date) + expect(page).to have_field(:start_time) + expect(page).to have_button('Create Party') + expect(page).to have_content('Batman') + + expect(@user2.user_parties.count).to eq(3) + expect(@user3.user_parties.count).to eq(2) + + fill_in :duration, with: "2" + fill_in :start_time, with: '10:00' + fill_in :date, with: '2023/08/01' + check "#{@user2.name} (#{@user2.email})" + check "#{@user3.name} (#{@user3.email})" + click_button 'Create Party' - # expect(@user2.user_parties.count).to eq(4) - # expect(@user3.user_parties.count).to eq(3) + expect(current_path).to eq("/users/#{@user1.id}/movies/268/viewing-party/new") end end \ No newline at end of file From 16428a3ba888476eea0df94fbddd8effa47e260e Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Fri, 1 Dec 2023 10:56:14 -0700 Subject: [PATCH 20/24] Add missing tests for sad paths --- app/controllers/users_controller.rb | 1 + spec/features/users/movies/viewing-party/new_spec.rb | 5 +---- spec/features/users/new_spec.rb | 8 ++++++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index d04f579ed..c05608522 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -8,6 +8,7 @@ def create if @user.save redirect_to user_path(@user) else + flash[:alert] = "Error: something is wrong with credentials" render :new end end diff --git a/spec/features/users/movies/viewing-party/new_spec.rb b/spec/features/users/movies/viewing-party/new_spec.rb index 08d631b90..c300f10c9 100644 --- a/spec/features/users/movies/viewing-party/new_spec.rb +++ b/spec/features/users/movies/viewing-party/new_spec.rb @@ -56,7 +56,7 @@ expect(current_path).to eq(user_path(@user1.id)) end - it 'sad path for creating a party: Empty duration' do + it 'sad path for creating a party: Bad data' do visit "/users/#{@user1.id}/movies/268/viewing-party/new" expect(page).to have_field(:duration, with:126) expect(page).to have_field(:date) @@ -67,9 +67,6 @@ expect(@user2.user_parties.count).to eq(3) expect(@user3.user_parties.count).to eq(2) - fill_in :duration, with: "" - fill_in :start_time, with: '10:00' - fill_in :date, with: '2023/08/01' check "#{@user2.name} (#{@user2.email})" check "#{@user3.name} (#{@user3.email})" click_button 'Create Party' diff --git a/spec/features/users/new_spec.rb b/spec/features/users/new_spec.rb index 16d89c415..7ebeaa6bf 100644 --- a/spec/features/users/new_spec.rb +++ b/spec/features/users/new_spec.rb @@ -22,4 +22,12 @@ user = User.find_by(email: 'john@example.com') expect(current_path).to eq("/users/#{user.id}") end + + it 'redirects user to create user page if bad data is entered' do + visit '/register' + fill_in 'Email', with: 'john@example.com' + fill_in 'Password', with: 'Sooners!2022' + click_button 'Register' + expect(current_path).to eq("/users") + end end \ No newline at end of file From 5608b3bc9ab11ffefd117db305c7220f7ae631cd Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Fri, 1 Dec 2023 14:45:55 -0600 Subject: [PATCH 21/24] add function, html and tests for invite accept extension --- app/.DS_Store | Bin 0 -> 6148 bytes app/controllers/application_controller.rb | 5 ++ app/controllers/viewing_parties_controller.rb | 13 ++++- app/models/user_party.rb | 1 + app/views/users/show.html.erb | 4 +- app/views/viewing_parties/index.html.erb | 12 ++++ config/routes.rb | 2 + ...1201181406_add_accepted_to_user_parties.rb | 5 ++ db/schema.rb | 3 +- .../application_controller_spec.rb | 19 +++++++ .../users/movies/viewing-party/index_spec.rb | 52 ++++++++++++++++++ .../users/movies/viewing-party/new_spec.rb | 23 ++++++++ spec/test_helper.rb | 4 ++ 13 files changed, 140 insertions(+), 3 deletions(-) create mode 100644 app/.DS_Store create mode 100644 app/views/viewing_parties/index.html.erb create mode 100644 db/migrate/20231201181406_add_accepted_to_user_parties.rb create mode 100644 spec/controllers/application_controller_spec.rb create mode 100644 spec/features/users/movies/viewing-party/index_spec.rb diff --git a/app/.DS_Store b/app/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..afa6b37672945dce081b47f7756a4c048ec17952 GIT binary patch literal 6148 zcmeHKOHRWu5FJC>M(w6cHb}VuNWDR*!h&@#Q2L=QN=elg*s#bRaR4@O1WtiC5@H2! z#ujpt7QqG~G!u5#AZxeSsKr}}-K2B$dj((N2}_zGZtbnI&~Il_iU|;t z(V#pMnau}pHXAfYzq8G=B6I1p>tJV+VP)QB27PV~qs(N^H>u$>L;2?|k>L#aRn=oX ze11)sW4bP9Co1?%1gd?Z0QPLQuw_w8RX`O`1wIwv^&x^Y#tw6fvUH%3BLFZ!wHWUC zGk{|vhq1%lB3fX^h5~JxU#fsA@UIjwLDEaQNXhN3mE?G@jo^Ja8}o9D5`w~Q$8y74 d@g7_ZZ4uu9V~4p#)WGyZKxEKD75G&JJ^((t)X4w< literal 0 HcmV?d00001 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 09705d12a..4bea3c211 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,7 @@ class ApplicationController < ActionController::Base + def current_user + @current_user ||= User.find(session[:user_id]) if session[:user_id] + end + + helper_method :current_user end diff --git a/app/controllers/viewing_parties_controller.rb b/app/controllers/viewing_parties_controller.rb index b9f34257b..82f2c1223 100644 --- a/app/controllers/viewing_parties_controller.rb +++ b/app/controllers/viewing_parties_controller.rb @@ -1,4 +1,9 @@ class ViewingPartiesController < ApplicationController + + def index + @user = User.find(params[:user_id]) + @user_parties = @user.user_parties + end def new facade = MovieFacade.new @user = User.find(params[:user_id]) @@ -21,7 +26,7 @@ def create @user.user_parties.create!(user_id: @user.id, party_id: @party.id, is_host: true) @users.each do |other_user| if params[:"#{other_user.id}"].present? - other_user.user_parties.create!(party_id: @party.id) + other_user.user_parties.create!(party_id: @party.id, accepted: false) end end redirect_to user_path(@user.id) @@ -31,4 +36,10 @@ def create end end end + + def accept_invite + user_party = UserParty.find_by(user_id: params[:user_id], party_id: params[:party_id]) + user_party.update(accepted: true) + redirect_to user_path(params[:user_id]) + end end \ No newline at end of file diff --git a/app/models/user_party.rb b/app/models/user_party.rb index 440ea09c2..273f2fb95 100644 --- a/app/models/user_party.rb +++ b/app/models/user_party.rb @@ -5,4 +5,5 @@ class UserParty < ApplicationRecord def get_user_name User.find(self.user_id).name end + end \ No newline at end of file diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 8f1823743..973f9e188 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -52,4 +52,6 @@ <% end %> <% end %> <% end %> -
    \ No newline at end of file +
    + +<%= link_to 'View Invites', user_viewing_parties_path(@user.id), class: 'btn btn-primary' %> \ No newline at end of file diff --git a/app/views/viewing_parties/index.html.erb b/app/views/viewing_parties/index.html.erb new file mode 100644 index 000000000..46e53c08e --- /dev/null +++ b/app/views/viewing_parties/index.html.erb @@ -0,0 +1,12 @@ +<% @user_parties.each do |user_party| %> +
    + <% party = user_party.party %> + <% if party && !user_party.accepted && current_user %> +

    Movie Title: <%= party.movie_title %>

    +

    Duration: <%= party.duration %>

    +

    Date: <%= party.date %>

    +

    Start Time: <%= party.start_time %>

    + <%= button_to 'Accept Invite', "/users/#{current_user.id}/viewing-parties/#{party.id}/accept_invite", method: :patch %> + <% end %> +
    +<% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 9a0cf2ab7..a51a9d73a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,8 +9,10 @@ resources :users, only: [:new, :create, :show] do resources :discover, only: [:index] resources :movies, only: [:index, :show] + resources :viewing_parties, only: [:index] end get "/users/:user_id/movies/:movid_id/viewing-party/new", to: "viewing_parties#new" post "/users/:user_id/movies/:movid_id/viewing-party/create", to: "viewing_parties#create" + patch "/users/:user_id/viewing-parties/:party_id/accept_invite", to: "viewing_parties#accept_invite" end diff --git a/db/migrate/20231201181406_add_accepted_to_user_parties.rb b/db/migrate/20231201181406_add_accepted_to_user_parties.rb new file mode 100644 index 000000000..b653b3be0 --- /dev/null +++ b/db/migrate/20231201181406_add_accepted_to_user_parties.rb @@ -0,0 +1,5 @@ +class AddAcceptedToUserParties < ActiveRecord::Migration[7.0] + def change + add_column :user_parties, :accepted, :boolean, default: false, null: false + end +end diff --git a/db/schema.rb b/db/schema.rb index e31e39284..5b7a7de0b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2023_11_28_001937) do +ActiveRecord::Schema[7.0].define(version: 2023_12_01_181406) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -30,6 +30,7 @@ t.bigint "party_id", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.boolean "accepted", default: false, null: false t.index ["party_id"], name: "index_user_parties_on_party_id" t.index ["user_id"], name: "index_user_parties_on_user_id" end diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb new file mode 100644 index 000000000..fa99115e0 --- /dev/null +++ b/spec/controllers/application_controller_spec.rb @@ -0,0 +1,19 @@ +require 'rails_helper' + +RSpec.describe ApplicationController, type: :controller do + before(:each) do + load_test_data + end + + describe '#current_user' do + it 'returns the current user based on the session user_id' do + session[:user_id] = @user1.id + expect(controller.current_user).to eq(@user1) + end + + it 'returns nil when there is no session user_id' do + session[:user_id] = nil + expect(controller.current_user).to be_nil + end + end +end \ No newline at end of file diff --git a/spec/features/users/movies/viewing-party/index_spec.rb b/spec/features/users/movies/viewing-party/index_spec.rb new file mode 100644 index 000000000..c645d91cb --- /dev/null +++ b/spec/features/users/movies/viewing-party/index_spec.rb @@ -0,0 +1,52 @@ +require 'rails_helper' + +RSpec.describe 'Viewing Party Index Page' do + before(:each) do + load_test_data + specific_movie_response = File.read('spec/fixtures/specific_movie.json') + starwars_response = File.read('spec/fixtures/starwars_collection.json') + lotr_response = File.read('spec/fixtures/lotr_collection.json') + + stub_request(:get, "https://api.themoviedb.org/3/movie/11?api_key=#{Rails.application.credentials.tmdb[:key]}") + .with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Faraday v2.7.12' + } + ) + .to_return(status: 200, body: starwars_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/120?api_key=#{Rails.application.credentials.tmdb[:key]}") + .with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Faraday v2.7.12' + } + ) + .to_return(status: 200, body: lotr_response, headers: {}) + + stub_request(:get, "https://api.themoviedb.org/3/movie/268?api_key=#{Rails.application.credentials.tmdb[:key]}") + .with( + headers: { + 'Accept' => '*/*', + 'Accept-Encoding' => 'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', + 'User-Agent' => 'Faraday v2.7.12' + } + ) + .to_return(status: 200, body: specific_movie_response, headers: {}) + end + + it 'sets accepted to true for a user who accepts an invite' do + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(@user2) + visit user_viewing_parties_path(@user2) + save_and_open_page + + within(first('.viewing-party')) do + click_on 'Accept Invite' + end + + expect(UserParty.where(party_id: Party.last.id, user_id: @user2.id).first.accepted).to eq(true) + end +end diff --git a/spec/features/users/movies/viewing-party/new_spec.rb b/spec/features/users/movies/viewing-party/new_spec.rb index c300f10c9..d646b1c1b 100644 --- a/spec/features/users/movies/viewing-party/new_spec.rb +++ b/spec/features/users/movies/viewing-party/new_spec.rb @@ -94,4 +94,27 @@ expect(current_path).to eq("/users/#{@user1.id}/movies/268/viewing-party/new") end + + it 'sets accepted to false for invited users when a party is created' do + visit "/users/#{@user1.id}/movies/268/viewing-party/new" + + fill_in :duration, with: 180 + fill_in :start_time, with: '10:00' + fill_in :date, with: '2023/08/01' + check "#{@user2.name} (#{@user2.email})" + check "#{@user3.name} (#{@user3.email})" + click_button 'Create Party' + + expect(UserParty.where(party_id: Party.last.id, user_id: @user2.id).first.accepted).to eq(false) + expect(UserParty.where(party_id: Party.last.id, user_id: @user3.id).first.accepted).to eq(false) + end + + it 'sets accepted to true for a user who accepts an invite' do + def accept_invite(user, party) + page.driver.submit :patch, "/users/#{user.id}/viewing-parties/#{party.id}/accept_invite", {} + end + accept_invite(@user2, Party.last) + + expect(UserParty.where(party_id: Party.last.id, user_id: @user2.id).first.accepted).to eq(true) + end end \ No newline at end of file diff --git a/spec/test_helper.rb b/spec/test_helper.rb index 858004e9d..578601079 100644 --- a/spec/test_helper.rb +++ b/spec/test_helper.rb @@ -13,4 +13,8 @@ def load_test_data @user_party5 = @user1.user_parties.create!(party_id: @party2.id) @user_party6 = @user3.user_parties.create!(party_id: @party2.id) +end + +def accept_invite(user, party) + page.driver.submit :patch, "/users/#{user.id}/viewing-parties/#{party.id}/accept_invite", {} end \ No newline at end of file From 6d98b745d0af18347448df7b8779b8adf31de735 Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Fri, 1 Dec 2023 14:46:49 -0600 Subject: [PATCH 22/24] remove save and open page --- spec/features/users/movies/viewing-party/index_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/features/users/movies/viewing-party/index_spec.rb b/spec/features/users/movies/viewing-party/index_spec.rb index c645d91cb..b89bb6133 100644 --- a/spec/features/users/movies/viewing-party/index_spec.rb +++ b/spec/features/users/movies/viewing-party/index_spec.rb @@ -41,7 +41,7 @@ it 'sets accepted to true for a user who accepts an invite' do allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(@user2) visit user_viewing_parties_path(@user2) - save_and_open_page + within(first('.viewing-party')) do click_on 'Accept Invite' From f16009dc1d3e106922ba3c68447cc39a133e3bf9 Mon Sep 17 00:00:00 2001 From: Blaine Kennedy Date: Fri, 1 Dec 2023 16:49:22 -0600 Subject: [PATCH 23/24] fix date/time --- app/views/users/show.html.erb | 8 ++++---- app/views/viewing_parties/index.html.erb | 3 +-- spec/features/users/show_spec.rb | 4 ++-- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index 973f9e188..b6c87c518 100644 --- a/app/views/users/show.html.erb +++ b/app/views/users/show.html.erb @@ -10,8 +10,8 @@ <% if party.movie_id == movie[:id] %>
  • Movie Image: <%= image_tag "https://image.tmdb.org/t/p/w92#{movie[:poster_path]}" %>
  • Movie Title: <%= link_to "#{movie[:title]}", "/users/#{@user.id}/movies/#{movie[:id]}" %>
  • -
  • Date and Time: <%= "Starts on #{party.date} at #{party.start_time}" %>
  • - <% party.user_parties.each do |us| %> +
  • Date and Time: <%= "Starts on #{party.date.strftime('%Y-%m-%d')} at #{party.start_time.strftime('%H:%M:%S')} UTC" %>
  • + <% party.user_parties.each do |us| %> <% if us.is_host == true %>
  • Hosted By: <%= "#{us.get_user_name}" %>
  • <% end %> @@ -36,8 +36,8 @@ <% if party.movie_id == movie[:id] %>
  • Movie Image: <%= image_tag "https://image.tmdb.org/t/p/w92#{movie[:poster_path]}" %>
  • Movie Title: <%= link_to "#{movie[:title]}", "/users/#{@user.id}/movies/#{movie[:id]}" %>
  • -
  • Date and Time: <%= "Starts on #{party.date} at #{party.start_time}" %>
  • - <% party.user_parties.each do |us| %> +
  • Date and Time: <%= "Starts on #{party.date.strftime('%Y-%m-%d')} at #{party.start_time.strftime('%H:%M:%S')} UTC" %>
  • + <% party.user_parties.each do |us| %> <% if us.is_host == true %>
  • Hosted By: <%= "#{us.get_user_name}" %>
  • <% end %> diff --git a/app/views/viewing_parties/index.html.erb b/app/views/viewing_parties/index.html.erb index 46e53c08e..ec4f6aa3f 100644 --- a/app/views/viewing_parties/index.html.erb +++ b/app/views/viewing_parties/index.html.erb @@ -4,8 +4,7 @@ <% if party && !user_party.accepted && current_user %>

    Movie Title: <%= party.movie_title %>

    Duration: <%= party.duration %>

    -

    Date: <%= party.date %>

    -

    Start Time: <%= party.start_time %>

    +
  • Date and Time: <%= "Starts on #{party.date.strftime('%Y-%m-%d')} at #{party.start_time.strftime('%H:%M:%S')} UTC" %>
  • <%= button_to 'Accept Invite', "/users/#{current_user.id}/viewing-parties/#{party.id}/accept_invite", method: :patch %> <% end %> diff --git a/spec/features/users/show_spec.rb b/spec/features/users/show_spec.rb index 515376172..50f9b7147 100644 --- a/spec/features/users/show_spec.rb +++ b/spec/features/users/show_spec.rb @@ -54,14 +54,14 @@ within('section.attending-parties') do expect(page).to have_css('h2', text: 'Attending Parties') expect(page).to have_content("Movie Title: The Lord of the Rings: The Fellowship of the Ring") - expect(page).to have_content("Date and Time: Starts on 2023-09-01 at 2000-01-01 11:00:00 UTC") + expect(page).to have_content("Date and Time: Starts on 2023-09-01 at 11:00:00 UTC") expect(page).to have_content("Hosted By: Jerry") expect(page).to have_content("Other users attending: Tom Bob") end within('section.hosting-parties') do expect(page).to have_css('h2', text: 'Hosting Parties') expect(page).to have_content("Movie Title: Star Wars") - expect(page).to have_content("Date and Time: Starts on 2023-08-01 at 2000-01-01 10:00:00 UTC") + expect(page).to have_content("Date and Time: Starts on 2023-08-01 at 10:00:00 UTC") expect(page).to have_content("Hosted By: Tom") expect(page).to have_content("Other users attending: Jerry Bob") end From b9543e7afd26325ae07022d54b361b91cba5477c Mon Sep 17 00:00:00 2001 From: Allan Evans Date: Fri, 1 Dec 2023 16:26:33 -0700 Subject: [PATCH 24/24] Just update to readme, no code --- README.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index d3e4d498d..0f16462ba 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,19 @@ -# Viewing Party +# Viewing Party for 2308 +Created by Blaine Kennedy and Allan Evans This is the base repo for the [Viewing Party Lite project](https://backend.turing.edu/module3/projects/viewing_party_lite) used for Turing's Backend Module 3. ### About this Project -Viewing Party Lite is an application in which users can explore movie options and create a viewing party event for themselves and other users of the application. +Viewing Party Lite is an application in which users can explore movie options and create a viewing party event for themselves and other users of the application. It uses the movie database api and several endpoints to pull the information and display it on the view. +Internally the app uses Webmock so that the tests can be run offline using fixtures and the api call is abstracted using facades so the methods can handle single responsibilities (most of the time) +There is an extension for accepting invitations for parties that was almost (or is finished by the time the project is turned in) in branch ext/feat/invite_accept. ## Setup 1. Fork and Clone the repo -2. Install gem packages: `bundle install` -3. Setup the database: `rails db:create` +2. Install gem packages: `bundle install` then `bundle update` +3. Setup the database: `rails db:{create,migrate}` ## Versions