Skip to content

Commit

Permalink
Merge pull request #15 from stephenkati/features/specs
Browse files Browse the repository at this point in the history
Setup Tests: model, requests, system
  • Loading branch information
stephenkati committed Aug 2, 2023
2 parents 6052af5 + 8b226ce commit 3e9e34d
Show file tree
Hide file tree
Showing 20 changed files with 695 additions and 5 deletions.
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,13 @@ group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem 'capybara'
gem 'selenium-webdriver'
gem 'webdrivers'
gem 'webdrivers', '>=5.3.0'
end

gem 'cancancan'
gem 'devise'
gem 'letter_opener'
gem 'rails-controller-testing'
gem 'rspec-rails', '~> 6.0', '>= 6.0.3'
gem 'rubocop', '>= 1.0', '< 2.0'
gem 'simplecov', require: false
38 changes: 35 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
diff-lcs (1.5.0)
docile (1.4.0)
erubi (1.12.0)
globalid (1.1.0)
activesupport (>= 5.0)
Expand Down Expand Up @@ -171,6 +173,10 @@ GEM
activesupport (= 7.0.6)
bundler (>= 1.15.0)
railties (= 7.0.6)
rails-controller-testing (1.0.5)
actionpack (>= 5.0.1.rc1)
actionview (>= 5.0.1.rc1)
activesupport (>= 5.0.1.rc1)
rails-dom-testing (2.1.1)
activesupport (>= 5.0.0)
minitest
Expand All @@ -194,6 +200,23 @@ GEM
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.6)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-rails (6.0.3)
actionpack (>= 6.1)
activesupport (>= 6.1)
railties (>= 6.1)
rspec-core (~> 3.12)
rspec-expectations (~> 3.12)
rspec-mocks (~> 3.12)
rspec-support (~> 3.12)
rspec-support (3.12.1)
rubocop (1.55.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
Expand All @@ -213,6 +236,12 @@ GEM
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
simplecov (0.22.0)
docile (~> 1.1)
simplecov-html (~> 0.11)
simplecov_json_formatter (~> 0.1)
simplecov-html (0.12.3)
simplecov_json_formatter (0.1.4)
sprockets (4.2.0)
concurrent-ruby (~> 1.0)
rack (>= 2.2.4, < 4)
Expand Down Expand Up @@ -242,10 +271,10 @@ GEM
activemodel (>= 6.0.0)
bindex (>= 0.4.0)
railties (>= 6.0.0)
webdrivers (5.2.0)
webdrivers (5.3.1)
nokogiri (~> 1.6)
rubyzip (>= 1.3.0)
selenium-webdriver (~> 4.0)
selenium-webdriver (~> 4.0, < 4.11)
websocket (1.2.9)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)
Expand All @@ -270,15 +299,18 @@ DEPENDENCIES
pg (~> 1.1)
puma (~> 5.0)
rails (~> 7.0.6)
rails-controller-testing
rspec-rails (~> 6.0, >= 6.0.3)
rubocop (>= 1.0, < 2.0)
selenium-webdriver
simplecov
sprockets-rails
stimulus-rails
tailwindcss-rails
turbo-rails
tzinfo-data
web-console
webdrivers
webdrivers (>= 5.3.0)

RUBY VERSION
ruby 3.1.2p20
Expand Down
1 change: 1 addition & 0 deletions app/controllers/general_shopping_lists_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class GeneralShoppingListsController < ApplicationController
before_action :authenticate_user!

def index
@user = current_user
@general_shopping_list = generate_general_shopping_list
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/recipe_foods_controller.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
class RecipeFoodsController < ApplicationController
before_action :authenticate_user!

def new
@recipe = Recipe.find_by(id: params[:recipe_id])
@recipe_food = RecipeFood.new
Expand Down Expand Up @@ -33,7 +34,6 @@ def edit
def update
@recipe = Recipe.find_by(id: params[:recipe_id])
@recipe_food = RecipeFood.includes(:recipe).find_by(id: params[:id])
puts @recipe

if @recipe_food.update(recipe_food_params)
flash[:notice] = 'Ingredient has been updated successfully'
Expand Down
2 changes: 2 additions & 0 deletions app/models/recipe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ class Recipe < ApplicationRecord

has_many :recipe_foods
has_many :foods, through: :recipe_foods, dependent: :destroy

validates :name, :preparation_time, :cooking_time, :description, presence: true
end
2 changes: 2 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ class User < ApplicationRecord

has_many :foods
has_many :recipes

validates :name, :email, :password, presence: true
end
1 change: 1 addition & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,6 @@ class Application < Rails::Application
#
# config.time_zone = "Central Time (US & Canada)"
# config.eager_load_paths << Rails.root.join("extras")
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
end
end
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
end

resources :general_shopping_lists, only: [:index]

get 'users', to: 'users#index'

resources :public_recipes

Expand Down
13 changes: 13 additions & 0 deletions spec/models/recipe_food_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'rails_helper'

RSpec.describe RecipeFood, type: :model do
describe 'associations' do
it 'should belong to a recipe' do
expect(RecipeFood.reflect_on_association(:recipe).macro).to eq(:belongs_to)
end

it 'should belong to a food' do
expect(RecipeFood.reflect_on_association(:food).macro).to eq(:belongs_to)
end
end
end
55 changes: 55 additions & 0 deletions spec/models/recipe_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
require 'rails_helper'

RSpec.describe Recipe, type: :model do
describe 'associations' do
it 'should have many foods' do
expect(Recipe.reflect_on_association(:foods).macro).to eq(:has_many)
end

it 'should have many recipe_foods' do
expect(Recipe.reflect_on_association(:recipe_foods).macro).to eq(:has_many)
end

it 'should belong to a user' do
expect(Recipe.reflect_on_association(:user).macro).to eq(:belongs_to)
end
end

describe 'validations' do
let(:user) { User.create(name: 'test', email: 'test@test.com', password: 'password') }

let(:recipe) do
Recipe.create(name: 'recipe', preparation_time: 10, cooking_time: 20, description: 'my recipe', public: false,
user_id: user.id)
end

it 'is valid with valid attributes' do
expect(recipe).to be_valid
end

it 'should validate presence of name' do
recipe.name = nil
expect(recipe).not_to be_valid
end

it 'should validate presence of preparation_time' do
recipe.preparation_time = nil
expect(recipe).not_to be_valid
end

it 'should validate presence of cooking_time' do
recipe.cooking_time = nil
expect(recipe).not_to be_valid
end

it 'should validate presence of description' do
recipe.description = nil
expect(recipe).not_to be_valid
end

it 'should validate presence of user_id' do
recipe.user_id = nil
expect(recipe).not_to be_valid
end
end
end
41 changes: 41 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'rails_helper'

RSpec.describe User, type: :model do
describe 'validations' do
let(:user) { User.create(name: 'test', email: 'test@test.com', password: 'password') }

it 'is valid with valid attributes' do
expect(user).to be_valid
end

it 'is not valid without a name' do
user.name = nil
expect(user).to_not be_valid
end

it 'is not valid without an email' do
user.email = nil
expect(user).to_not be_valid
end

it 'is not valid without a password' do
user.password = nil
expect(user).to_not be_valid
end

it 'is not valid with a password shorter than 6 characters' do
user.password = 'short'
expect(user).to_not be_valid
end
end

describe 'associations' do
it 'should have many foods' do
expect(User.reflect_on_association(:foods).macro).to eq(:has_many)
end

it 'should have many recipes' do
expect(User.reflect_on_association(:recipes).macro).to eq(:has_many)
end
end
end
65 changes: 65 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
# Prevent database truncation if the environment is production
abort('The Rails environment is running in production mode!') if Rails.env.production?
require 'rspec/rails'
# Add additional requires below this line. Rails is not loaded until this point!

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
# run as spec files by default. This means that files in spec/support that end
# in _spec.rb will both be required and run as specs, causing the specs to be
# run twice. It is recommended that you do not name files matching this glob to
# end with _spec.rb. You can configure this pattern with the --pattern
# option on the command line or in ~/.rspec, .rspec or `.rspec-local`.
#
# The following line is provided for convenience purposes. It has the downside
# of increasing the boot-up time by auto-requiring all files in the support
# directory. Alternatively, in the individual `*_spec.rb` files, manually
# require only the support files necessary.
#
# Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }

# Checks for pending migrations and applies them before tests are run.
# If you are not using ActiveRecord, you can remove these lines.
begin
ActiveRecord::Migration.maintain_test_schema!
rescue ActiveRecord::PendingMigrationError => e
abort e.to_s.strip
end
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_path = "#{Rails.root}/spec/fixtures"

# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
config.use_transactional_fixtures = true

# You can uncomment this line to turn off ActiveRecord support entirely.
# config.use_active_record = false

# RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and
# `post` in specs under `spec/controllers`.
#
# You can disable this behaviour by removing the line below, and instead
# explicitly tag your specs with their type, e.g.:
#
# RSpec.describe UsersController, type: :controller do
# # ...
# end
#
# The different available types are documented in the features, such as in
# https://rspec.info/features/6-0/rspec-rails
config.infer_spec_type_from_file_location!

# Filter lines from Rails gems in backtraces.
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.include Devise::Test::IntegrationHelpers, type: :request
config.include Devise::Test::IntegrationHelpers, type: :feature
end
37 changes: 37 additions & 0 deletions spec/requests/general_shopping_lists_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
require 'rails_helper'

RSpec.describe GeneralShoppingListsController, type: :request do
let(:user) { User.new(name: 'test', email: 'test@test.com', password: 'password') }
let(:recipe) do
Recipe.new(name: 'recipe', preparation_time: 10, cooking_time: 20, description: 'my recipe', public: false,
user_id: user.id)
end
let(:food) { Food.new(name: 'food', measurement_unit: 'units', price: 10, quantity: 10, user_id: user.id) }

before do
user.skip_confirmation!
user.save
recipe.save
food.save
end

def authenticate_user(user)
post user_session_path, params: { user: { email: user.email, password: user.password, name: user.name } }
follow_redirect!
end

describe 'GET #index' do
let(:general_shopping_list) { [{ food_id: food.id, name: food.name, price: food.price, quantity: food.quantity }] }

it 'returns a success response if user is authenticated' do
authenticate_user(user)
get general_shopping_lists_path

expect(response).to have_http_status(:ok)
expect(assigns(:user)).to eq(user)
expect(assigns(:general_shopping_list)).to eq(general_shopping_list)
expect(assigns(:total_food_items)).to eq(food.quantity)
expect(assigns(:total_price)).to eq(food.price * food.quantity)
end
end
end
Loading

0 comments on commit 3e9e34d

Please sign in to comment.