phase002 complete

This commit is contained in:
2026-09-15 20:28:07 -06:00
parent 9793cd08bc
commit a3a65c24ed
28 changed files with 656 additions and 13 deletions
+38
View File
@@ -0,0 +1,38 @@
require "rails_helper"
RSpec.describe FuelEntry do
it "has a valid factory" do
expect(build(:fuel_entry)).to be_valid
end
it "requires all fields" do
entry = build(
:fuel_entry,
vehicle: nil,
updated_by_user: nil,
odometer: nil,
gallons_pumped: nil,
price_paid: nil,
date: nil
)
expect(entry).not_to be_valid
expect(entry.errors.attribute_names).to include(:vehicle, :updated_by_user, :odometer, :gallons_pumped, :price_paid, :date)
end
it "requires valid numeric values" do
entry = build(:fuel_entry, odometer: -1, gallons_pumped: 0, price_paid: 0)
expect(entry).not_to be_valid
expect(entry.errors[:odometer]).to be_present
expect(entry.errors[:gallons_pumped]).to be_present
expect(entry.errors[:price_paid]).to be_present
end
it "rejects future dates" do
entry = build(:fuel_entry, date: Date.current + 1.day)
expect(entry).not_to be_valid
expect(entry.errors[:date]).to be_present
end
end
+53
View File
@@ -0,0 +1,53 @@
require "rails_helper"
RSpec.describe MaintenanceEntry do
it "has a valid factory" do
expect(build(:maintenance_entry)).to be_valid
end
it "requires all fields" do
entry = build(
:maintenance_entry,
vehicle: nil,
updated_by_user: nil,
name: nil,
notes: nil,
odometer: nil,
cost: nil,
date: nil,
ensure_matching_schedule: false
)
expect(entry).not_to be_valid
expect(entry.errors.attribute_names).to include(:vehicle, :updated_by_user, :name, :notes, :odometer, :cost, :date)
end
it "requires valid numeric values and allows zero cost" do
invalid_entry = build(:maintenance_entry, odometer: -1, cost: -1)
no_cost_entry = build(:maintenance_entry, cost: 0)
expect(invalid_entry).not_to be_valid
expect(invalid_entry.errors[:odometer]).to be_present
expect(invalid_entry.errors[:cost]).to be_present
expect(no_cost_entry).to be_valid
end
it "rejects future dates" do
entry = build(:maintenance_entry, date: Date.current + 1.day)
expect(entry).not_to be_valid
expect(entry.errors[:date]).to be_present
end
it "requires name to match a vehicle maintenance schedule case-insensitively" do
vehicle = create(:vehicle)
create(:maintenance_schedule, vehicle: vehicle, maintenance_type: "Oil Change")
matching_entry = build(:maintenance_entry, vehicle: vehicle, name: "oil change")
unknown_entry = build(:maintenance_entry, vehicle: vehicle, name: "Tire Rotation", ensure_matching_schedule: false)
expect(matching_entry).to be_valid
expect(unknown_entry).not_to be_valid
expect(unknown_entry.errors[:name]).to be_present
end
end
+34
View File
@@ -0,0 +1,34 @@
require "rails_helper"
RSpec.describe MaintenanceSchedule do
it "has a valid factory" do
expect(build(:maintenance_schedule)).to be_valid
end
it "requires all fields" do
schedule = build(:maintenance_schedule, vehicle: nil, maintenance_type: nil, mileage_interval: nil, time_interval: nil)
expect(schedule).not_to be_valid
expect(schedule.errors.attribute_names).to include(:vehicle, :maintenance_type, :mileage_interval, :time_interval)
end
it "requires positive integer intervals" do
schedule = build(:maintenance_schedule, mileage_interval: 0, time_interval: 0)
expect(schedule).not_to be_valid
expect(schedule.errors[:mileage_interval]).to be_present
expect(schedule.errors[:time_interval]).to be_present
end
it "requires maintenance type to be unique per vehicle case-insensitively" do
vehicle = create(:vehicle)
create(:maintenance_schedule, vehicle: vehicle, maintenance_type: "Oil Change")
duplicate = build(:maintenance_schedule, vehicle: vehicle, maintenance_type: "oil change")
other_vehicle_schedule = build(:maintenance_schedule, maintenance_type: "oil change")
expect(duplicate).not_to be_valid
expect(duplicate.errors[:maintenance_type]).to be_present
expect(other_vehicle_schedule).to be_valid
end
end
+32
View File
@@ -0,0 +1,32 @@
require "rails_helper"
RSpec.describe User do
it "has a valid factory" do
expect(build(:user)).to be_valid
end
it "requires a name and email" do
user = build(:user, name: nil, email: nil)
expect(user).not_to be_valid
expect(user.errors[:name]).to be_present
expect(user.errors[:email]).to be_present
end
it "requires email to be unique case-insensitively" do
create(:user, email: "driver@example.com")
user = build(:user, email: "DRIVER@example.com")
expect(user).not_to be_valid
expect(user.errors[:email]).to be_present
end
it "cannot be destroyed when entries reference it" do
user = create(:user)
create(:fuel_entry, updated_by_user: user)
expect(user.destroy).to be(false)
expect(user.errors[:base]).to be_present
end
end
+89
View File
@@ -0,0 +1,89 @@
require "rails_helper"
RSpec.describe Vehicle do
it "has a valid factory" do
expect(build(:vehicle)).to be_valid
end
it "defaults to active" do
expect(described_class.new.active).to be(true)
end
it "requires all fields" do
vehicle = build(
:vehicle,
make: nil,
model: nil,
year: nil,
color: nil,
vin: nil,
licence_plate: nil,
current_odometer: nil,
fuel_tank_size: nil,
active: nil
)
expect(vehicle).not_to be_valid
expect(vehicle.errors.attribute_names).to include(
:make,
:model,
:year,
:color,
:vin,
:licence_plate,
:current_odometer,
:fuel_tank_size,
:active
)
end
it "normalizes VIN to uppercase" do
vehicle = build(:vehicle, vin: "abc123")
vehicle.valid?
expect(vehicle.vin).to eq("ABC123")
end
it "requires VIN to be unique after normalization" do
create(:vehicle, vin: "ABC123")
vehicle = build(:vehicle, vin: "abc123")
expect(vehicle).not_to be_valid
expect(vehicle.errors[:vin]).to be_present
end
it "requires licence plate to be unique case-insensitively" do
create(:vehicle, licence_plate: "ABC123")
vehicle = build(:vehicle, licence_plate: "abc123")
expect(vehicle).not_to be_valid
expect(vehicle.errors[:licence_plate]).to be_present
end
it "requires a realistic year" do
too_old = build(:vehicle, year: 1979)
future = build(:vehicle, year: Date.current.year + 1)
expect(too_old).not_to be_valid
expect(future).not_to be_valid
end
it "requires numeric mileage and fuel tank values" do
vehicle = build(:vehicle, current_odometer: -1, fuel_tank_size: 0)
expect(vehicle).not_to be_valid
expect(vehicle.errors[:current_odometer]).to be_present
expect(vehicle.errors[:fuel_tank_size]).to be_present
end
it "cannot be destroyed when entries reference it" do
vehicle = create(:vehicle)
create(:maintenance_schedule, vehicle: vehicle)
expect(vehicle.destroy).to be(false)
expect(vehicle.errors[:base]).to be_present
end
end