Skip to content

Commit

Permalink
Merge pull request #6 from ab-noori/unit-integration-tests
Browse files Browse the repository at this point in the history
Unit and integration tests
  • Loading branch information
ab-noori committed Sep 23, 2023
2 parents 722d66f + b1d4a5a commit 106e00a
Show file tree
Hide file tree
Showing 18 changed files with 443 additions and 0 deletions.
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ gem 'bootsnap', require: false
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem 'debug', platforms: %i[mri mingw x64_mingw]
gem 'factory_bot_rails'
gem 'rspec-rails'
end

group :development do
Expand All @@ -73,5 +75,6 @@ end
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem 'capybara'
gem 'rails-controller-testing'
gem 'selenium-webdriver'
end
30 changes: 30 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,13 @@ GEM
railties (>= 4.1.0)
responders
warden (~> 1.2.3)
diff-lcs (1.5.0)
erubi (1.12.0)
factory_bot (6.2.1)
activesupport (>= 5.0.0)
factory_bot_rails (6.2.0)
factory_bot (~> 6.2.0)
railties (>= 5.0.0)
globalid (1.2.1)
activesupport (>= 6.1)
i18n (1.14.1)
Expand Down Expand Up @@ -168,6 +174,10 @@ GEM
activesupport (= 7.0.8)
bundler (>= 1.15.0)
railties (= 7.0.8)
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.2.0)
activesupport (>= 5.0.0)
minitest
Expand All @@ -193,6 +203,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.56.3)
base64 (~> 0.1.1)
json (~> 2.3)
Expand Down Expand Up @@ -257,11 +284,14 @@ DEPENDENCIES
capybara
debug
devise
factory_bot_rails
importmap-rails
jbuilder
pg (~> 1.1)
puma (~> 5.0)
rails (~> 7.0.8)
rails-controller-testing
rspec-rails
rubocop (>= 1.0, < 2.0)
selenium-webdriver
sprockets-rails
Expand Down
2 changes: 2 additions & 0 deletions app/models/category.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ class Category < ApplicationRecord
has_many :expense_category_associations
has_one_attached :icon, dependent: :destroy
has_many :expenses, through: :expense_category_associations

validates :name, presence: true
end
3 changes: 3 additions & 0 deletions app/models/expense.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ class Expense < ApplicationRecord
belongs_to :user
has_many :expense_category_associations
has_many :categories, through: :expense_category_associations

validates :name, presence: true
validates :amount, presence: true, numericality: { greater_than: 0 }
end
8 changes: 8 additions & 0 deletions spec/factories/categories.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# spec/factories/categories.rb

FactoryBot.define do
factory :category, class: Category do
name { 'Sample Category' }
association :user, factory: :user
end
end
9 changes: 9 additions & 0 deletions spec/factories/expenses.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# spec/factories/expenses.rb

FactoryBot.define do
factory :expense, class: Expense do
name { 'Sample Expense' }
amount { 50.0 }
association :user, factory: :user
end
end
10 changes: 10 additions & 0 deletions spec/factories/users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# In spec/factories/users.rb

FactoryBot.define do
factory :user do
email { '[email protected]' }
password { 'password' }
name { 'Example User' }
role { 'User' }
end
end
28 changes: 28 additions & 0 deletions spec/models/category_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'rails_helper'

RSpec.describe Category, type: :model do
context 'validations' do
it 'is valid with a name' do
category = FactoryBot.create(:category)
expect(category).to be_valid
end

it 'is invalid without a name' do
category = Category.new
expect(category).to_not be_valid
expect(category.errors[:name]).to include("can't be blank")
end
end

context 'associations' do
it 'belongs to a user' do
association = Category.reflect_on_association(:user)
expect(association.macro).to eq(:belongs_to)
end

it 'has many expenses' do
association = Category.reflect_on_association(:expenses)
expect(association.macro).to eq(:has_many)
end
end
end
31 changes: 31 additions & 0 deletions spec/models/expense_category_association_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# spec/models/expense_category_association_spec.rb

require 'rails_helper'

RSpec.describe ExpenseCategoryAssociation, type: :model do
describe 'associations' do
it 'belongs to an expense' do
association = described_class.reflect_on_association(:expense)
expect(association.macro).to eq :belongs_to
end

it 'belongs to a category' do
association = described_class.reflect_on_association(:category)
expect(association.macro).to eq :belongs_to
end
end

describe 'validations' do
it 'is not valid without an expense' do
category = FactoryBot.create(:category)
association = ExpenseCategoryAssociation.new(category:)
expect(association).to_not be_valid
end

it 'is not valid without a category' do
expense = FactoryBot.create(:expense)
association = ExpenseCategoryAssociation.new(expense:)
expect(association).to_not be_valid
end
end
end
41 changes: 41 additions & 0 deletions spec/models/expense_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
require 'rails_helper'

RSpec.describe Expense, type: :model do
describe 'validations' do
it 'is valid with valid attributes' do
user = FactoryBot.create(:user)
expense = Expense.new(name: 'Groceries', amount: 50.0, user:)
expect(expense).to be_valid
end

it 'is not valid without a name' do
user = FactoryBot.create(:user)
expense = Expense.new(amount: 50.0, user:)
expect(expense).to_not be_valid
end

it 'is not valid without an amount' do
user = FactoryBot.create(:user)
expense = Expense.new(name: 'Groceries', user:)
expect(expense).to_not be_valid
end

it 'is not valid with a non-positive amount' do
user = FactoryBot.create(:user)
expense = Expense.new(name: 'Groceries', amount: -10.0, user:)
expect(expense).to_not be_valid
end
end

describe 'associations' do
it 'belongs to a user' do
association = described_class.reflect_on_association(:user)
expect(association.macro).to eq :belongs_to
end

it 'has many expense category associations' do
association = described_class.reflect_on_association(:expense_category_associations)
expect(association.macro).to eq :has_many
end
end
end
24 changes: 24 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require 'rails_helper'

RSpec.describe User, type: :model do
# Test 1: Validation - User is valid with valid attributes
it 'is valid with valid attributes' do
user = FactoryBot.build(:user, name: 'exampleuser', email: '[email protected]', password: 'password')
expect(user).to be_valid
end

# Test 2: Validation - User is not valid without a username
it 'is not valid without a username' do
user = FactoryBot.build(:user, name: nil, email: '[email protected]', password: 'password')
expect(user).to_not be_valid
end

# Test 3: Association - User has many categories
it 'has many categories' do
user = FactoryBot.create(:user)
category1 = FactoryBot.create(:category, user:)
category2 = FactoryBot.create(:category, user:)

expect(user.categories).to include(category1, category2)
end
end
70 changes: 70 additions & 0 deletions spec/rails_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# 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.

require 'devise'
require 'factory_bot_rails'

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

config.include Devise::Test::IntegrationHelpers, type: :request
config.include FactoryBot::Syntax::Methods

# 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")
end
38 changes: 38 additions & 0 deletions spec/requests/categories_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
require 'rails_helper'

RSpec.describe 'Categories', type: :request do
let(:user) { create(:user) } # Create a user using FactoryBot

before do
sign_in user # Assuming you have a sign_in helper method for Devise
end

describe 'GET /categories' do
it 'displays the categories index page' do
get categories_path
expect(response).to have_http_status(200)
expect(response).to render_template(:index)
end
end

describe 'GET /categories/new' do
it 'displays the new category form' do
get new_category_path
expect(response).to have_http_status(200)
expect(response).to render_template(:new)
end
end

describe 'POST /categories' do
it 'creates a new category' do
category_attributes = attributes_for(:category, user:)

expect do
post categories_path, params: { category: category_attributes }
end.to change(Category, :count).by(1)

expect(response).to have_http_status(302)
expect(response).to redirect_to(categories_path)
end
end
end
27 changes: 27 additions & 0 deletions spec/requests/expenses_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
require 'rails_helper'

RSpec.describe ExpensesController, type: :request do
let(:user) { create(:user) }
let(:category) { create(:category, user:) }

before do
sign_in user
end

describe 'GET /new' do
it 'returns a successful response' do
get new_category_expense_path(category)
expect(response).to be_successful
end

it "renders the 'new' template" do
get new_category_expense_path(category)
expect(response).to render_template(:new)
end

it 'assigns a new expense' do
get new_category_expense_path(category)
expect(assigns(:expense)).to be_a_new(Expense)
end
end
end
Loading

0 comments on commit 106e00a

Please sign in to comment.