From 04335103046b1d8a18ff24028da479a323aa3e3e Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 13:26:27 -0700 Subject: [PATCH 01/49] Initial setup --- .gitignore | 17 ++ Gemfile | 54 ++++++ Gemfile.lock | 179 ++++++++++++++++++ Rakefile | 6 + app/channels/application_cable/channel.rb | 4 + app/channels/application_cable/connection.rb | 4 + app/controllers/application_controller.rb | 2 + app/controllers/concerns/.keep | 0 app/controllers/movies_controller.rb | 5 + app/jobs/application_job.rb | 2 + app/mailers/application_mailer.rb | 4 + app/models/application_record.rb | 3 + app/models/concerns/.keep | 0 app/views/layouts/mailer.html.erb | 13 ++ app/views/layouts/mailer.text.erb | 1 + bin/bundle | 3 + bin/rails | 9 + bin/rake | 9 + bin/setup | 34 ++++ bin/spring | 17 ++ bin/update | 29 +++ config.ru | 5 + config/application.rb | 34 ++++ config/boot.rb | 3 + config/cable.yml | 9 + config/database.yml | 85 +++++++++ config/environment.rb | 5 + config/environments/development.rb | 47 +++++ config/environments/production.rb | 78 ++++++++ config/environments/test.rb | 42 ++++ .../application_controller_renderer.rb | 6 + config/initializers/backtrace_silencers.rb | 7 + config/initializers/cors.rb | 16 ++ .../initializers/filter_parameter_logging.rb | 4 + config/initializers/inflections.rb | 16 ++ config/initializers/mime_types.rb | 4 + config/initializers/new_framework_defaults.rb | 18 ++ config/initializers/wrap_parameters.rb | 14 ++ config/locales/en.yml | 23 +++ config/puma.rb | 47 +++++ config/routes.rb | 4 + config/secrets.yml | 22 +++ config/spring.rb | 6 + lib/tasks/.keep | 0 log/.keep | 0 public/robots.txt | 5 + test/controllers/.keep | 0 test/controllers/movies_controller_test.rb | 7 + test/fixtures/.keep | 0 test/fixtures/files/.keep | 0 test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/test_helper.rb | 26 +++ tmp/.keep | 0 55 files changed, 928 insertions(+) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Rakefile create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/controllers/movies_controller.rb create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100755 bin/bundle create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/setup create mode 100755 bin/spring create mode 100755 bin/update create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/application_controller_renderer.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/cors.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/new_framework_defaults.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/routes.rb create mode 100644 config/secrets.yml create mode 100644 config/spring.rb create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 public/robots.txt create mode 100644 test/controllers/.keep create mode 100644 test/controllers/movies_controller_test.rb create mode 100644 test/fixtures/.keep create mode 100644 test/fixtures/files/.keep create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..48fb168f6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +# Ignore Byebug command history file. +.byebug_history diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..3392a98e4 --- /dev/null +++ b/Gemfile @@ -0,0 +1,54 @@ +source 'https://rubygems.org' + +git_source(:github) do |repo_name| + repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") + "https://github.com/#{repo_name}.git" +end + + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '~> 5.0.2' +# Use postgresql as the database for Active Record +gem 'pg', '~> 0.18' +# Use Puma as the app server +gem 'puma', '~> 3.0' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +# gem 'jbuilder', '~> 2.5' +# Use Redis adapter to run Action Cable in production +# gem 'redis', '~> 3.0' +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible +# gem 'rack-cors' + +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug', platform: :mri +end + +group :development do + gem 'listen', '~> 3.0.5' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem 'spring-watcher-listen', '~> 2.0.0' +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +group :development do + gem 'better_errors' + gem 'binding_of_caller' + gem 'pry-rails' +end + +gem 'awesome_print' +gem 'foundation-rails' +group :test do + gem 'minitest-rails' + gem 'minitest-reporters' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..d50315933 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,179 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.0.2) + actionpack (= 5.0.2) + nio4r (>= 1.2, < 3.0) + websocket-driver (~> 0.6.1) + actionmailer (5.0.2) + actionpack (= 5.0.2) + actionview (= 5.0.2) + activejob (= 5.0.2) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.0.2) + actionview (= 5.0.2) + activesupport (= 5.0.2) + rack (~> 2.0) + rack-test (~> 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.0.2) + activesupport (= 5.0.2) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.0.2) + activesupport (= 5.0.2) + globalid (>= 0.3.6) + activemodel (5.0.2) + activesupport (= 5.0.2) + activerecord (5.0.2) + activemodel (= 5.0.2) + activesupport (= 5.0.2) + arel (~> 7.0) + activesupport (5.0.2) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + ansi (1.5.0) + arel (7.1.4) + awesome_print (1.7.0) + babel-source (5.8.35) + babel-transpiler (0.7.0) + babel-source (>= 4.0, < 6) + execjs (~> 2.0) + better_errors (2.1.1) + coderay (>= 1.0.0) + erubis (>= 2.6.6) + rack (>= 0.9.0) + binding_of_caller (0.7.2) + debug_inspector (>= 0.0.1) + builder (3.2.3) + byebug (9.0.6) + coderay (1.1.1) + concurrent-ruby (1.0.5) + debug_inspector (0.0.3) + erubis (2.7.0) + execjs (2.7.0) + ffi (1.9.18) + foundation-rails (6.3.1.0) + railties (>= 3.1.0) + sass (>= 3.3.0, < 3.5) + sprockets-es6 (>= 0.9.0) + globalid (0.4.0) + activesupport (>= 4.2.0) + i18n (0.8.1) + listen (3.0.8) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + loofah (2.0.3) + nokogiri (>= 1.5.9) + mail (2.6.5) + mime-types (>= 1.16, < 4) + method_source (0.8.2) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mini_portile2 (2.1.0) + minitest (5.10.1) + minitest-rails (3.0.0) + minitest (~> 5.8) + railties (~> 5.0) + minitest-reporters (1.1.14) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + nio4r (2.0.0) + nokogiri (1.7.1) + mini_portile2 (~> 2.1.0) + pg (0.20.0) + pry (0.10.4) + coderay (~> 1.1.0) + method_source (~> 0.8.1) + slop (~> 3.4) + pry-rails (0.3.6) + pry (>= 0.10.4) + puma (3.8.2) + rack (2.0.2) + rack-test (0.6.3) + rack (>= 1.0) + rails (5.0.2) + actioncable (= 5.0.2) + actionmailer (= 5.0.2) + actionpack (= 5.0.2) + actionview (= 5.0.2) + activejob (= 5.0.2) + activemodel (= 5.0.2) + activerecord (= 5.0.2) + activesupport (= 5.0.2) + bundler (>= 1.3.0, < 2.0) + railties (= 5.0.2) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.2) + activesupport (>= 4.2.0, < 6.0) + nokogiri (~> 1.6) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + railties (5.0.2) + actionpack (= 5.0.2) + activesupport (= 5.0.2) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (12.0.0) + rb-fsevent (0.9.8) + rb-inotify (0.9.8) + ffi (>= 0.5.0) + ruby-progressbar (1.8.1) + sass (3.4.23) + slop (3.6.0) + spring (2.0.1) + activesupport (>= 4.2) + spring-watcher-listen (2.0.1) + listen (>= 2.7, < 4.0) + spring (>= 1.2, < 3.0) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-es6 (0.9.2) + babel-source (>= 5.8.11) + babel-transpiler + sprockets (>= 3.0.0) + sprockets-rails (3.2.0) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.19.4) + thread_safe (0.3.6) + tzinfo (1.2.3) + thread_safe (~> 0.1) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) + +PLATFORMS + ruby + +DEPENDENCIES + awesome_print + better_errors + binding_of_caller + byebug + foundation-rails + listen (~> 3.0.5) + minitest-rails + minitest-reporters + pg (~> 0.18) + pry-rails + puma (~> 3.0) + rails (~> 5.0.2) + spring + spring-watcher-listen (~> 2.0.0) + tzinfo-data + +BUNDLED WITH + 1.14.6 diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..e85f91391 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative 'config/application' + +Rails.application.load_tasks diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 000000000..d67269728 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 000000000..0ff5442f4 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 000000000..4ac8823b0 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::API +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb new file mode 100644 index 000000000..a4881d046 --- /dev/null +++ b/app/controllers/movies_controller.rb @@ -0,0 +1,5 @@ +class MoviesController < ApplicationController + def index + render :json => { message: "it works!"} + end +end diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 000000000..a009ace51 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 000000000..286b2239d --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 000000000..cbd34d2e9 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 000000000..37f0bddbd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..66e9889e8 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..5badb2fde --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..d87d5f578 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 000000000..e620b4dad --- /dev/null +++ b/bin/setup @@ -0,0 +1,34 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 000000000..fb2ec2ebb --- /dev/null +++ b/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + spring = lockfile.specs.detect { |spec| spec.name == "spring" } + if spring + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version + require 'spring/binstub' + end +end diff --git a/bin/update b/bin/update new file mode 100755 index 000000000..a8e4462f2 --- /dev/null +++ b/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/config.ru b/config.ru new file mode 100644 index 000000000..f7ba0b527 --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +# This file is used by Rack-based servers to start the application. + +require_relative 'config/environment' + +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 000000000..54782d010 --- /dev/null +++ b/config/application.rb @@ -0,0 +1,34 @@ +require_relative 'boot' + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_view/railtie" +require "action_cable/engine" +# require "sprockets/railtie" +require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module VideoStoreAPI + class Application < Rails::Application + # Force new test files to be generated in the minitest-spec style + config.generators do |g| + g.test_framework :minitest, spec: true + end + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Only loads a smaller set of middleware suitable for API only apps. + # Middleware like session, flash, cookies can be added back manually. + # Skip views, helpers and assets when generating a new resource. + config.api_only = true + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 000000000..30f5120df --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..0bbde6f74 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,9 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: redis://localhost:6379/1 diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 000000000..aead51124 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,85 @@ +# PostgreSQL. Versions 9.1 and up are supported. +# +# Install the pg driver: +# gem install pg +# On OS X with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On OS X with MacPorts: +# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem 'pg' +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see rails configuration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + +development: + <<: *default + database: VideoStoreAPI_development + + # The specified database role being used to connect to postgres. + # To create additional roles in postgres see `$ createuser --help`. + # When left blank, postgres will use the default role. This is + # the same name as the operating system user that initialized the database. + #username: VideoStoreAPI + + # The password associated with the postgres role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: VideoStoreAPI_test + +# As with config/secrets.yml, you never want to store sensitive information, +# like your database password, in your source code. If your source code is +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password as a unix environment variable when you boot +# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full rundown on how to provide these environment variables in a +# production deployment. +# +# On Heroku and other platform providers, you may have a full connection URL +# available as an environment variable. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# You can use this database configuration with: +# +# production: +# url: <%= ENV['DATABASE_URL'] %> +# +production: + <<: *default + database: VideoStoreAPI_production + username: VideoStoreAPI + password: <%= ENV['VIDEOSTOREAPI_DATABASE_PASSWORD'] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 000000000..426333bb4 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 000000000..082a013ab --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,47 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + if Rails.root.join('tmp/caching-dev.txt').exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=172800' + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 000000000..49275a9d6 --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,78 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "VideoStoreAPI_#{Rails.env}" + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 000000000..30587ef6d --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => 'public, max-age=3600' + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 000000000..51639b67a --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,6 @@ +# Be sure to restart your server when you modify this file. + +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 000000000..59385cdf3 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100644 index 000000000..3b1c1b5ed --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Avoid CORS issues when API is called from the frontend app. +# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests. + +# Read more: https://github.com/cyu/rack-cors + +# Rails.application.config.middleware.insert_before 0, Rack::Cors do +# allow do +# origins 'example.com' +# +# resource '*', +# headers: :any, +# methods: [:get, :post, :put, :patch, :delete, :options, :head] +# end +# end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 000000000..4a994e1e7 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 000000000..ac033bf9d --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 000000000..dc1899682 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/new_framework_defaults.rb b/config/initializers/new_framework_defaults.rb new file mode 100644 index 000000000..d859e4bea --- /dev/null +++ b/config/initializers/new_framework_defaults.rb @@ -0,0 +1,18 @@ +# Be sure to restart your server when you modify this file. +# +# This file contains migration options to ease your Rails 5.0 upgrade. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. + +# Make Ruby 2.4 preserve the timezone of the receiver when calling `to_time`. +# Previous versions had false. +ActiveSupport.to_time_preserves_timezone = true + +# Require `belongs_to` associations by default. Previous versions had false. +Rails.application.config.active_record.belongs_to_required_by_default = true + +# Do not halt callback chains when a callback returns false. Previous versions had true. +ActiveSupport.halt_callback_chains_on_return_false = false + +# Configure SSL options to enable HSTS with subdomains. Previous versions had false. +Rails.application.config.ssl_options = { hsts: { subdomains: true } } diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 000000000..bbfc3961b --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 000000000..065395716 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,23 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 000000000..c7f311f81 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,47 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum, this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests, default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. If you use this option +# you need to make sure to reconnect any threads in the `on_worker_boot` +# block. +# +# preload_app! + +# The code in the `on_worker_boot` will be called if you are using +# clustered mode by specifying a number of `workers`. After each worker +# process is booted this block will be run, if you are using `preload_app!` +# option you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, Ruby +# cannot share connections between processes. +# +# on_worker_boot do +# ActiveRecord::Base.establish_connection if defined?(ActiveRecord) +# end + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 000000000..42b7e91e7 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,4 @@ +Rails.application.routes.draw do + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + get "/zomg", to: "movies#index" +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 000000000..abdac3545 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,22 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rails secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +development: + secret_key_base: df155bf0d4a6b976d3353d144d683fe2cc4a813adb6be6677373df15a64e12f4c269ef434ae3c1c3ecaf5232beb500d448ba39b72a9bab543ff1408ef864eec3 + +test: + secret_key_base: 236cae61252377e43ff3970928975cab4400d0cb64e4f277f26d6417de2c2528ab632bc02f75d0897867bebe4b837d0b25e1c6be93e6f07caa076e5d7d034d44 + +# Do not keep production secrets in the repository, +# instead read values from the environment. +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..c9119b40c --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/log/.keep b/log/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 000000000..3c9c7c01f --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-agent: * +# Disallow: / diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb new file mode 100644 index 000000000..67fabbcfb --- /dev/null +++ b/test/controllers/movies_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +describe MoviesController do + # it "must be a real test" do + # flunk "Need real tests" + # end +end diff --git a/test/fixtures/.keep b/test/fixtures/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 000000000..10594a324 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,26 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path("../../config/environment", __FILE__) +require "rails/test_help" +require "minitest/rails" +require "minitest/reporters" # for Colorized output + +# For colorful output! +Minitest::Reporters.use!( + Minitest::Reporters::SpecReporter.new, + ENV, + Minitest.backtrace_filter +) + + +# To add Capybara feature tests add `gem "minitest-rails-capybara"` +# to the test group in the Gemfile and uncomment the following: +# require "minitest/rails/capybara" + +# Uncomment for awesome colorful output +# require "minitest/pride" + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + # Add more helper methods to be used by all tests here... +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 000000000..e69de29bb From 541278f59f7fe53f762ec54ba75b351485b3b10e Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 13:41:56 -0700 Subject: [PATCH 02/49] Generate customer, movie and rental models --- app/models/customer.rb | 2 + app/models/movie.rb | 2 + app/models/rental.rb | 4 ++ db/migrate/20170509202653_create_movies.rb | 11 ++++ db/migrate/20170509202844_create_customers.rb | 15 ++++++ db/migrate/20170509203433_create_rentals.rb | 13 +++++ ...509203810_add_account_creditto_customer.rb | 5 ++ db/schema.rb | 54 +++++++++++++++++++ test/fixtures/customers.yml | 19 +++++++ test/fixtures/movies.yml | 11 ++++ test/fixtures/rentals.yml | 11 ++++ test/models/customer_test.rb | 9 ++++ test/models/movie_test.rb | 9 ++++ test/models/rental_test.rb | 9 ++++ 14 files changed, 174 insertions(+) create mode 100644 app/models/customer.rb create mode 100644 app/models/movie.rb create mode 100644 app/models/rental.rb create mode 100644 db/migrate/20170509202653_create_movies.rb create mode 100644 db/migrate/20170509202844_create_customers.rb create mode 100644 db/migrate/20170509203433_create_rentals.rb create mode 100644 db/migrate/20170509203810_add_account_creditto_customer.rb create mode 100644 db/schema.rb create mode 100644 test/fixtures/customers.yml create mode 100644 test/fixtures/movies.yml create mode 100644 test/fixtures/rentals.yml create mode 100644 test/models/customer_test.rb create mode 100644 test/models/movie_test.rb create mode 100644 test/models/rental_test.rb diff --git a/app/models/customer.rb b/app/models/customer.rb new file mode 100644 index 000000000..0b5277335 --- /dev/null +++ b/app/models/customer.rb @@ -0,0 +1,2 @@ +class Customer < ApplicationRecord +end diff --git a/app/models/movie.rb b/app/models/movie.rb new file mode 100644 index 000000000..dc614df15 --- /dev/null +++ b/app/models/movie.rb @@ -0,0 +1,2 @@ +class Movie < ApplicationRecord +end diff --git a/app/models/rental.rb b/app/models/rental.rb new file mode 100644 index 000000000..34d3f4df8 --- /dev/null +++ b/app/models/rental.rb @@ -0,0 +1,4 @@ +class Rental < ApplicationRecord + belongs_to :movie + belongs_to :customer +end diff --git a/db/migrate/20170509202653_create_movies.rb b/db/migrate/20170509202653_create_movies.rb new file mode 100644 index 000000000..6e5d1cad0 --- /dev/null +++ b/db/migrate/20170509202653_create_movies.rb @@ -0,0 +1,11 @@ +class CreateMovies < ActiveRecord::Migration[5.0] + def change + create_table :movies do |t| + t.string :title + t.string :overview + t.datetime :release_date + t.integer :inventory + t.timestamps + end + end +end diff --git a/db/migrate/20170509202844_create_customers.rb b/db/migrate/20170509202844_create_customers.rb new file mode 100644 index 000000000..ba079c631 --- /dev/null +++ b/db/migrate/20170509202844_create_customers.rb @@ -0,0 +1,15 @@ +class CreateCustomers < ActiveRecord::Migration[5.0] + def change + create_table :customers do |t| + t.string :name + t.datetime :registered_at + t.string :address + t.string :city + t.string :state + t.string :postal_code + t.string :phone + + t.timestamps + end + end +end diff --git a/db/migrate/20170509203433_create_rentals.rb b/db/migrate/20170509203433_create_rentals.rb new file mode 100644 index 000000000..92b53cc5c --- /dev/null +++ b/db/migrate/20170509203433_create_rentals.rb @@ -0,0 +1,13 @@ +class CreateRentals < ActiveRecord::Migration[5.0] + def change + create_table :rentals do |t| + t.references :movie, foreign_key: true + t.references :customer, foreign_key: true + t.datetime :checkout_date + t.datetime :due_date + t.datetime :checkin_date + + t.timestamps + end + end +end diff --git a/db/migrate/20170509203810_add_account_creditto_customer.rb b/db/migrate/20170509203810_add_account_creditto_customer.rb new file mode 100644 index 000000000..d4de21308 --- /dev/null +++ b/db/migrate/20170509203810_add_account_creditto_customer.rb @@ -0,0 +1,5 @@ +class AddAccountCredittoCustomer < ActiveRecord::Migration[5.0] + def change + add_column :customers, :account_credit, :float + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..9969686c8 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,54 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 20170509203810) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + + create_table "customers", force: :cascade do |t| + t.string "name" + t.datetime "registered_at" + t.string "address" + t.string "city" + t.string "state" + t.string "postal_code" + t.string "phone" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.float "account_credit" + end + + create_table "movies", force: :cascade do |t| + t.string "title" + t.string "overview" + t.datetime "release_date" + t.integer "inventory" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "rentals", force: :cascade do |t| + t.integer "movie_id" + t.integer "customer_id" + t.datetime "checkout_date" + t.datetime "due_date" + t.datetime "checkin_date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["customer_id"], name: "index_rentals_on_customer_id", using: :btree + t.index ["movie_id"], name: "index_rentals_on_movie_id", using: :btree + end + + add_foreign_key "rentals", "customers" + add_foreign_key "rentals", "movies" +end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml new file mode 100644 index 000000000..de3b0d1ac --- /dev/null +++ b/test/fixtures/customers.yml @@ -0,0 +1,19 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + registered_at: 2017-05-09 13:28:44 + address: MyString + city: MyString + state: MyString + postal_code: MyString + phone: MyString + +two: + name: MyString + registered_at: 2017-05-09 13:28:44 + address: MyString + city: MyString + state: MyString + postal_code: MyString + phone: MyString diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/movies.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml new file mode 100644 index 000000000..ba0d8d5e8 --- /dev/null +++ b/test/fixtures/rentals.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + movie: one + customer: one + checkout_date: 2017-05-09 13:34:33 + +two: + movie: two + customer: two + checkout_date: 2017-05-09 13:34:33 diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb new file mode 100644 index 000000000..5ebc5c850 --- /dev/null +++ b/test/models/customer_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Customer do + let(:customer) { Customer.new } + + it "must be valid" do + value(customer).must_be :valid? + end +end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb new file mode 100644 index 000000000..34d1d30a5 --- /dev/null +++ b/test/models/movie_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Movie do + let(:movie) { Movie.new } + + it "must be valid" do + value(movie).must_be :valid? + end +end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb new file mode 100644 index 000000000..6ea53d94f --- /dev/null +++ b/test/models/rental_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Rental do + let(:rental) { Rental.new } + + it "must be valid" do + value(rental).must_be :valid? + end +end From f28cc231a9bfd38b6d400de348736ba945061ce5 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 13:48:15 -0700 Subject: [PATCH 03/49] Add sketched-out routes to routes file --- config/routes.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/config/routes.rb b/config/routes.rb index 42b7e91e7..0c446ba44 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,4 +1,18 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get "/zomg", to: "movies#index" + + # get "/customers", to: "customers#index" + # + # get "/movies", to: "movies#index" + # + # get "/movies/:title", to: "movies#show" + # + # post "/rentals/:title/check-out", to: "rentals#create" + # [post customer_id and due_date] + # + # post "/rentals/:title/check-in", to: "rentals#update" + # [post customer_id] + # + # get "/rentals/overdue", to: "rentals#overdue" end From 25f84c6c6e23a429cef7a784f990128f01ceb26b Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Tue, 9 May 2017 13:49:06 -0700 Subject: [PATCH 04/49] added customer yml fixtures --- test/fixtures/customers.yml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index de3b0d1ac..01c9e2c8d 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -1,19 +1,19 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html -one: - name: MyString +good_data: + name: Ann D registered_at: 2017-05-09 13:28:44 - address: MyString - city: MyString - state: MyString - postal_code: MyString - phone: MyString + address: 1111 19th Ave South + city: Seattle + state: WA + postal_code: "98122" + phone: 701-306-7504 -two: - name: MyString +bad_data: + name: Ann A D registered_at: 2017-05-09 13:28:44 - address: MyString - city: MyString - state: MyString - postal_code: MyString - phone: MyString + address: 1759 19th Ave + city: Seattle + state: WA + postal_code: "98144" + phone: 701-306-7504 From 4e9d8451e20f50a3dda94b04bcdd98f541aedd33 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 14:06:33 -0700 Subject: [PATCH 05/49] Stub in tests for movie model --- test/fixtures/movies.yml | 22 +++++++++++++++++----- test/models/movie_test.rb | 29 +++++++++++++++++++++++++++-- 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index dc3ee79b5..c958b4252 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -4,8 +4,20 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} -# column: value -# -two: {} -# column: value +psycho: + title: "Psycho", + overview: "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower.", + release_date: 1960-06-16 + inventory: 8 + +bad_data1: + overview: "Nothing happens." + release_date: 1960-06-16 + inventory: 4 + +bad_data2: + overview: "Even more of nothing happens." + release_date: 1970-04-22 + +bad_data3: + title: "Whatevs." diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 34d1d30a5..2872fbc68 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -2,8 +2,33 @@ describe Movie do let(:movie) { Movie.new } + let(:psycho) {movies(:psycho)} - it "must be valid" do - value(movie).must_be :valid? + + #at least one positive and one neg case + # for each relation + # for each validation + describe "validations" do + it "must have both a title and an inventory count" do + + end + + it "must not allow a movie without a title and inventory" do + + end + + it "must have a unique combination of title and release date" do + + end + + it "must not allow a movie with a duplicate title/release date pair" do + + end + end + + describe "relations" do + it "may have zero or more rentals" do + + end end end From 253a37f328d5c7a3331b377225f437010281ef6d Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Tue, 9 May 2017 14:15:19 -0700 Subject: [PATCH 06/49] added tests to customer model --- test/fixtures/customers.yml | 25 ++++++++++++++++++++++++- test/models/customer_test.rb | 35 ++++++++++++++++++++++++++++++++--- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index 01c9e2c8d..d06e0f3ff 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -8,12 +8,35 @@ good_data: state: WA postal_code: "98122" phone: 701-306-7504 + account_credit: 100.00 + +good_data_dupe: + name: Ann D + registered_at: 2017-05-09 13:28:44 + address: 1111 19th Ave South + city: Seattle + state: WA + postal_code: "98122" + phone: 701-306-7504 + account_credit: 100.00 + bad_data: name: Ann A D registered_at: 2017-05-09 13:28:44 address: 1759 19th Ave - city: Seattle + # city: Seattle state: WA postal_code: "98144" phone: 701-306-7504 + account_credit: 100.00 + +negative_account: + name: Ann D + registered_at: 2017-05-09 13:28:44 + address: 1111 19th Ave South + city: Seattle + state: WA + postal_code: "98122" + phone: 701-306-7504 + account_credit: -100.00 diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 5ebc5c850..cc6ac3a51 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -1,9 +1,38 @@ require "test_helper" + describe Customer do - let(:customer) { Customer.new } + let(:good_data) {customers(:good_data) } + let(:good_data_dupe) {customers(:good_data) } + let(:bad_data) {customers(:bad_data) } + let(:negative_account) {customers(:negative_account) } + + + describe "validations" do + + it "must be able to create valid customer" do + good_data.must_be :valid? + end + + it 'invalid without all parameters' do + bad_data.must_equal false + bad_data.errors.messages.must_include :city + end + + it 'customer requires a unique username and address (w/ city, state, zip) combo' do + good_data.save! + good_data_dupe.save.must_equal false + good_data_dupe.errors.messages.must_include :name + good_data_dupe.errors.messages.must_include :address + good_data_dupe.errors.messages.must_include :city + good_data_dupe.errors.messages.must_include :state + good_data_dupe.errors.messages.must_include :postal_code + end + + it 'cannot create customer with negative account credit' do + negative_account.save.must_equal false + good_data_dupe.errors.messages.must_include :account_credit + end - it "must be valid" do - value(customer).must_be :valid? end end From 6ff59429c156ef0acb19689441dc50c765c284af Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 14:15:51 -0700 Subject: [PATCH 07/49] First movie validations tests --- test/fixtures/movies.yml | 16 ++-------------- test/models/movie_test.rb | 32 +++++++++++++++++++++++++++----- test/models/rental_test.rb | 2 +- 3 files changed, 30 insertions(+), 20 deletions(-) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index c958b4252..b8a6f46df 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -5,19 +5,7 @@ # below each fixture, per the syntax in the comments below # psycho: - title: "Psycho", - overview: "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower.", + title: "Psycho" + overview: "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower." release_date: 1960-06-16 inventory: 8 - -bad_data1: - overview: "Nothing happens." - release_date: 1960-06-16 - inventory: 4 - -bad_data2: - overview: "Even more of nothing happens." - release_date: 1970-04-22 - -bad_data3: - title: "Whatevs." diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 2872fbc68..8d0a50fb6 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -5,29 +5,51 @@ let(:psycho) {movies(:psycho)} + # bad_data1: + # overview: "Nothing happens." + # release_date: 1960-06-16 + # inventory: 4 + # + # bad_data2: + # overview: "Even more of nothing happens." + # release_date: 1970-04-22 + # + # bad_data3: + # title: "Whatevs." #at least one positive and one neg case # for each relation # for each validation describe "validations" do it "must have both a title and an inventory count" do - + movie.title = "North by Northwest" + movie.inventory = 8 + movie.save.must_equal true end it "must not allow a movie without a title and inventory" do + movie.overview = "Nothing happens." + movie.release_date = 1960-06-16 + movie.save.must_equal false + movie.errors.messages.must_include :title + movie.errors.messages.must_include :inventory end - it "must have a unique combination of title and release date" do + it "must have a unique combination of title and release date" do skip end - it "must not allow a movie with a duplicate title/release date pair" do - + it "must not allow a movie with a duplicate title/release date pair" do skip + + end + + it "must have an inventory greater than or equal to zero" do skip + end end describe "relations" do - it "may have zero or more rentals" do + it "may have zero or more rentals" do skip end end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6ea53d94f..a5d5d15e7 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -3,7 +3,7 @@ describe Rental do let(:rental) { Rental.new } - it "must be valid" do + it "must be valid" do skip value(rental).must_be :valid? end end From 2c6ea17515db708ee489472dc5d586a0c33a8905 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 14:16:54 -0700 Subject: [PATCH 08/49] Add presence validations for title and inventory --- app/models/movie.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/movie.rb b/app/models/movie.rb index dc614df15..29401b57f 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,2 +1,4 @@ class Movie < ApplicationRecord + validates :title, presence: true + validates :inventory, presence: true end From 3f7ea24bc1ca29197f5eb09fbcc27922ba20722f Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Tue, 9 May 2017 14:26:46 -0700 Subject: [PATCH 09/49] customer model test --- test/models/customer_test.rb | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index cc6ac3a51..2f0368ee7 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -11,12 +11,23 @@ describe "validations" do it "must be able to create valid customer" do - good_data.must_be :valid? + good_data.save.must_equal true end + it "must be able to create valid customer and return corresponding data" do + good_data.save + good_data.name.must_equal "Ann D" + end + + # it 'invalid without all parameters' do + # bad_data.must_equal false + # bad_data.errors.messages.must_include :city + # end + it 'invalid without all parameters' do - bad_data.must_equal false - bad_data.errors.messages.must_include :city + customer_missing_name = good_data.save + customer_missing_name.name = nil + customer_missing_name.save.must_equal false end it 'customer requires a unique username and address (w/ city, state, zip) combo' do @@ -31,7 +42,7 @@ it 'cannot create customer with negative account credit' do negative_account.save.must_equal false - good_data_dupe.errors.messages.must_include :account_credit + negative_account.errors.messages.must_include :account_credit end end From 73f1289191e1f910a2e042878a0cf45774823137 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 14:34:19 -0700 Subject: [PATCH 10/49] Add tests and validations for uniqueness --- app/models/movie.rb | 2 ++ test/models/movie_test.rb | 41 +++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 19 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 29401b57f..3217883a9 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,4 +1,6 @@ class Movie < ApplicationRecord validates :title, presence: true + validates_uniqueness_of :title, scope: :release_date validates :inventory, presence: true + validates :release_date, presence: true end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 8d0a50fb6..70bdbdb5b 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -4,43 +4,46 @@ let(:movie) { Movie.new } let(:psycho) {movies(:psycho)} - - # bad_data1: - # overview: "Nothing happens." - # release_date: 1960-06-16 - # inventory: 4 - # - # bad_data2: - # overview: "Even more of nothing happens." - # release_date: 1970-04-22 - # - # bad_data3: - # title: "Whatevs." #at least one positive and one neg case # for each relation # for each validation describe "validations" do - it "must have both a title and an inventory count" do + it "must have a title, release date, and inventory count" do movie.title = "North by Northwest" movie.inventory = 8 + movie.release_date = "1959-07-17" movie.save.must_equal true end - it "must not allow a movie without a title and inventory" do + it "must not allow a movie without a title, release date and inventory" do movie.overview = "Nothing happens." - movie.release_date = 1960-06-16 movie.save.must_equal false movie.errors.messages.must_include :title movie.errors.messages.must_include :inventory - + movie.errors.messages.must_include :release_date end - it "must have a unique combination of title and release date" do skip - + it "must not allow just a title but no inventory or release date" do + movie.title = "Whatevs" + movie.save.must_equal false + movie.errors.messages.must_include :inventory + movie.errors.messages.must_include :release_date end - it "must not allow a movie with a duplicate title/release date pair" do skip + it "must permit a unique combination of title and release date" do + movie.title = "Psycho" + movie.overview = "The animated children's version of the Hitchcock classic" + movie.release_date = "2015-09-01" + movie.inventory = 3 + movie.save.must_equal true + end + it "must not allow a movie with a duplicate title/release date pair" do + movie.title = psycho.title + movie.release_date = psycho.release_date + movie.inventory = 1 + movie.save.must_equal false + movie.errors.messages.must_include :title end it "must have an inventory greater than or equal to zero" do skip From b485b7498f2560ff42e8cf65e49aa8cdea5eb79d Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 15:09:03 -0700 Subject: [PATCH 11/49] Add inventory tests and validations for movie --- app/models/movie.rb | 4 +++- test/fixtures/rentals.yml | 4 ++-- test/models/movie_test.rb | 16 ++++++++++++++-- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 3217883a9..3409bbdfa 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,6 +1,8 @@ class Movie < ApplicationRecord validates :title, presence: true validates_uniqueness_of :title, scope: :release_date - validates :inventory, presence: true + validates :inventory, presence: true, numericality: { only_integer: true, greater_than_or_equal_to: 0} validates :release_date, presence: true + + has_many :rentals end diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index ba0d8d5e8..941e8385e 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -1,11 +1,11 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - movie: one + movie: psycho customer: one checkout_date: 2017-05-09 13:34:33 two: - movie: two + movie: psycho customer: two checkout_date: 2017-05-09 13:34:33 diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 70bdbdb5b..25b6787b9 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -31,7 +31,7 @@ end it "must permit a unique combination of title and release date" do - movie.title = "Psycho" + movie.title = psycho.title movie.overview = "The animated children's version of the Hitchcock classic" movie.release_date = "2015-09-01" movie.inventory = 3 @@ -46,8 +46,20 @@ movie.errors.messages.must_include :title end - it "must have an inventory greater than or equal to zero" do skip + it "must have an inventory that is an integer" do + movie.title = "North by Northwest" + movie.inventory = "cheezits" + movie.release_date = "1959-07-17" + movie.save.must_equal false + movie.errors.messages.must_include :inventory + end + it "must have an inventory greater than or equal to zero" do + movie.title = "North by Northwest" + movie.inventory = -7 + movie.release_date = "1959-07-17" + movie.save.must_equal false + movie.errors.messages.must_include :inventory end end From a4b74494b67fcba2145ca38405525c501d304ae3 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 15:13:02 -0700 Subject: [PATCH 12/49] Add test for relation of movie to rental --- test/models/movie_test.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 25b6787b9..3db7ed87e 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -2,7 +2,9 @@ describe Movie do let(:movie) { Movie.new } - let(:psycho) {movies(:psycho)} + let(:psycho) { movies(:psycho) } + let(:sample_rental) { rentals(:one) } + let(:sample_customer) { customers(:one) } #at least one positive and one neg case # for each relation @@ -64,8 +66,9 @@ end describe "relations" do - it "may have zero or more rentals" do skip - + it "may have zero or more rentals" do + psycho.rentals.must_include sample_rental end + end end From e9fd68422c181183fecc79cff1388f645791a87c Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Tue, 9 May 2017 15:24:57 -0700 Subject: [PATCH 13/49] all model test validations passed thus far --- app/models/customer.rb | 15 +++++++++++++++ app/models/movie.rb | 1 + test/fixtures/customers.yml | 18 ++++++++++++++---- test/models/customer_test.rb | 32 +++++++++++++++----------------- 4 files changed, 45 insertions(+), 21 deletions(-) diff --git a/app/models/customer.rb b/app/models/customer.rb index 0b5277335..b7c8809e2 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,2 +1,17 @@ class Customer < ApplicationRecord + + # has_many :movies + + validates :name, presence: true + validates :address, presence: true + validates :city, presence: true + validates :state, presence: true + validates :postal_code, presence: true + validates :phone, presence: true + validates :account_credit, presence: true, numericality: { greater_than_or_equal_to: 0 } + + + + validates :name, uniqueness: { scope: [:address, :city, :state, :postal_code, :phone] } + end diff --git a/app/models/movie.rb b/app/models/movie.rb index dc614df15..759a62a7f 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,2 +1,3 @@ class Movie < ApplicationRecord + end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index d06e0f3ff..4595604df 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -1,7 +1,7 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html good_data: - name: Ann D + name: John registered_at: 2017-05-09 13:28:44 address: 1111 19th Ave South city: Seattle @@ -11,7 +11,17 @@ good_data: account_credit: 100.00 good_data_dupe: - name: Ann D + name: John + registered_at: 2017-05-09 13:28:44 + address: 1111 19th Ave South + city: Seattle + state: WA + postal_code: "98122" + phone: 701-306-7504 + account_credit: 100.00 + +good_data_unique: + name: Amy registered_at: 2017-05-09 13:28:44 address: 1111 19th Ave South city: Seattle @@ -22,7 +32,7 @@ good_data_dupe: bad_data: - name: Ann A D + name: Bob registered_at: 2017-05-09 13:28:44 address: 1759 19th Ave # city: Seattle @@ -32,7 +42,7 @@ bad_data: account_credit: 100.00 negative_account: - name: Ann D + name: Ann registered_at: 2017-05-09 13:28:44 address: 1111 19th Ave South city: Seattle diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 2f0368ee7..2f5fc34a7 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -3,7 +3,8 @@ describe Customer do let(:good_data) {customers(:good_data) } - let(:good_data_dupe) {customers(:good_data) } + let(:good_data_dupe) {customers(:good_data_dupe) } + let(:good_data_unique) {customers(:good_data_unique) } let(:bad_data) {customers(:bad_data) } let(:negative_account) {customers(:negative_account) } @@ -11,39 +12,36 @@ describe "validations" do it "must be able to create valid customer" do - good_data.save.must_equal true + # Customer.new(new_customer).save.must_equal true + good_data_unique.save!.must_equal true end it "must be able to create valid customer and return corresponding data" do good_data.save - good_data.name.must_equal "Ann D" + good_data.name.must_equal "John" end - # it 'invalid without all parameters' do - # bad_data.must_equal false - # bad_data.errors.messages.must_include :city - # end - it 'invalid without all parameters' do - customer_missing_name = good_data.save - customer_missing_name.name = nil - customer_missing_name.save.must_equal false + bad_data.save.must_equal false + bad_data.errors.messages.must_include :city end + # it 'invalid without all parameters' do + # customer_missing_name = good_data + # customer_missing_name[:name].must_be nil + # # customer_missing_name.save.must_equal false + # end + it 'customer requires a unique username and address (w/ city, state, zip) combo' do - good_data.save! + good_data.save good_data_dupe.save.must_equal false good_data_dupe.errors.messages.must_include :name - good_data_dupe.errors.messages.must_include :address - good_data_dupe.errors.messages.must_include :city - good_data_dupe.errors.messages.must_include :state - good_data_dupe.errors.messages.must_include :postal_code + end it 'cannot create customer with negative account credit' do negative_account.save.must_equal false negative_account.errors.messages.must_include :account_credit end - end end From e7482be5455da4e1b1902bd65b8b106544d100ba Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 15:30:07 -0700 Subject: [PATCH 14/49] Stub in rental model tests --- test/models/rental_test.rb | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index a5d5d15e7..855a4c43b 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -3,7 +3,27 @@ describe Rental do let(:rental) { Rental.new } - it "must be valid" do skip - value(rental).must_be :valid? + it "can be created with an associated movie and customer" do skip + + end + + it "cannot be created without a movie" do + + end + + it "also cannot be created without a customer" do + + end + + it "should be assigned today's date as default for checkout_date" do + + end + + it "should be assigned a default due date of two weeks from today" do + + end + + it "cannot be created without a due date or checkout date" do + end end From 8c3bfc28355bb3054cbd57725303fb8610534da8 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 15:40:37 -0700 Subject: [PATCH 15/49] Add test to require associated movie for rental --- test/models/rental_test.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 855a4c43b..1d1644198 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -2,13 +2,19 @@ describe Rental do let(:rental) { Rental.new } + let(:sample_customer) {customers(:good_data)} + let(:sample_movie) {movies(:psycho)} it "can be created with an associated movie and customer" do skip end it "cannot be created without a movie" do - + rental.customer_id = sample_customer.id + rental.checkout_date = Date.current + rental.due_date = Date.current + rental.save.must_equal false + rental.errors.messages.must_include :movie end it "also cannot be created without a customer" do @@ -24,6 +30,6 @@ end it "cannot be created without a due date or checkout date" do - + end end From 7daf8f73367b8838ac39c57c13db9780630e5de9 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 16:08:49 -0700 Subject: [PATCH 16/49] Add chronic gem and defaults for rental model --- Gemfile | 2 ++ Gemfile.lock | 2 ++ app/models/rental.rb | 6 ++++++ test/models/rental_test.rb | 5 ++++- 4 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 3392a98e4..e79223552 100644 --- a/Gemfile +++ b/Gemfile @@ -48,6 +48,8 @@ end gem 'awesome_print' gem 'foundation-rails' +gem 'chronic' + group :test do gem 'minitest-rails' gem 'minitest-reporters' diff --git a/Gemfile.lock b/Gemfile.lock index d50315933..eaee83688 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -53,6 +53,7 @@ GEM debug_inspector (>= 0.0.1) builder (3.2.3) byebug (9.0.6) + chronic (0.10.2) coderay (1.1.1) concurrent-ruby (1.0.5) debug_inspector (0.0.3) @@ -163,6 +164,7 @@ DEPENDENCIES better_errors binding_of_caller byebug + chronic foundation-rails listen (~> 3.0.5) minitest-rails diff --git a/app/models/rental.rb b/app/models/rental.rb index 34d3f4df8..f81fd8642 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,4 +1,10 @@ class Rental < ApplicationRecord belongs_to :movie belongs_to :customer + after_initialize :set_defaults + + def set_defaults + self.checkout_date ||= Date.today + self.due_date ||= Chronic.parse('two weeks from today') + end end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 1d1644198..9d7c522b5 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -22,7 +22,10 @@ end it "should be assigned today's date as default for checkout_date" do - + rental.customer_id = sample_customer.id + rental.movie_id = sample_movie.id + rental.save.must_equal true + rental.checkout_date.must_equal Date.today end it "should be assigned a default due date of two weeks from today" do From e9ef964bfc4e52f0c0d85e6190dc7d083ee1a5b6 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Tue, 9 May 2017 16:09:36 -0700 Subject: [PATCH 17/49] added rental model tests --- test/models/rental_test.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 855a4c43b..ef53af204 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -3,27 +3,32 @@ describe Rental do let(:rental) { Rental.new } - it "can be created with an associated movie and customer" do skip + it "can be created with an associated movie and customer" do + rental.movie = Movie.first + rental.customer = Customer.last + rental.save.must_equal true end it "cannot be created without a movie" do - end it "also cannot be created without a customer" do + rental.movie = Movie.first + rental.customer = nil + rental.save.must_equal false end it "should be assigned today's date as default for checkout_date" do - end it "should be assigned a default due date of two weeks from today" do - + rental.movie = Movie.first + rental.customer = Customer.last + rental.due_date.must_be Chronic.parse('two weeks from today') end it "cannot be created without a due date or checkout date" do - end end From 95c9159d0286738712abf45166014bcd0bbc6445 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 16:30:27 -0700 Subject: [PATCH 18/49] Generate rentals and customers controllers --- .DS_Store | Bin 0 -> 6148 bytes app/controllers/customers_controller.rb | 2 ++ app/controllers/rentals_controller.rb | 2 ++ test/controllers/customers_controller_test.rb | 7 +++++++ test/controllers/rentals_controller_test.rb | 7 +++++++ 5 files changed, 18 insertions(+) create mode 100644 .DS_Store create mode 100644 app/controllers/customers_controller.rb create mode 100644 app/controllers/rentals_controller.rb create mode 100644 test/controllers/customers_controller_test.rb create mode 100644 test/controllers/rentals_controller_test.rb diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..ca5d0e6e71945129431efcf086d0e96e397046d8 GIT binary patch literal 6148 zcmeH~F^f4mh3n7#7gpu zObo#Gk7);t0M>LTwjO3?%m>_Y#trxB_H+5ZUN2sxtvcW-eZ*`(w*@I61*Cu!kOER* zK?>wCzTPb8ne-@9Kng5F0slS}y0a!*XM8#sVgw)umczJ?S%NHHAZxO9vO=?*9xPie z#t^SZJ6ZC&nrxlD9hSp~<(h|QedXQN6$w;|Bv*)=KooXQYjz> z{+R+c98QNlUn Date: Tue, 9 May 2017 16:30:58 -0700 Subject: [PATCH 19/49] Uncomment first routes --- config/routes.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 0c446ba44..1c35b4ac4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,10 +1,9 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html - get "/zomg", to: "movies#index" - # get "/customers", to: "customers#index" - # - # get "/movies", to: "movies#index" + get "/customers", to: "customers#index" + + get "/movies", to: "movies#index" # # get "/movies/:title", to: "movies#show" # From f23cd927de64ccc1374582b5e0bd5cf26f60ccd2 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Tue, 9 May 2017 16:55:56 -0700 Subject: [PATCH 20/49] added movie index controller method and tests --- app/controllers/movies_controller.rb | 3 +- test/controllers/movies_controller_test.rb | 40 ++++++++++++++++++++-- test/models/rental_test.rb | 5 +-- 3 files changed, 40 insertions(+), 8 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index a4881d046..b3dc2ef8d 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -1,5 +1,6 @@ class MoviesController < ApplicationController def index - render :json => { message: "it works!"} + movies = Movie.all + render json: movies.as_json(only: [:title, :release_date]), status: :ok end end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 67fabbcfb..b805b7c68 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -1,7 +1,41 @@ require "test_helper" describe MoviesController do - # it "must be a real test" do - # flunk "Need real tests" - # end + + KEYS = %w(release_date title) #if we loop through this, we can see whether the keys and values work/exist + + describe 'index' do + it "is a real wokring route" do + get movies_url + must_respond_with :success + end + + it "returns json" do + get movies_url + response.header['Content-Type'].must_include 'json' + end + + it "returns an array" do + get movies_url + + body = JSON.parse(response.body) + body.must_be_kind_of Array + end + + it "returns all fo the Movies" do + get movies_url + + body = JSON.parse(response.body) + body.length.must_equal Movie.count + end + + it "returns movies with the required fields" do + get movies_url + body = JSON.parse(response.body) + body.each do |movie| + movie.keys.sort.must_equal KEYS + end + end + end + end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 3c6acc3e7..9a500e632 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -39,10 +39,7 @@ it "should be assigned a default due date of two weeks from today" do rental.movie = Movie.first rental.customer = Customer.last - rental.due_date.must_be Chronic.parse('two weeks from today') + rental.due_date.must_equal Chronic.parse('two weeks from today') end - it "cannot be created without a due date or checkout date" do - - end end From 5244c5991079725eb578d28d638def1647359729 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Tue, 9 May 2017 17:01:46 -0700 Subject: [PATCH 21/49] Add tests and controller action for customer index --- app/controllers/customers_controller.rb | 6 ++++ app/models/customer.rb | 5 +++ app/models/rental.rb | 1 + test/controllers/customers_controller_test.rb | 36 ++++++++++++++++--- 4 files changed, 44 insertions(+), 4 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index ca3b6e024..afe71961b 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -1,2 +1,8 @@ class CustomersController < ApplicationController + + def index + customers = Customer.all + render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]) + # need to eventually return movies_checked_out_count + end end diff --git a/app/models/customer.rb b/app/models/customer.rb index b7c8809e2..8f9095d52 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,4 +1,5 @@ class Customer < ApplicationRecord + # attr_reader :movies_checked_out_count # has_many :movies @@ -14,4 +15,8 @@ class Customer < ApplicationRecord validates :name, uniqueness: { scope: [:address, :city, :state, :postal_code, :phone] } + # def movies_checked_out + # @movies_checked_out_count = 0 + # end + end diff --git a/app/models/rental.rb b/app/models/rental.rb index f81fd8642..67802278e 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -7,4 +7,5 @@ def set_defaults self.checkout_date ||= Date.today self.due_date ||= Chronic.parse('two weeks from today') end + end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 5e123f6cd..622831009 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -1,7 +1,35 @@ require "test_helper" -describe CustomersController do - # it "must be a real test" do - # flunk "Need real tests" - # end +describe "CustomersController" do +KEYS = %w(id name phone postal_code registered_at) +# need to eventually include movies_checked_out_count + + describe "index" do + before do + get customers_url + end + + it "is an actual route" do + must_respond_with :success + end + + it "returns json" do + response.header['Content-Type'].must_include 'json' + end + + it "returns an array of all the customers" do + body = JSON.parse(response.body) + body.must_be_kind_of Array + body.length.must_equal Customer.count + end + + it "returns customers with exactly the required fields" do + body = JSON.parse(response.body) + body.each do |customer| + customer.keys.sort.must_equal KEYS + end + + end + + end end From 2641f41ac60dd81773ad6ae73985ddc4c6b37343 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 10:37:43 -0700 Subject: [PATCH 22/49] Add custom method to customers and return value in json for customer index --- app/controllers/customers_controller.rb | 4 ++-- app/models/customer.rb | 7 +++---- config/routes.rb | 2 +- test/controllers/customers_controller_test.rb | 2 +- 4 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index afe71961b..2a942fdbb 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -2,7 +2,7 @@ class CustomersController < ApplicationController def index customers = Customer.all - render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]) - # need to eventually return movies_checked_out_count + render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone], + methods: :movies_checked_out_count), status: :ok end end diff --git a/app/models/customer.rb b/app/models/customer.rb index 8f9095d52..14ed49ae5 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,5 +1,4 @@ class Customer < ApplicationRecord - # attr_reader :movies_checked_out_count # has_many :movies @@ -15,8 +14,8 @@ class Customer < ApplicationRecord validates :name, uniqueness: { scope: [:address, :city, :state, :postal_code, :phone] } - # def movies_checked_out - # @movies_checked_out_count = 0 - # end + def movies_checked_out_count + return 0 + end end diff --git a/config/routes.rb b/config/routes.rb index 1c35b4ac4..f351802f9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,6 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html - + get "/customers", to: "customers#index" get "/movies", to: "movies#index" diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 622831009..8ce716e7b 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -1,7 +1,7 @@ require "test_helper" describe "CustomersController" do -KEYS = %w(id name phone postal_code registered_at) +KEYS = %w(id movies_checked_out_count name phone postal_code registered_at) # need to eventually include movies_checked_out_count describe "index" do From 0df9bad64b979da2bab366c8ff950c2195941c96 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 10:41:47 -0700 Subject: [PATCH 23/49] Rename constant in tests to avoid conflict --- test/controllers/customers_controller_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 8ce716e7b..68a5e220c 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -1,7 +1,7 @@ require "test_helper" describe "CustomersController" do -KEYS = %w(id movies_checked_out_count name phone postal_code registered_at) +CUSTOMER_KEYS = %w(id movies_checked_out_count name phone postal_code registered_at) # need to eventually include movies_checked_out_count describe "index" do @@ -26,7 +26,7 @@ it "returns customers with exactly the required fields" do body = JSON.parse(response.body) body.each do |customer| - customer.keys.sort.must_equal KEYS + customer.keys.sort.must_equal CUSTOMER_KEYS end end From cc59455957150f9fa1aa0fc76963dda261640e59 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Wed, 10 May 2017 10:55:20 -0700 Subject: [PATCH 24/49] added test stubs for checkout method --- config/routes.rb | 2 +- test/controllers/movies_controller_test.rb | 30 +++++++++++++++++++-- test/controllers/rentals_controller_test.rb | 26 +++++++++++++++--- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 1c35b4ac4..34ec24dfc 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,7 +7,7 @@ # # get "/movies/:title", to: "movies#show" # - # post "/rentals/:title/check-out", to: "rentals#create" + post "/rentals/:title/check-out", to: "rentals#create" # [post customer_id and due_date] # # post "/rentals/:title/check-in", to: "rentals#update" diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index b805b7c68..592775b20 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -2,7 +2,7 @@ describe MoviesController do - KEYS = %w(release_date title) #if we loop through this, we can see whether the keys and values work/exist + MOVIE_KEYS = %w(release_date title) #if we loop through this, we can see whether the keys and values work/exist describe 'index' do it "is a real wokring route" do @@ -33,9 +33,35 @@ get movies_url body = JSON.parse(response.body) body.each do |movie| - movie.keys.sort.must_equal KEYS + movie.keys.sort.must_equal MOVIE_KEYS end end end + # describe 'show' do + # it "can get a movie" do + # get movie_path(Movie.all.last.id) + # must_respond_with :success + # end + # + # it "returns JSON when movie not found" do + # get movie_path(Movie.all.last.id+1) + # must_respond_with :not_found + # + # body = JSON.parse(response.body) + # body.must_equal "not found" => true + # end + # + # it "returns the right movie when id" do + # get movie_path(Movie.all.first.id) + # + # body = JSON.parse(response.body) + # + # MOVIE_KEYS.each do |key| + # body[key].must_equal Movie.all.first[key] + # end + # end + # + # end + end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index f0227216c..5d2c65e3b 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -1,7 +1,27 @@ require "test_helper" describe RentalsController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe "Create (checkout)" do + + it "given valid customer id and movie id, can checkout movie" do + end + + it "given invalide customer_id, cannot checkout movie" do + end + + it "given invalide movie_id, cannot checkout movie" do + end + + it "can checkout a movie with enough inventory" do + end + + it "cannot checkout movie with no inventory" do + end + + it "returns a due_date that is 2 weeks from the checkout date" do + + end + + + end end From eab2a5e5243bbd4942ed64a63fa2281f0069bb1e Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 10:58:09 -0700 Subject: [PATCH 25/49] First test movie show --- config/routes.rb | 4 +-- test/controllers/movies_controller_test.rb | 29 ++++++++++++++++++++-- test/fixtures/movies.yml | 7 ++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index f351802f9..cae04193b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,11 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html - + get "/customers", to: "customers#index" get "/movies", to: "movies#index" # - # get "/movies/:title", to: "movies#show" + get "/movies/:title", to: "movies#show", as: "movie" # # post "/rentals/:title/check-out", to: "rentals#create" # [post customer_id and due_date] diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index b805b7c68..1d91f2a6a 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -2,7 +2,8 @@ describe MoviesController do - KEYS = %w(release_date title) #if we loop through this, we can see whether the keys and values work/exist + MOVIE_INDEX_KEYS = %w(release_date title) #if we loop through this, we can see whether the keys and values work/exist + MOVIE_SHOW_KEYS = %w(available_inventory inventory overview release_date title) describe 'index' do it "is a real wokring route" do @@ -33,9 +34,33 @@ get movies_url body = JSON.parse(response.body) body.each do |movie| - movie.keys.sort.must_equal KEYS + movie.keys.sort.must_equal MOVIE_INDEX_KEYS end end end + describe "show" do + let(:arabia) { movies(:arabia) } + + before do + get movie_path(arabia.title) + end + + it "should find a movie given a title" do + must_respond_with :success + + body = JSON.parse(response.body) + body.must_be_instance_of Hash + body.keys.sort.must_equal MOVIE_SHOW_KEYS + end + + it "should return a movie with the right information" do skip + + end + + it "should return not found if the movie is not found" do skip + + end + end + end diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index b8a6f46df..5e197f077 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -9,3 +9,10 @@ psycho: overview: "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower." release_date: 1960-06-16 inventory: 8 + + +arabia: + title: "Lawrence of Arabia" + overview: "Lawrence of Arabia is the classic film from David Lean starring Peter O’Toole and based on the autobiography from Thomas Edward Lawrence who during the first World War was on assignment by the British Empire in Arabia. The film would become a cult classic and is known today as a masterpiece." + release_date: 1962-12-10 + inventory: 6 From 4a16b11ee213cb2cff581266675e67ba132a0a3a Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 12:34:48 -0700 Subject: [PATCH 26/49] Additional tests and action for movie show --- app/controllers/movies_controller.rb | 13 +++++++++++ app/models/movie.rb | 4 ++++ test/controllers/movies_controller_test.rb | 27 +++++++++++++--------- 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index b3dc2ef8d..a442015e0 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -3,4 +3,17 @@ def index movies = Movie.all render json: movies.as_json(only: [:title, :release_date]), status: :ok end + + def show + # this might be better if titles can be duplicate + # returns an array of instances rather than an instance + # movie = Movie.where({title: params[:title]}) + + movie = Movie.find_by(title: params[:title]) + + if movie + render json: movie.as_json(except: [:id, :updated_at, :created_at], + methods: :available_inventory), status: :ok + end + end end diff --git a/app/models/movie.rb b/app/models/movie.rb index 37e0a2561..21032487b 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -6,4 +6,8 @@ class Movie < ApplicationRecord has_many :rentals + def available_inventory + return 0 + end + end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 1d91f2a6a..76790248e 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -6,32 +6,29 @@ MOVIE_SHOW_KEYS = %w(available_inventory inventory overview release_date title) describe 'index' do - it "is a real wokring route" do + before do get movies_url + end + + it "is a real working route" do must_respond_with :success end it "returns json" do - get movies_url response.header['Content-Type'].must_include 'json' end it "returns an array" do - get movies_url - body = JSON.parse(response.body) body.must_be_kind_of Array end - it "returns all fo the Movies" do - get movies_url - + it "returns all of the movies" do body = JSON.parse(response.body) body.length.must_equal Movie.count end it "returns movies with the required fields" do - get movies_url body = JSON.parse(response.body) body.each do |movie| movie.keys.sort.must_equal MOVIE_INDEX_KEYS @@ -54,12 +51,20 @@ body.keys.sort.must_equal MOVIE_SHOW_KEYS end - it "should return a movie with the right information" do skip + it "should return a movie with the right information" do + body = JSON.parse(response.body) + MOVIE_SHOW_KEYS.each do |key| + next if key == "available_inventory" + body[key].must_equal arabia[key] + end end - it "should return not found if the movie is not found" do skip - + it "should return status not found if the movie is not found" do skip + get movie_path("xqrt99") + must_respond_with :not_found + body = JSON.parse(response.body) + body.must_equal {} end end From a8c2d9c911daafc1658f18bb35a3cf418e45e8d7 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 12:43:34 -0700 Subject: [PATCH 27/49] Add negative test for movie show --- app/controllers/movies_controller.rb | 2 ++ test/controllers/movies_controller_test.rb | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index a442015e0..19feec216 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -14,6 +14,8 @@ def show if movie render json: movie.as_json(except: [:id, :updated_at, :created_at], methods: :available_inventory), status: :ok + else + render json: { nothing: true }, status: :not_found end end end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 76790248e..3a16cea6e 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -60,11 +60,11 @@ end end - it "should return status not found if the movie is not found" do skip + it "should return status not found if the movie is not found" do get movie_path("xqrt99") must_respond_with :not_found body = JSON.parse(response.body) - body.must_equal {} + body.must_equal "nothing" => true end end From 94d9e28a0cba67a32772eae416c94c758b1ef67e Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 12:45:49 -0700 Subject: [PATCH 28/49] Complete movie show tests --- test/controllers/movies_controller_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 3a16cea6e..6660216cd 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -55,7 +55,7 @@ body = JSON.parse(response.body) MOVIE_SHOW_KEYS.each do |key| - next if key == "available_inventory" + next if key == "available_inventory" body[key].must_equal arabia[key] end end From a8d152b8c1240d215f940174ee051ac2d24495c0 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 13:22:52 -0700 Subject: [PATCH 29/49] Stub in tests for checkin --- config/routes.rb | 2 +- test/controllers/rentals_controller_test.rb | 22 +++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index cae04193b..aadbabced 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,7 +10,7 @@ # post "/rentals/:title/check-out", to: "rentals#create" # [post customer_id and due_date] # - # post "/rentals/:title/check-in", to: "rentals#update" + post "/rentals/:title/check-in", to: "rentals#update", as: "checkin" # [post customer_id] # # get "/rentals/overdue", to: "rentals#overdue" diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index f0227216c..1278959c7 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -4,4 +4,26 @@ # it "must be a real test" do # flunk "Need real tests" # end + + describe "check_in" do + it "succeeds for valid title and customer id" do + #valid means: rental exists [and therefore movie and customer exist] + end + + it "modifies the db with today's date as checkin date" do + + end + + it "renders bad request for invalid customer id data" do + #customer id not found + end + + it "renders a different message if rental does not exist" do + #rental does not exist (customer does not actually have that movie checked out) + end + + it "returns status not found if movie not found" do + #movie title does not return movie + end + end end From 184273b93c2307dded925eedb2ae9e16ea1c225e Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 14:28:33 -0700 Subject: [PATCH 30/49] First rental update test --- app/controllers/rentals_controller.rb | 3 +++ test/controllers/rentals_controller_test.rb | 20 ++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 58c72b791..40e2c17bf 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,2 +1,5 @@ class RentalsController < ApplicationController + + def update + end end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 1278959c7..203864772 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -6,23 +6,31 @@ # end describe "check_in" do - it "succeeds for valid title and customer id" do - #valid means: rental exists [and therefore movie and customer exist] + before do + sample_rental = Rental.create({ movie: Movie.first, customer: Customer.first }) + + post checkin_path(Movie.first.title), params: { customer_id: Customer.first.id } end - it "modifies the db with today's date as checkin date" do + it "succeeds for valid title and customer id" do + #valid means: rental exists [and therefore movie and customer exist] + + must_respond_with :success + end + it "modifies the db with today's date as checkin date" do skip + sample_rental.checkin_date.must_equal Date.today end - it "renders bad request for invalid customer id data" do + it "renders bad request for invalid customer id data" do skip #customer id not found end - it "renders a different message if rental does not exist" do + it "renders a different message if rental does not exist" do skip #rental does not exist (customer does not actually have that movie checked out) end - it "returns status not found if movie not found" do + it "returns status not found if movie not found" do skip #movie title does not return movie end end From bc286bbd27f858c2a5254bef36018143e2928972 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Wed, 10 May 2017 15:14:31 -0700 Subject: [PATCH 31/49] rental controller tests --- app/controllers/rentals_controller.rb | 25 ++++++++ app/models/rental.rb | 6 ++ config/routes.rb | 2 +- test/controllers/rentals_controller_test.rb | 66 +++++++++++++++++++-- test/fixtures/movies.yml | 6 ++ 5 files changed, 98 insertions(+), 7 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 58c72b791..78453bc75 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,2 +1,27 @@ class RentalsController < ApplicationController + + def create + if Movie.find_by_title(params[:title]).nil? + id = Movie.find_by_title(params[:title]).id + else + id = 0 + end + + rental = Rental.new(movie_id: id, customer_id: rental_params[:customer_id], due_date: rental_params[:due_date] ) + + if rental.save + render status: :ok, json: rental.as_json + else + render status: :error, json: { error: true } + end + + + end + + private + + def rental_params + params.permit(:customer_id, :due_date) + end + end diff --git a/app/models/rental.rb b/app/models/rental.rb index f81fd8642..069f8ac46 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -3,6 +3,12 @@ class Rental < ApplicationRecord belongs_to :customer after_initialize :set_defaults + validates :due_date, presence: true + validates :customer_id, presence: true + + + + def set_defaults self.checkout_date ||= Date.today self.due_date ||= Chronic.parse('two weeks from today') diff --git a/config/routes.rb b/config/routes.rb index 34ec24dfc..de0f85b31 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -7,7 +7,7 @@ # # get "/movies/:title", to: "movies#show" # - post "/rentals/:title/check-out", to: "rentals#create" + post "/rentals/:title/check-out", to: "rentals#create", as: "checkout" # [post customer_id and due_date] # # post "/rentals/:title/check-in", to: "rentals#update" diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 5d2c65e3b..1a08c9b01 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -1,24 +1,78 @@ require "test_helper" describe RentalsController do + describe "Create (checkout)" do - it "given valid customer id and movie id, can checkout movie" do + it "given valid customer id and movie title, can checkout movie (increase rental record by 1)" do + proc { + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, #this is going to AR to get the actual record but is talkign to the fixtures + due_date: Chronic.parse("two weeks from today") + + } + }.must_change 'Rental.count', 1 + must_respond_with :success end - it "given invalide customer_id, cannot checkout movie" do + it "given invalid customer_id, cannot checkout movie" do + proc { + post checkout_path("Psycho"), params: { + customer_id: Customer.all.last.id+1, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 0 + must_respond_with :error + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "error" end - it "given invalide movie_id, cannot checkout movie" do + it "given invalid movie_title, cannot checkout movie" do + proc { + post checkout_path("Psychosss"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 0 + must_respond_with :bad_request + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "errors" + body["errors"].must_include "invalid movie" end - it "can checkout a movie with enough inventory" do + it "can checkout a movie with enough inventory" do skip + proc { + post checkout_path("Psycho"), params: { rental: enough_inventory} + }.must_change 'Rental.count', 1 + must_respond_with :success end - it "cannot checkout movie with no inventory" do + it "cannot checkout movie with no inventory" do skip + proc { + post checkout_path("Psycho"), params: { rental: no_inventory} + }.must_change 'Rental.count', 0 + must_respond_with :bad_request + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "errors" + body["errors"].must_include "not enough inventory" end - it "returns a due_date that is 2 weeks from the checkout date" do + it "returns error when due date is in the past" do skip + proc { + post checkout_path("Psycho"), params: { rental: invalid_due_date} + }.must_change 'Rental.count', 0 + must_respond_with :bad_request + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "errors" + body["errors"].must_include "due date cannot be in the past" end diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index b8a6f46df..a67ffaee9 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -9,3 +9,9 @@ psycho: overview: "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower." release_date: 1960-06-16 inventory: 8 + +bringit: + title: "Bring it On" + overview: "Cheerleading drama" + release_date: 1960-06-16 + inventory: 0 From ad93c602aef316c88828007d259ba289a97e2e60 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 15:47:33 -0700 Subject: [PATCH 32/49] Start to build out update method --- app/controllers/rentals_controller.rb | 22 +++++++++++++++++++++ test/controllers/rentals_controller_test.rb | 21 ++++++++++++-------- test/fixtures/rentals.yml | 6 +++--- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 40e2c17bf..fc4dc2607 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,5 +1,27 @@ class RentalsController < ApplicationController def update + # movie_id = find_movie_id(params[:title]) + # find the rental in question based on params[:title] and params[:customer_id] + customer_id = params[:customer_id] + movie_id = Movie.find_by(title: params[:title]) + + rental = Rental.find_by(customer_id: customer_id, movie_id: movie_id) + # if found, set checkin_date to today's date + if rental + rental.checkin_date = Date.today + rental.save + render status: :ok, json: { nothing: true } + end + + + # if not found, do various things based on + # if customer id not valid + # if movie title not found + # if rental doesn't exist (customer id and movie id valid but movie never checked out) end + + # def find_movie_id(title) + # Movie.find_by_title(title).id + # end end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 203864772..6930ee9fd 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -5,21 +5,26 @@ # flunk "Need real tests" # end + describe "check_in" do - before do - sample_rental = Rental.create({ movie: Movie.first, customer: Customer.first }) + let(:rental) { rentals(:one) } + let(:customer) { customers(:good_data) } + let(:movie) { movies(:psycho) } - post checkin_path(Movie.first.title), params: { customer_id: Customer.first.id } - end + # before do + # + # # post checkin_path(Movie.first.title), params: { customer_id: Customer.first.id } + # end - it "succeeds for valid title and customer id" do + it "succeeds for valid title and customer id" do #valid means: rental exists [and therefore movie and customer exist] - + post checkin_path(movie.title), params: { customer_id: customer.id } must_respond_with :success end - it "modifies the db with today's date as checkin date" do skip - sample_rental.checkin_date.must_equal Date.today + it "modifies the db with today's date as checkin date" do + post checkin_path(movie.title), params: { customer_id: customer.id } + rental.checkin_date.must_equal Date.today end it "renders bad request for invalid customer id data" do skip diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 941e8385e..ab20cbe09 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -2,10 +2,10 @@ one: movie: psycho - customer: one + customer: good_data checkout_date: 2017-05-09 13:34:33 two: - movie: psycho - customer: two + movie: arabia + customer: good_data checkout_date: 2017-05-09 13:34:33 From 6342b6851e88657fe9cb38c6e3c94f33531212c4 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Wed, 10 May 2017 15:52:54 -0700 Subject: [PATCH 33/49] more checkout tests --- app/controllers/rentals_controller.rb | 15 ++++++----- app/models/rental.rb | 9 ++++++- test/controllers/rentals_controller_test.rb | 30 +++++++++++++-------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 78453bc75..8235bc517 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -2,17 +2,20 @@ class RentalsController < ApplicationController def create if Movie.find_by_title(params[:title]).nil? - id = Movie.find_by_title(params[:title]).id - else id = 0 + else + id = Movie.find_by_title(params[:title]).id end - rental = Rental.new(movie_id: id, customer_id: rental_params[:customer_id], due_date: rental_params[:due_date] ) + @rental = Rental.new(movie_id: id, customer_id: rental_params[:customer_id], due_date: rental_params[:due_date] ) - if rental.save - render status: :ok, json: rental.as_json + if @rental.save + render status: :ok, json: @rental.as_json else - render status: :error, json: { error: true } + # @rental.errors.full_messages.each do |message| + # puts message + # end + render status: :error, json: { error: @rental.errors.full_messages } end diff --git a/app/models/rental.rb b/app/models/rental.rb index 069f8ac46..743566d74 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -4,13 +4,20 @@ class Rental < ApplicationRecord after_initialize :set_defaults validates :due_date, presence: true + validate :due_date_not_in_past validates :customer_id, presence: true - + def due_date_not_in_past + if due_date < Date.today + errors.add(:due_date, "can't be in the past") + end + end def set_defaults self.checkout_date ||= Date.today self.due_date ||= Chronic.parse('two weeks from today') end + + end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 1a08c9b01..aaa578e89 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -36,43 +36,51 @@ due_date: Chronic.parse("two weeks from today") } }.must_change 'Rental.count', 0 - must_respond_with :bad_request + must_respond_with 500 body = JSON.parse(response.body) body.must_be_kind_of Hash - body.must_include "errors" - body["errors"].must_include "invalid movie" + body.must_include "error" end - it "can checkout a movie with enough inventory" do skip + it "can checkout a movie with enough inventory" do proc { - post checkout_path("Psycho"), params: { rental: enough_inventory} + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } }.must_change 'Rental.count', 1 must_respond_with :success end it "cannot checkout movie with no inventory" do skip proc { - post checkout_path("Psycho"), params: { rental: no_inventory} - }.must_change 'Rental.count', 0 + post checkout_path("Bring it On"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 0 must_respond_with :bad_request body = JSON.parse(response.body) body.must_be_kind_of Hash body.must_include "errors" - body["errors"].must_include "not enough inventory" + end - it "returns error when due date is in the past" do skip + it "returns error when due date is in the past" do proc { - post checkout_path("Psycho"), params: { rental: invalid_due_date} + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("yesterday") + } }.must_change 'Rental.count', 0 must_respond_with :bad_request body = JSON.parse(response.body) body.must_be_kind_of Hash body.must_include "errors" - body["errors"].must_include "due date cannot be in the past" + end From 95898533fa878a25ef7080251d45e310bfcecd5b Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Wed, 10 May 2017 20:14:57 -0700 Subject: [PATCH 34/49] Add tests and logic for invalid customer id or movie title --- app/controllers/rentals_controller.rb | 46 +++++++++++++-------- test/controllers/rentals_controller_test.rb | 24 +++++++---- test/fixtures/customers.yml | 10 +++++ 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index fc4dc2607..b64d7d296 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,27 +1,37 @@ class RentalsController < ApplicationController def update - # movie_id = find_movie_id(params[:title]) - # find the rental in question based on params[:title] and params[:customer_id] - customer_id = params[:customer_id] - movie_id = Movie.find_by(title: params[:title]) - - rental = Rental.find_by(customer_id: customer_id, movie_id: movie_id) - # if found, set checkin_date to today's date - if rental - rental.checkin_date = Date.today - rental.save - render status: :ok, json: { nothing: true } + movie = find_movie(params[:title]) + customer = find_customer(params[:customer_id]) + if movie.nil? + # if movie title not found + render status: :bad_request, json: { error: "no movie found with that title"} + elsif customer.nil? + # if customer id not valid + render status: :bad_request, json: { error: "no customer found"} + else + # find the rental in question based on params[:title] and params[:customer_id] + rental = Rental.find_by(customer_id: customer.id, movie_id: movie.id) + # if found, set checkin_date to today's date + if rental + rental.checkin_date = Date.today + rental.save + render status: :ok, json: { nothing: true } + else + # if rental doesn't exist (customer id and movie id valid but movie never checked out) + render status: :bad_request, json: { error: "that movie is not checked out to that customer"} + end end + end + + private - # if not found, do various things based on - # if customer id not valid - # if movie title not found - # if rental doesn't exist (customer id and movie id valid but movie never checked out) + def find_movie(title) + Movie.find_by_title(title) end - # def find_movie_id(title) - # Movie.find_by_title(title).id - # end + def find_customer(id) + Customer.find_by_id(id) + end end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 6930ee9fd..43fb55e52 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -10,11 +10,7 @@ let(:rental) { rentals(:one) } let(:customer) { customers(:good_data) } let(:movie) { movies(:psycho) } - - # before do - # - # # post checkin_path(Movie.first.title), params: { customer_id: Customer.first.id } - # end + let(:customer2) { customers(:no_rentals)} it "succeeds for valid title and customer id" do #valid means: rental exists [and therefore movie and customer exist] @@ -27,12 +23,26 @@ rental.checkin_date.must_equal Date.today end - it "renders bad request for invalid customer id data" do skip + it "modifies the db" do + proc { + post checkin_path(movie.title), params: { customer_id: customer.id } + }.must_change rental.checkin_date + end + + it "renders bad request for invalid customer id data" do #customer id not found + post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "customer" end - it "renders a different message if rental does not exist" do skip + it "renders a different message if rental does not exist" do #rental does not exist (customer does not actually have that movie checked out) + post checkin_path(movie.title), params: { customer_id: customer2.id} + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "not checked out" end it "returns status not found if movie not found" do skip diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index 4595604df..326dfe21a 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -50,3 +50,13 @@ negative_account: postal_code: "98122" phone: 701-306-7504 account_credit: -100.00 + +no_rentals: + name: Ethelbert + registered_at: 2017-05-09 13:28:44 + address: 1111 19th Ave South + city: Seattle + state: WA + postal_code: "98122" + phone: 701-306-7504 + account_credit: 0 From 579c02136015d1347533445ceb3097afcbdd395f Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Thu, 11 May 2017 09:23:07 -0700 Subject: [PATCH 35/49] Complete checkin tests --- test/controllers/rentals_controller_test.rb | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 43fb55e52..e47eb83c7 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -30,13 +30,19 @@ end it "renders bad request for invalid customer id data" do - #customer id not found post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} must_respond_with :bad_request body = JSON.parse(response.body) body["error"].must_include "customer" end + it "renders bad request if movie not found" do + post checkin_path("totally made up title"), params: { customer_id: customer.id } + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "movie" + end + it "renders a different message if rental does not exist" do #rental does not exist (customer does not actually have that movie checked out) post checkin_path(movie.title), params: { customer_id: customer2.id} @@ -45,8 +51,6 @@ body["error"].must_include "not checked out" end - it "returns status not found if movie not found" do skip - #movie title does not return movie - end + end end From 208b099c88c155852c02e8d6d80f53d6c7b3c3b9 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Thu, 11 May 2017 09:26:40 -0700 Subject: [PATCH 36/49] Add seed for rental --- db/seeds.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/db/seeds.rb b/db/seeds.rb index 5322340ba..b946d6de7 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,3 +5,9 @@ JSON.parse(File.read('db/seeds/movies.json')).each do |movie| Movie.create!(movie) end + +Rental.create ( + { + movie: Movie.first, + customer: Customer.first + }) From 2a4149ab40dfff45d31cbb792eaddae0e1a78079 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Thu, 11 May 2017 09:50:11 -0700 Subject: [PATCH 37/49] more rental checkout contorller testing --- app/controllers/rentals_controller.rb | 9 +++++++-- app/models/rental.rb | 9 +++++++++ test/controllers/rentals_controller_test.rb | 12 ++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 8235bc517..f31f2b86c 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,10 +1,15 @@ class RentalsController < ApplicationController def create - if Movie.find_by_title(params[:title]).nil? + movie = Movie.find_by_title(params[:title]) + # if movie.inventory < 1 + # render status: :error, json: { error: "not enough inventory"} + # end + + if movie.nil? || movie.inventory < 1 id = 0 else - id = Movie.find_by_title(params[:title]).id + id = movie.id end @rental = Rental.new(movie_id: id, customer_id: rental_params[:customer_id], due_date: rental_params[:due_date] ) diff --git a/app/models/rental.rb b/app/models/rental.rb index 743566d74..565e7f5ee 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -5,6 +5,8 @@ class Rental < ApplicationRecord validates :due_date, presence: true validate :due_date_not_in_past + # validate :enough_inventory + validates :customer_id, presence: true @@ -14,6 +16,13 @@ def due_date_not_in_past end end + # def enough_inventory + # inventory = movie.inventory + # if inventory < 1 + # errors.add(:inventory, "not enough inventory") + # end + # end + def set_defaults self.checkout_date ||= Date.today self.due_date ||= Chronic.parse('two weeks from today') diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index aaa578e89..e9b44f359 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -53,18 +53,18 @@ must_respond_with :success end - it "cannot checkout movie with no inventory" do skip + it "cannot checkout movie with no inventory" do proc { post checkout_path("Bring it On"), params: { customer_id: Customer.all.first.id, due_date: Chronic.parse("two weeks from today") } }.must_change 'Rental.count', 0 - must_respond_with :bad_request + must_respond_with 500 body = JSON.parse(response.body) body.must_be_kind_of Hash - body.must_include "errors" + body.must_include "error" end @@ -75,12 +75,12 @@ due_date: Chronic.parse("yesterday") } }.must_change 'Rental.count', 0 - must_respond_with :bad_request + must_respond_with 500 body = JSON.parse(response.body) body.must_be_kind_of Hash - body.must_include "errors" - + body.must_include "error" + end From 670d7195c6baa1e15406402386a6d2196362630e Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Thu, 11 May 2017 10:15:02 -0700 Subject: [PATCH 38/49] added decrease inventory logic --- app/controllers/rentals_controller.rb | 9 +- test/controllers/rentals_controller_test.rb | 197 +++++++++++--------- 2 files changed, 108 insertions(+), 98 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 4bf71d649..1e26346d2 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -3,9 +3,6 @@ class RentalsController < ApplicationController def create movie = Movie.find_by_title(params[:title]) - # if movie.inventory < 1 - # render status: :error, json: { error: "not enough inventory"} - # end if movie.nil? || movie.inventory < 1 id = 0 @@ -16,13 +13,13 @@ def create @rental = Rental.new(movie_id: id, customer_id: rental_params[:customer_id], due_date: rental_params[:due_date] ) if @rental.save + movie.inventory -= 1 + movie.save render status: :ok, json: @rental.as_json else - # @rental.errors.full_messages.each do |message| - # puts message - # end render status: :error, json: { error: @rental.errors.full_messages } end + end def update diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index cb13e90f4..a1b3f9e9f 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -5,128 +5,141 @@ describe "Create (checkout)" do it "given valid customer id and movie title, can checkout movie (increase rental record by 1)" do - proc { - post checkout_path("Psycho"), params: { - customer_id: Customer.all.first.id, #this is going to AR to get the actual record but is talkign to the fixtures - due_date: Chronic.parse("two weeks from today") - - } - }.must_change 'Rental.count', 1 - must_respond_with :success + proc { + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, #this is going to AR to get the actual record but is talkign to the fixtures + due_date: Chronic.parse("two weeks from today") + + } + }.must_change 'Rental.count', 1 + must_respond_with :success end it "given invalid customer_id, cannot checkout movie" do proc { - post checkout_path("Psycho"), params: { - customer_id: Customer.all.last.id+1, - due_date: Chronic.parse("two weeks from today") - } - }.must_change 'Rental.count', 0 - must_respond_with :error - - body = JSON.parse(response.body) - body.must_be_kind_of Hash - body.must_include "error" + post checkout_path("Psycho"), params: { + customer_id: Customer.all.last.id+1, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 0 + must_respond_with :error + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "error" end it "given invalid movie_title, cannot checkout movie" do proc { - post checkout_path("Psychosss"), params: { - customer_id: Customer.all.first.id, - due_date: Chronic.parse("two weeks from today") - } - }.must_change 'Rental.count', 0 - must_respond_with 500 - - body = JSON.parse(response.body) - body.must_be_kind_of Hash - body.must_include "error" + post checkout_path("Psychosss"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 0 + must_respond_with 500 + + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "error" end it "can checkout a movie with enough inventory" do proc { - post checkout_path("Psycho"), params: { - customer_id: Customer.all.first.id, - due_date: Chronic.parse("two weeks from today") - } - }.must_change 'Rental.count', 1 - must_respond_with :success + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 1 + must_respond_with :success end it "cannot checkout movie with no inventory" do proc { - post checkout_path("Bring it On"), params: { - customer_id: Customer.all.first.id, - due_date: Chronic.parse("two weeks from today") - } - }.must_change 'Rental.count', 0 - must_respond_with 500 + post checkout_path("Bring it On"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Rental.count', 0 + must_respond_with 500 - body = JSON.parse(response.body) - body.must_be_kind_of Hash - body.must_include "error" + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "error" end it "returns error when due date is in the past" do proc { - post checkout_path("Psycho"), params: { - customer_id: Customer.all.first.id, - due_date: Chronic.parse("yesterday") - } - }.must_change 'Rental.count', 0 - must_respond_with 500 - - body = JSON.parse(response.body) - body.must_be_kind_of Hash - body.must_include "error" - - - describe "check_in" do - let(:rental) { rentals(:one) } - let(:customer) { customers(:good_data) } - let(:movie) { movies(:psycho) } - let(:customer2) { customers(:no_rentals)} - - it "succeeds for valid title and customer id" do - #valid means: rental exists [and therefore movie and customer exist] - post checkin_path(movie.title), params: { customer_id: customer.id } - must_respond_with :success - end + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("yesterday") + } + }.must_change 'Rental.count', 0 + must_respond_with 500 - it "modifies the db with today's date as checkin date" do - post checkin_path(movie.title), params: { customer_id: customer.id } - rental.checkin_date.must_equal Date.today + body = JSON.parse(response.body) + body.must_be_kind_of Hash + body.must_include "error" end - it "modifies the db" do + it "decreases inventory of movie by 1" do proc { - post checkin_path(movie.title), params: { customer_id: customer.id } - }.must_change rental.checkin_date - end + post checkout_path("Psycho"), params: { + customer_id: Customer.all.first.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'Movie.find_by_title("Psycho").inventory', -1 - it "renders bad request for invalid customer id data" do - post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} - must_respond_with :bad_request - body = JSON.parse(response.body) - body["error"].must_include "customer" end - it "renders bad request if movie not found" do - post checkin_path("totally made up title"), params: { customer_id: customer.id } - must_respond_with :bad_request - body = JSON.parse(response.body) - body["error"].must_include "movie" - end + end - it "renders a different message if rental does not exist" do - #rental does not exist (customer does not actually have that movie checked out) - post checkin_path(movie.title), params: { customer_id: customer2.id} - must_respond_with :bad_request - body = JSON.parse(response.body) - body["error"].must_include "not checked out" - end + describe "check_in" do + let(:rental) { rentals(:one) } + let(:customer) { customers(:good_data) } + let(:movie) { movies(:psycho) } + let(:customer2) { customers(:no_rentals)} + it "succeeds for valid title and customer id" do + #valid means: rental exists [and therefore movie and customer exist] + post checkin_path(movie.title), params: { customer_id: customer.id } + must_respond_with :success + end + + it "modifies the db with today's date as checkin date" do + post checkin_path(movie.title), params: { customer_id: customer.id } + rental.checkin_date.must_equal Date.today + end + + it "modifies the db" do + proc { + post checkin_path(movie.title), params: { customer_id: customer.id } + }.must_change rental.checkin_date + end + + it "renders bad request for invalid customer id data" do + post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "customer" + end + + it "renders bad request if movie not found" do + post checkin_path("totally made up title"), params: { customer_id: customer.id } + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "movie" + end + + it "renders a different message if rental does not exist" do + #rental does not exist (customer does not actually have that movie checked out) + post checkin_path(movie.title), params: { customer_id: customer2.id} + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "not checked out" + end + + + end end -end From 38c070c6c92c574db42e94896daecd31de5f057d Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Thu, 11 May 2017 13:29:05 -0700 Subject: [PATCH 39/49] Stub in tests for customers sort --- test/controllers/customers_controller_test.rb | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 68a5e220c..ac81bc4f3 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -32,4 +32,22 @@ end end + + describe "index with sort parameter" do + it "sorts customers by name" do + get customers_path(sort: name) + end + + it "sorts customers by date registered" do + + end + + it "sorts customers by postal code" do + + end + + it "reverts to rails default if sort value is not valid" do + + end + end end From 779f024352aaf464a00190b8c62a8e14b791c2f3 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Thu, 11 May 2017 13:32:43 -0700 Subject: [PATCH 40/49] WIP sort tests --- test/controllers/customers_controller_test.rb | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index ac81bc4f3..efae17aab 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -28,25 +28,27 @@ body.each do |customer| customer.keys.sort.must_equal CUSTOMER_KEYS end - end - end describe "index with sort parameter" do it "sorts customers by name" do get customers_path(sort: name) + # check first and last against sorted db + body = JSON.parse(response.body) + body.each do |customer| + end - it "sorts customers by date registered" do + it "sorts customers by date registered" do skip end - it "sorts customers by postal code" do + it "sorts customers by postal code" do skip end - it "reverts to rails default if sort value is not valid" do + it "reverts to rails default if sort value is not valid" do skip end end From 24c9aae848879329bec739488c704dfc8b2e8efd Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Fri, 12 May 2017 10:10:04 -0700 Subject: [PATCH 41/49] Add movies checked out count method --- app/models/customer.rb | 4 +++- test/controllers/customers_controller_test.rb | 1 - test/controllers/rentals_controller_test.rb | 11 +++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/models/customer.rb b/app/models/customer.rb index 14ed49ae5..3b7e35283 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -15,7 +15,9 @@ class Customer < ApplicationRecord validates :name, uniqueness: { scope: [:address, :city, :state, :postal_code, :phone] } def movies_checked_out_count - return 0 + #rentals with this customer id and checkin_date = nil + rentals = Rental.where(customer_id: self.id, checkin_date: nil) + return rentals.size end end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 68a5e220c..a9f2830ec 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -2,7 +2,6 @@ describe "CustomersController" do CUSTOMER_KEYS = %w(id movies_checked_out_count name phone postal_code registered_at) -# need to eventually include movies_checked_out_count describe "index" do before do diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index a1b3f9e9f..4c41d9cbb 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -3,6 +3,8 @@ describe RentalsController do describe "Create (checkout)" do + let(:customer) { customers(:good_data) } + let(:movie) { movies(:psycho) } it "given valid customer id and movie title, can checkout movie (increase rental record by 1)" do proc { @@ -92,6 +94,15 @@ end + it "increases the customer's movies_checked_out_count by 1" do + proc { + post checkout_path(movie.title), params: { + customer_id: customer.id, + due_date: Chronic.parse("two weeks from today") + } + }.must_change 'customer.movies_checked_out_count', 1 + end + end From be2894fbe71589a7041135834eb20c0db1422967 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Fri, 12 May 2017 10:34:01 -0700 Subject: [PATCH 42/49] added overdue controller tests --- app/controllers/movies_controller.rb | 22 +++++++++++++--------- app/controllers/rentals_controller.rb | 14 ++++++++++++++ app/models/rental.rb | 14 ++++++++++++++ config/routes.rb | 2 +- test/controllers/movies_controller_test.rb | 17 +++++++++++++++++ 5 files changed, 59 insertions(+), 10 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 19feec216..5ebc7625a 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -1,21 +1,25 @@ class MoviesController < ApplicationController + + before_action :find_movie, :only => [:show] + def index movies = Movie.all render json: movies.as_json(only: [:title, :release_date]), status: :ok end def show - # this might be better if titles can be duplicate - # returns an array of instances rather than an instance - # movie = Movie.where({title: params[:title]}) - - movie = Movie.find_by(title: params[:title]) - - if movie + if movie.nil? + render json: { nothing: true }, status: :not_found + else render json: movie.as_json(except: [:id, :updated_at, :created_at], methods: :available_inventory), status: :ok - else - render json: { nothing: true }, status: :not_found end end end + +private + +def find_movie + movie = Movie.find_by(title: params[:title]) + return movie +end diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 1e26346d2..b5dcef89a 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -45,6 +45,20 @@ def update end end + + def overdue + movie = Movie.find_by_title(params[:title]) + if movie + if customers_with_overdue.length != 0 + render json: over_due_rentals.as_json(only: [:title, :customer_id, :name, :postal_code, :checkout_date, :due_date], status: :ok) + else + render json: { overdue: "none" }, status: :ok + end + else + render json: { movie: "not found" }, status: :error + end + end + end private diff --git a/app/models/rental.rb b/app/models/rental.rb index acc68a183..edb610131 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -28,4 +28,18 @@ def set_defaults self.due_date ||= Chronic.parse('two weeks from today') end + def over_due_rentals #returns array of Customer objects + movie_rentals = Rental.find_by_movie_id(movie.id) + over_due_rentals = movie_rentals.where('due_date > Today.date') + + customers_with_overdue = [] + over_due_rentals.each do |rental| + customers_with_overdue << Customer.find_by_customer_id(rental.customer_id) + end + return customers_with_overdue + end + + + + end diff --git a/config/routes.rb b/config/routes.rb index 5bbd62f28..c0b52f36b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -13,5 +13,5 @@ post "/rentals/:title/check-in", to: "rentals#update", as: "checkin" # [post customer_id] # - # get "/rentals/overdue", to: "rentals#overdue" + get "/rentals/overdue", to: "rentals#overdue", as: "overdue" end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 6660216cd..a92984fcf 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -68,4 +68,21 @@ end end + describe "overdue" do + let(:arabia) { movies(:arabia) } + + it "should list customers given a movie with overdue inventory" do + get overdue(arabia.title) + must_respond_with :success + + end + + it "should return no movies given a title with no overdue inventory" do skip + end + + it "should return an error when an invalid movie is given" do skip + end + + end + end From 4105087f07a61d3c2566729776e86acc43e52581 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Fri, 12 May 2017 10:56:05 -0700 Subject: [PATCH 43/49] Add test and logic to increase movie inventory on checkin --- app/controllers/rentals_controller.rb | 2 ++ test/controllers/rentals_controller_test.rb | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 1e26346d2..deb031532 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -38,6 +38,8 @@ def update if rental rental.checkin_date = Date.today rental.save + movie.inventory += 1 + movie.save render status: :ok, json: { nothing: true } else # if rental doesn't exist (customer id and movie id valid but movie never checked out) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 4c41d9cbb..d4e3be4ea 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -129,6 +129,18 @@ }.must_change rental.checkin_date end + it "decreases the customer's movies_checked_out_count by 1" do + proc { + post checkin_path(movie.title), params: { customer_id: customer.id } + }.must_change 'customer.movies_checked_out_count', -1 + end + + it "increases the movie's inventory count by 1" do + proc { + post checkin_path(movie.title), params: { customer_id: customer.id } + }.must_change 'Movie.find_by_title("Psycho").inventory', 1 + end + it "renders bad request for invalid customer id data" do post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} must_respond_with :bad_request @@ -136,6 +148,12 @@ body["error"].must_include "customer" end + it "does not change the customer's movies_checked_out_count with invalid data" do + proc { + post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} + }.must_change 'customer.movies_checked_out_count', 0 + end + it "renders bad request if movie not found" do post checkin_path("totally made up title"), params: { customer_id: customer.id } must_respond_with :bad_request @@ -152,5 +170,7 @@ end + + end end From 32687371d0f9839d45dcd205c8686c4fa857ece1 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Fri, 12 May 2017 11:11:22 -0700 Subject: [PATCH 44/49] Revise tests and methods to use available_inventory rather than inventory --- app/controllers/rentals_controller.rb | 10 +++++----- app/models/movie.rb | 6 ++++-- test/controllers/rentals_controller_test.rb | 20 +++++++++++++++++--- test/fixtures/movies.yml | 3 +-- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index deb031532..2fb026a67 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,7 +4,7 @@ class RentalsController < ApplicationController def create movie = Movie.find_by_title(params[:title]) - if movie.nil? || movie.inventory < 1 + if movie.nil? || movie.available_inventory < 1 id = 0 else id = movie.id @@ -13,8 +13,8 @@ def create @rental = Rental.new(movie_id: id, customer_id: rental_params[:customer_id], due_date: rental_params[:due_date] ) if @rental.save - movie.inventory -= 1 - movie.save + # movie.inventory -= 1 + # movie.save render status: :ok, json: @rental.as_json else render status: :error, json: { error: @rental.errors.full_messages } @@ -38,8 +38,8 @@ def update if rental rental.checkin_date = Date.today rental.save - movie.inventory += 1 - movie.save + # movie.inventory += 1 + # movie.save render status: :ok, json: { nothing: true } else # if rental doesn't exist (customer id and movie id valid but movie never checked out) diff --git a/app/models/movie.rb b/app/models/movie.rb index 21032487b..dd115e8e5 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -7,7 +7,9 @@ class Movie < ApplicationRecord has_many :rentals def available_inventory - return 0 + #should subtract from the inventory the number of copies out in active rentals (checkin_date = nil) + rentals = Rental.where(movie_id: self.id, checkin_date: nil) + return self.inventory - rentals.size end - + end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index d4e3be4ea..f6c7040c7 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -5,6 +5,7 @@ describe "Create (checkout)" do let(:customer) { customers(:good_data) } let(:movie) { movies(:psycho) } + let(:customer2) { customers(:no_rentals)} it "given valid customer id and movie title, can checkout movie (increase rental record by 1)" do proc { @@ -67,6 +68,19 @@ body = JSON.parse(response.body) body.must_be_kind_of Hash body.must_include "error" + end + + it "cannot checkout movie with no available inventory" do + post checkout_path("Lawrence of Arabia"), params: { + customer_id: customer.id, + due_date: Chronic.parse("two weeks from today")} + proc { + post checkout_path("Lawrence of Arabia"), params: { + customer_id: customer.id, + due_date: Chronic.parse("two weeks from today")} + }.must_change 'Rental.count', 0 + must_respond_with 500 + end @@ -90,7 +104,7 @@ customer_id: Customer.all.first.id, due_date: Chronic.parse("two weeks from today") } - }.must_change 'Movie.find_by_title("Psycho").inventory', -1 + }.must_change 'Movie.find_by_title("Psycho").available_inventory', -1 end @@ -135,10 +149,10 @@ }.must_change 'customer.movies_checked_out_count', -1 end - it "increases the movie's inventory count by 1" do + it "increases the movie's available inventory count by 1" do proc { post checkin_path(movie.title), params: { customer_id: customer.id } - }.must_change 'Movie.find_by_title("Psycho").inventory', 1 + }.must_change 'Movie.find_by_title("Psycho").available_inventory', 1 end it "renders bad request for invalid customer id data" do diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index 7dcb06da9..aa4894c99 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -22,5 +22,4 @@ arabia: title: "Lawrence of Arabia" overview: "Lawrence of Arabia is the classic film from David Lean starring Peter O’Toole and based on the autobiography from Thomas Edward Lawrence who during the first World War was on assignment by the British Empire in Arabia. The film would become a cult classic and is known today as a masterpiece." release_date: 1962-12-10 - inventory: 6 - + inventory: 1 From e8fb92295d5a3ac24695f67ea9f8dedf5ad6bd9b Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Fri, 12 May 2017 13:18:31 -0700 Subject: [PATCH 45/49] making changes in overdue method --- app/controllers/movies_controller.rb | 15 ++-- app/controllers/rentals_controller.rb | 12 +-- app/models/rental.rb | 10 +-- config/routes.rb | 3 +- test/controllers/movies_controller_test.rb | 17 ---- test/controllers/rentals_controller_test.rb | 99 ++++++++++++--------- test/fixtures/rentals.yml | 6 ++ 7 files changed, 81 insertions(+), 81 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 5ebc7625a..a67224ec2 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -1,6 +1,6 @@ class MoviesController < ApplicationController - before_action :find_movie, :only => [:show] + # before_action :find_movie, :only => [:show] def index movies = Movie.all @@ -8,6 +8,7 @@ def index end def show + movie = Movie.find_by(title: params[:title]) if movie.nil? render json: { nothing: true }, status: :not_found else @@ -17,9 +18,9 @@ def show end end -private - -def find_movie - movie = Movie.find_by(title: params[:title]) - return movie -end +# private +# +# def find_movie +# movie = Movie.find_by(title: params[:title]) +# return movie +# end diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index b5dcef89a..1d6110acf 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -47,15 +47,11 @@ def update def overdue - movie = Movie.find_by_title(params[:title]) - if movie - if customers_with_overdue.length != 0 - render json: over_due_rentals.as_json(only: [:title, :customer_id, :name, :postal_code, :checkout_date, :due_date], status: :ok) - else - render json: { overdue: "none" }, status: :ok - end + overdue_customers = Rental.over_due_rentals + if overdue_customers.nil? + render json: { overdue: "none" }, status: :ok else - render json: { movie: "not found" }, status: :error + render json: overdue_customers.as_json(only: [:title, :customer_id, :name, :postal_code, :checkout_date, :due_date], status: :ok) end end diff --git a/app/models/rental.rb b/app/models/rental.rb index edb610131..26773dec9 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -28,13 +28,13 @@ def set_defaults self.due_date ||= Chronic.parse('two weeks from today') end - def over_due_rentals #returns array of Customer objects - movie_rentals = Rental.find_by_movie_id(movie.id) - over_due_rentals = movie_rentals.where('due_date > Today.date') + def self.over_due_rentals #returns array of Customer objects + rentals = Rental.where("due_date < ?", Date.today) + overdue_rentals = rentals.where.not('checkin_date': nil) customers_with_overdue = [] - over_due_rentals.each do |rental| - customers_with_overdue << Customer.find_by_customer_id(rental.customer_id) + overdue_rentals.each do |rental| + customers_with_overdue << Customer.find_by_id(rental.customer_id) end return customers_with_overdue end diff --git a/config/routes.rb b/config/routes.rb index c0b52f36b..28f73fb79 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,11 +1,13 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + get "/rentals/overdue", to: "rentals#overdue" get "/customers", to: "customers#index" get "/movies", to: "movies#index" # get "/movies/:title", to: "movies#show", as: "movie" + # post "/rentals/:title/check-out", to: "rentals#create", as: "checkout" # [post customer_id and due_date] @@ -13,5 +15,4 @@ post "/rentals/:title/check-in", to: "rentals#update", as: "checkin" # [post customer_id] # - get "/rentals/overdue", to: "rentals#overdue", as: "overdue" end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index a92984fcf..6660216cd 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -68,21 +68,4 @@ end end - describe "overdue" do - let(:arabia) { movies(:arabia) } - - it "should list customers given a movie with overdue inventory" do - get overdue(arabia.title) - must_respond_with :success - - end - - it "should return no movies given a title with no overdue inventory" do skip - end - - it "should return an error when an invalid movie is given" do skip - end - - end - end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index a1b3f9e9f..fa3ec172f 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -87,59 +87,72 @@ post checkout_path("Psycho"), params: { customer_id: Customer.all.first.id, due_date: Chronic.parse("two weeks from today") - } - }.must_change 'Movie.find_by_title("Psycho").inventory', -1 + } + }.must_change 'Movie.find_by_title("Psycho").inventory', -1 end end - describe "check_in" do - let(:rental) { rentals(:one) } - let(:customer) { customers(:good_data) } - let(:movie) { movies(:psycho) } - let(:customer2) { customers(:no_rentals)} + describe "check_in" do + let(:rental) { rentals(:one) } + let(:customer) { customers(:good_data) } + let(:movie) { movies(:psycho) } + let(:customer2) { customers(:no_rentals)} - it "succeeds for valid title and customer id" do - #valid means: rental exists [and therefore movie and customer exist] - post checkin_path(movie.title), params: { customer_id: customer.id } - must_respond_with :success - end + it "succeeds for valid title and customer id" do + #valid means: rental exists [and therefore movie and customer exist] + post checkin_path(movie.title), params: { customer_id: customer.id } + must_respond_with :success + end - it "modifies the db with today's date as checkin date" do + it "modifies the db with today's date as checkin date" do + post checkin_path(movie.title), params: { customer_id: customer.id } + rental.checkin_date.must_equal Date.today + end + + it "modifies the db" do + proc { post checkin_path(movie.title), params: { customer_id: customer.id } - rental.checkin_date.must_equal Date.today - end - - it "modifies the db" do - proc { - post checkin_path(movie.title), params: { customer_id: customer.id } - }.must_change rental.checkin_date - end - - it "renders bad request for invalid customer id data" do - post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} - must_respond_with :bad_request - body = JSON.parse(response.body) - body["error"].must_include "customer" - end - - it "renders bad request if movie not found" do - post checkin_path("totally made up title"), params: { customer_id: customer.id } - must_respond_with :bad_request - body = JSON.parse(response.body) - body["error"].must_include "movie" - end - - it "renders a different message if rental does not exist" do - #rental does not exist (customer does not actually have that movie checked out) - post checkin_path(movie.title), params: { customer_id: customer2.id} - must_respond_with :bad_request - body = JSON.parse(response.body) - body["error"].must_include "not checked out" - end + }.must_change rental.checkin_date + end + it "renders bad request for invalid customer id data" do + post checkin_path(movie.title), params: { customer_id: (Customer.last.id + 1)} + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "customer" + end + it "renders bad request if movie not found" do + post checkin_path("totally made up title"), params: { customer_id: customer.id } + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "movie" end + + it "renders a different message if rental does not exist" do + #rental does not exist (customer does not actually have that movie checked out) + post checkin_path(movie.title), params: { customer_id: customer2.id} + must_respond_with :bad_request + body = JSON.parse(response.body) + body["error"].must_include "not checked out" + end + end + + + describe "overdue" do + + it "should list customers with overdue titles" do + get rentals_overdue_path + must_respond_with :success + end + + it "response should be in json" do skip + end + + end + +end diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index ab20cbe09..35edb2879 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -9,3 +9,9 @@ two: movie: arabia customer: good_data checkout_date: 2017-05-09 13:34:33 + +three: + movie: arabia + customer: good_data + checkout_date: 2017-05-09 13:34:33 + due_date: 2017-05-09 13:34:33 From 6aea9c736362ad76b2ed0a91c8d8a554d81563f4 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Fri, 12 May 2017 13:43:49 -0700 Subject: [PATCH 46/49] resolved overdue method errors --- app/controllers/rentals_controller.rb | 5 +++-- app/models/rental.rb | 14 +++++++------- db/seeds.rb | 9 +++++++++ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 1d6110acf..8be7600ba 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -44,18 +44,19 @@ def update render status: :bad_request, json: { error: "that movie is not checked out to that customer"} end end + end def overdue overdue_customers = Rental.over_due_rentals - if overdue_customers.nil? + if overdue_customers.length == 0 render json: { overdue: "none" }, status: :ok else render json: overdue_customers.as_json(only: [:title, :customer_id, :name, :postal_code, :checkout_date, :due_date], status: :ok) end end - end + private diff --git a/app/models/rental.rb b/app/models/rental.rb index 26773dec9..d6a14ad9d 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -4,17 +4,17 @@ class Rental < ApplicationRecord after_initialize :set_defaults validates :due_date, presence: true - validate :due_date_not_in_past + # validate :due_date_not_in_past # validate :enough_inventory validates :customer_id, presence: true - def due_date_not_in_past - if due_date < Date.today - errors.add(:due_date, "can't be in the past") - end - end + # def due_date_not_in_past + # if due_date < Date.today + # errors.add(:due_date, "can't be in the past") + # end + # end # def enough_inventory # inventory = movie.inventory @@ -30,7 +30,7 @@ def set_defaults def self.over_due_rentals #returns array of Customer objects rentals = Rental.where("due_date < ?", Date.today) - overdue_rentals = rentals.where.not('checkin_date': nil) + overdue_rentals = rentals.where('checkin_date': nil) customers_with_overdue = [] overdue_rentals.each do |rental| diff --git a/db/seeds.rb b/db/seeds.rb index b946d6de7..e938c60b8 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -11,3 +11,12 @@ movie: Movie.first, customer: Customer.first }) + +Rental.create ( + { + movie: Movie.first, + customer: Customer.last, + due_date: Chronic.parse('yesterday') + + } +) From b625ff9199d4d7dd171297d1bb877e0975c82295 Mon Sep 17 00:00:00 2001 From: Regan Huff Date: Fri, 12 May 2017 14:21:10 -0700 Subject: [PATCH 47/49] Tests and action to accept sort parameter for customer index --- app/controllers/customers_controller.rb | 7 ++++- test/controllers/customers_controller_test.rb | 27 ++++++++++++------- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 2a942fdbb..bf46fe5f6 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -1,7 +1,12 @@ class CustomersController < ApplicationController def index - customers = Customer.all + if ["name", "registered_at", "postal_code"].include?(params[:sort]) + customers = Customer.order(params[:sort]) + else + customers = Customer.all + end + render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone], methods: :movies_checked_out_count), status: :ok end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index ba31cea59..134727374 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -32,23 +32,32 @@ describe "index with sort parameter" do it "sorts customers by name" do - get customers_path(sort: name) + get customers_path(sort: "name") # check first and last against sorted db body = JSON.parse(response.body) - body.each do |customer| - + customers = Customer.order(:name) + body.first["name"].must_equal customers.first[:name] + body.last["name"].must_equal customers.last[:name] end - it "sorts customers by date registered" do skip - + it "sorts customers by date registered" do + get customers_path(sort: "registered_at") + # check first and last against sorted db + body = JSON.parse(response.body) + customers = Customer.order(:registered_at) + body.first["registered_at"].must_equal customers.first[:registered_at] + body.last["registered_at"].must_equal customers.last[:registered_at] end - it "sorts customers by postal code" do skip - + it "sorts customers by postal code" do + get customers_path(sort: "postal_code") + # check first and last against sorted db + body = JSON.parse(response.body) + customers = Customer.order(:postal_code) + body.first["postal_code"].must_equal customers.first[:postal_code] + body.last["postal_code"].must_equal customers.last[:postal_code] end - it "reverts to rails default if sort value is not valid" do skip - end end end From ee99fa75fa27dc074615583d484960c73bf866ef Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Fri, 12 May 2017 14:46:27 -0700 Subject: [PATCH 48/49] fixed display for overdue --- app/controllers/rentals_controller.rb | 17 +++++++---------- app/models/rental.rb | 20 +++++++++++++++----- 2 files changed, 22 insertions(+), 15 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 2ee394337..e64cfc5d2 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,6 +1,5 @@ class RentalsController < ApplicationController - def create movie = Movie.find_by_title(params[:title]) @@ -49,16 +48,14 @@ def update end - def overdue - overdue_customers = Rental.over_due_rentals - if overdue_customers.length == 0 - render json: { overdue: "none" }, status: :ok - else - render json: overdue_customers.as_json(only: [:title, :customer_id, :name, :postal_code, :checkout_date, :due_date], status: :ok) - end + def overdue + overdue_rentals = Rental.over_due_rentals + if overdue_rentals.length == 0 + render json: { overdue: "none" }, status: :ok + else + render json: overdue_rentals.as_json(only: [:customer_id, :checkout_date, :due_date], methods: [:customer_name, :customer_postal_code, :movie_title]), status: :ok end - - + end private diff --git a/app/models/rental.rb b/app/models/rental.rb index d6a14ad9d..ecc64e5ec 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -31,14 +31,24 @@ def set_defaults def self.over_due_rentals #returns array of Customer objects rentals = Rental.where("due_date < ?", Date.today) overdue_rentals = rentals.where('checkin_date': nil) + return overdue_rentals - customers_with_overdue = [] - overdue_rentals.each do |rental| - customers_with_overdue << Customer.find_by_id(rental.customer_id) - end - return customers_with_overdue end + def customer_name + return self.customer.name + end + + def customer_postal_code + return self.customer.postal_code + end + + def movie_title + return self.movie.title + end + + + From 53d58d625dd2539d30d46f1ed56cd31879e1daf3 Mon Sep 17 00:00:00 2001 From: Ann Dai Date: Fri, 12 May 2017 14:51:28 -0700 Subject: [PATCH 49/49] took out due date in past test --- test/controllers/rentals_controller_test.rb | 30 +++++++++++---------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 1f0cd4f1c..c465124bf 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -84,19 +84,19 @@ end - it "returns error when due date is in the past" do - proc { - post checkout_path("Psycho"), params: { - customer_id: Customer.all.first.id, - due_date: Chronic.parse("yesterday") - } - }.must_change 'Rental.count', 0 - must_respond_with 500 - - body = JSON.parse(response.body) - body.must_be_kind_of Hash - body.must_include "error" - end + # it "returns error when due date is in the past" do + # proc { + # post checkout_path("Psycho"), params: { + # customer_id: Customer.all.first.id, + # due_date: Chronic.parse("yesterday") + # } + # }.must_change 'Rental.count', 0 + # must_respond_with 500 + # + # body = JSON.parse(response.body) + # body.must_be_kind_of Hash + # body.must_include "error" + # end it "decreases inventory of movie by 1" do proc { @@ -217,7 +217,9 @@ must_respond_with :success end - it "response should be in json" do skip + it "response should be in json" do + get rentals_overdue_path + response.header['Content-Type'].must_include 'json' end