From 65bd580d420576626b1794ee9c3ba565f8506d65 Mon Sep 17 00:00:00 2001 From: Azuna <36605286+azunaVT@users.noreply.github.com> Date: Thu, 8 Jan 2026 06:09:18 +0000 Subject: [PATCH 1/2] Added user model, simple tests and db migration --- Gemfile | 6 ++- Gemfile.lock | 7 +-- Makefile | 4 +- app/models/user.rb | 5 +++ db/migrate/20260108050125_create_users.rb | 10 +++++ db/schema.rb | 9 +++- test/fixtures/users.yml | 9 ++++ test/models/user_test.rb | 55 +++++++++++++++++++++++ test/support/auth_constants.rb | 3 ++ test/test_helper.rb | 5 +++ 10 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 app/models/user.rb create mode 100644 db/migrate/20260108050125_create_users.rb create mode 100644 test/fixtures/users.yml create mode 100644 test/models/user_test.rb create mode 100644 test/support/auth_constants.rb diff --git a/Gemfile b/Gemfile index d641979..293e4ca 100644 --- a/Gemfile +++ b/Gemfile @@ -35,6 +35,9 @@ gem "thruster", require: false # Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin Ajax possible # gem "rack-cors" +# BCrypt for password hashing +gem "bcrypt", "~> 3.1" + group :development, :test do # See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem gem "debug", platforms: %i[ mri windows ], require: "debug/prelude" @@ -43,7 +46,8 @@ group :development, :test do gem "brakeman", require: false # Testing Framework - gem "minitest", "~> 6.0" + # Minitest 6.0+ is having some issues with how tests are currently written + gem "minitest", "~> 5.0" gem "minitest-reporters" # Omakase Ruby styling [https://github.com/rails/rubocop-rails-omakase/] diff --git a/Gemfile.lock b/Gemfile.lock index 681bf19..6fed48a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -78,6 +78,7 @@ GEM ansi (1.5.0) ast (2.4.3) base64 (0.3.0) + bcrypt (3.1.21) bcrypt_pbkdf (1.1.2) bigdecimal (4.0.1) bootsnap (1.20.1) @@ -137,8 +138,7 @@ GEM net-smtp marcel (1.1.0) mini_mime (1.1.5) - minitest (6.0.1) - prism (~> 1.5) + minitest (5.27.0) minitest-reporters (1.7.1) ansi builder @@ -323,11 +323,12 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + bcrypt (~> 3.1) bootsnap brakeman debug kamal - minitest (~> 6.0) + minitest (~> 5.0) minitest-reporters pg (~> 1.6) puma (>= 5.0) diff --git a/Makefile b/Makefile index 781cb53..61fdaf6 100644 --- a/Makefile +++ b/Makefile @@ -6,5 +6,7 @@ logs: @docker-compose -f docker-compose.yml logs -f build: @docker build --build-arg RAILS_MASTER_KEY=$(cat config/master.key) -f Dockerfile -t simplesave-api:latest . +test: + @rails test run: - @rails s \ No newline at end of file + @rails server -b \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..527cea1 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,5 @@ +class User < ApplicationRecord + has_secure_password + + validates :email, presence: true, uniqueness: true +end diff --git a/db/migrate/20260108050125_create_users.rb b/db/migrate/20260108050125_create_users.rb new file mode 100644 index 0000000..10a5684 --- /dev/null +++ b/db/migrate/20260108050125_create_users.rb @@ -0,0 +1,10 @@ +class CreateUsers < ActiveRecord::Migration[8.1] + def change + create_table :users do |t| + t.string :email, null: false, index: { unique: true } + t.string :password_digest, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index f8be1d3..848d591 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,8 +10,15 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.1].define(version: 0) do +ActiveRecord::Schema[8.1].define(version: 2026_01_08_050125) do # These are extensions that must be enabled in order to support this database enable_extension "pg_catalog.plpgsql" + create_table "users", force: :cascade do |t| + t.datetime "created_at", null: false + t.string "email", null: false + t.string "password_digest", null: false + t.datetime "updated_at", null: false + t.index ["email"], name: "index_users_on_email", unique: true + end end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..574ff5e --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +alice: + email: alice@example.com + password_digest: <%= BCrypt::Password.create(TestCredentials::DEFAULT_PASSWORD) %> + +bob: + email: bob@example.com + password_digest: <%= BCrypt::Password.create(TestCredentials::DEFAULT_PASSWORD) %> \ No newline at end of file diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..6927227 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,55 @@ +require "test_helper" + +class UserTest < ActiveSupport::TestCase + test "is valid with email and password" do + user = User.new( + email: "newuser@example.com", + password: TestCredentials::DEFAULT_PASSWORD, + password_confirmation: TestCredentials::DEFAULT_PASSWORD + ) + + assert user.valid? + end + + test "is invalid without email" do + user = User.new( + password: TestCredentials::DEFAULT_PASSWORD, + password_confirmation: TestCredentials::DEFAULT_PASSWORD + ) + + assert_not user.valid? + assert_includes user.errors[:email], "can't be blank" + end + + test "is invalid without password" do + user = User.new(email: "nopassword@example.com") + + assert_not user.valid? + assert_includes user.errors[:password], "can't be blank" + end + + test "email must be unique" do + existing_user = users(:alice) + + duplicate = User.new( + email: existing_user.email, + password: TestCredentials::DEFAULT_PASSWORD, + password_confirmation: TestCredentials::DEFAULT_PASSWORD + ) + + assert_not duplicate.valid? + assert_includes duplicate.errors[:email], "has already been taken" + end + + test "authenticates with correct password" do + user = users(:alice) + + assert user.authenticate(TestCredentials::DEFAULT_PASSWORD) + end + + test "does not authenticate with incorrect password" do + user = users(:alice) + + assert_not user.authenticate("wrong-password") + end +end diff --git a/test/support/auth_constants.rb b/test/support/auth_constants.rb new file mode 100644 index 0000000..f8cdeba --- /dev/null +++ b/test/support/auth_constants.rb @@ -0,0 +1,3 @@ +module TestCredentials + DEFAULT_PASSWORD = "password123" +end diff --git a/test/test_helper.rb b/test/test_helper.rb index 90dbd23..b18c239 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -5,6 +5,11 @@ require "minitest/reporters" Minitest::Reporters.use! Minitest::Reporters::SpecReporter.new +require "bcrypt" + +# Load support file: +Dir[Rails.root.join("test/support/**/*.rb")].each { |f| require f } + module ActiveSupport class TestCase # Run tests in parallel with specified workers From 0f72eac2e67806f13de29335329c6d131c4f4ee2 Mon Sep 17 00:00:00 2001 From: Azuna <36605286+azunaVT@users.noreply.github.com> Date: Thu, 8 Jan 2026 06:14:19 +0000 Subject: [PATCH 2/2] Updating Makefile to fix the problems introduced by previous commit --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 61fdaf6..256861f 100644 --- a/Makefile +++ b/Makefile @@ -1,3 +1,4 @@ +.PHONY: up down logs build test run up: @docker-compose -f docker-compose.yml up -d down: @@ -9,4 +10,4 @@ build: test: @rails test run: - @rails server -b \ No newline at end of file + @rails server \ No newline at end of file