diff --git a/.gitignore b/.gitignore index f92525c..e5c9b58 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ # Ignore master key for decrypting credentials and more. /config/master.key + +# Ignore DS Store +*.DS_Store \ No newline at end of file diff --git a/Gemfile b/Gemfile index e0f49f7..8221f34 100644 --- a/Gemfile +++ b/Gemfile @@ -18,7 +18,7 @@ gem "stimulus-rails" gem "jbuilder" # Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword] -# gem "bcrypt", "~> 3.1.7" +gem "bcrypt", "~> 3.1.7" # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[ windows jruby ] diff --git a/Gemfile.lock b/Gemfile.lock index be1a5d0..092b1d3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,11 +76,12 @@ GEM public_suffix (>= 2.0.2, < 7.0) ast (2.4.3) base64 (0.2.0) + bcrypt (3.1.20) bcrypt_pbkdf (1.1.1) benchmark (0.4.0) bigdecimal (3.1.9) bindex (0.8.1) - bootsnap (1.18.4) + bootsnap (1.18.6) msgpack (~> 1.2) brakeman (7.0.2) racc @@ -127,13 +128,13 @@ GEM actionview (>= 5.0.0) activesupport (>= 5.0.0) json (2.11.3) - kamal (2.5.3) + kamal (2.6.1) activesupport (>= 7.0) base64 (~> 0.2) bcrypt_pbkdf (~> 1.0) concurrent-ruby (~> 1.2) dotenv (~> 3.1) - ed25519 (~> 1.2) + ed25519 (~> 1.4) net-ssh (~> 7.3) sshkit (>= 1.23.0, < 2.0) thor (~> 1.3) @@ -141,7 +142,7 @@ GEM language_server-protocol (3.17.0.4) lint_roller (1.1.0) logger (1.7.0) - loofah (2.24.0) + loofah (2.24.1) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -197,7 +198,7 @@ GEM activesupport (>= 7.0.0) rack railties (>= 7.0.0) - psych (5.2.4) + psych (5.2.6) date stringio public_suffix (6.0.2) @@ -205,8 +206,8 @@ GEM nio4r (~> 2.0) raabro (1.4.0) racc (1.8.1) - rack (3.1.13) - rack-session (2.1.0) + rack (3.1.14) + rack-session (2.1.1) base64 (>= 0.1.0) rack (>= 3.0.0) rack-test (2.2.0) @@ -287,7 +288,7 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) - solid_cable (3.0.7) + solid_cable (3.0.8) actioncable (>= 7.2) activejob (>= 7.2) activerecord (>= 7.2) @@ -363,6 +364,7 @@ PLATFORMS x86_64-linux-musl DEPENDENCIES + bcrypt (~> 3.1.7) bootsnap brakeman capybara diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 0d95db2..6c9b518 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,4 +1,14 @@ class ApplicationController < ActionController::Base # Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has. allow_browser versions: :modern + + def logged_in? + if session[:user_id] then true else false end + end + + def current_user + if logged_in? + session[:user_id] + end + end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb new file mode 100644 index 0000000..c21b297 --- /dev/null +++ b/app/controllers/sessions_controller.rb @@ -0,0 +1,21 @@ +class SessionsController < ApplicationController + def new + end + + def create + user = User.find_by(email: params[:email]) + + if user && user.authenticate(params[:password]) + session[:user_id] = user.id + redirect_to root_path, notice: "Logged in!" + else + flash.now[:alert] = "Invalid email or password" + render :new, status: :unprocessable_entity + end + end + + def destroy + session[:user_id] = nil + redirect_to root_path + end +end diff --git a/app/controllers/test/images_controller.rb b/app/controllers/test/images_controller.rb new file mode 100644 index 0000000..aebeba8 --- /dev/null +++ b/app/controllers/test/images_controller.rb @@ -0,0 +1,25 @@ +class Test::ImagesController < ApplicationController + def index + @images = Image.all + @image = Image.new + end + + def create + @image = Image.new(image_params) + + if @image.save + respond_to do |format| + format.turbo_stream + format.html { redirect_to test_images_path } + end + else + render :index, status: :unprocessable_entity + end + end + + private + + def image_params + params.require(:image).permit(:title, :file) + end +end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb new file mode 100644 index 0000000..4f43771 --- /dev/null +++ b/app/controllers/users_controller.rb @@ -0,0 +1,16 @@ +class UsersController < ApplicationController + def new + end + + def create + end + + def edit + end + + def update + end + + def destroy + end +end diff --git a/app/helpers/sessions_helper.rb b/app/helpers/sessions_helper.rb new file mode 100644 index 0000000..309f8b2 --- /dev/null +++ b/app/helpers/sessions_helper.rb @@ -0,0 +1,2 @@ +module SessionsHelper +end diff --git a/app/helpers/test/images_helper.rb b/app/helpers/test/images_helper.rb new file mode 100644 index 0000000..53c4ea6 --- /dev/null +++ b/app/helpers/test/images_helper.rb @@ -0,0 +1,2 @@ +module Test::ImagesHelper +end diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb new file mode 100644 index 0000000..2310a24 --- /dev/null +++ b/app/helpers/users_helper.rb @@ -0,0 +1,2 @@ +module UsersHelper +end diff --git a/app/models/image.rb b/app/models/image.rb new file mode 100644 index 0000000..6443fa1 --- /dev/null +++ b/app/models/image.rb @@ -0,0 +1,8 @@ +class Image < ApplicationRecord + has_one_attached :file + + has_many :taggings, as: :taggable + has_many :tags, through: :taggings + + validates :title, :file, presence: true +end diff --git a/app/models/post.rb b/app/models/post.rb new file mode 100644 index 0000000..80800c8 --- /dev/null +++ b/app/models/post.rb @@ -0,0 +1,6 @@ +class Post < ApplicationRecord + belongs_to :user + belongs_to :image + has_many :taggings, as: :taggable + has_many :tags, through: :taggings +end diff --git a/app/models/tag.rb b/app/models/tag.rb new file mode 100644 index 0000000..c4d1c12 --- /dev/null +++ b/app/models/tag.rb @@ -0,0 +1,5 @@ +class Tag < ApplicationRecord + has_many :taggings + has_many :posts, through: :taggings, source: :taggable, source_type: "Post" + has_many :images, through: :taggings, source: :taggable, source_type: "Image" +end diff --git a/app/models/tagging.rb b/app/models/tagging.rb new file mode 100644 index 0000000..e608dcd --- /dev/null +++ b/app/models/tagging.rb @@ -0,0 +1,4 @@ +class Tagging < ApplicationRecord + belongs_to :tag + belongs_to :taggable, polymorphic: true +end diff --git a/app/models/user.rb b/app/models/user.rb new file mode 100644 index 0000000..15bd0f0 --- /dev/null +++ b/app/models/user.rb @@ -0,0 +1,6 @@ +class User < ApplicationRecord + has_secure_password + has_many :posts + + validates :name, :status, :email, :password_digest, presence: true +end diff --git a/app/views/sessions/destroy.html.erb b/app/views/sessions/destroy.html.erb new file mode 100644 index 0000000..d75237d --- /dev/null +++ b/app/views/sessions/destroy.html.erb @@ -0,0 +1,2 @@ +
Find me in app/views/sessions/destroy.html.erb
diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb new file mode 100644 index 0000000..b39a3bc --- /dev/null +++ b/app/views/sessions/new.html.erb @@ -0,0 +1,2 @@ +Find me in app/views/sessions/new.html.erb
diff --git a/app/views/test/images/_image.html.erb b/app/views/test/images/_image.html.erb new file mode 100644 index 0000000..1ea09c3 --- /dev/null +++ b/app/views/test/images/_image.html.erb @@ -0,0 +1,6 @@ +Find me in app/views/users/create.html.erb
diff --git a/app/views/users/new.html.erb b/app/views/users/new.html.erb new file mode 100644 index 0000000..c21a1ad --- /dev/null +++ b/app/views/users/new.html.erb @@ -0,0 +1,2 @@ +Find me in app/views/users/new.html.erb
diff --git a/config/routes.rb b/config/routes.rb index 167b8ab..0dccbbf 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,12 @@ Rails.application.routes.draw do - resources :notes + resources :users, only: [ :new, :create, :edit, :update, :destroy ] + + resource :sessions, only: [ :new, :create, :destroy ] + + namespace :test do + resources :images, only: [ :index, :create ] + end + # Define your application routes per the DSL in https://guides.rubyonrails.org/routing.html # Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500. @@ -11,5 +18,5 @@ Rails.application.routes.draw do # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker # Defines the root path route ("/") - # root "posts#index" + root "images#index" end diff --git a/db/migrate/20250507082715_create_active_storage_tables.active_storage.rb b/db/migrate/20250507082715_create_active_storage_tables.active_storage.rb new file mode 100644 index 0000000..6bd8bd0 --- /dev/null +++ b/db/migrate/20250507082715_create_active_storage_tables.active_storage.rb @@ -0,0 +1,57 @@ +# This migration comes from active_storage (originally 20170806125915) +class CreateActiveStorageTables < ActiveRecord::Migration[7.0] + def change + # Use Active Record's configured type for primary and foreign keys + primary_key_type, foreign_key_type = primary_and_foreign_key_types + + create_table :active_storage_blobs, id: primary_key_type do |t| + t.string :key, null: false + t.string :filename, null: false + t.string :content_type + t.text :metadata + t.string :service_name, null: false + t.bigint :byte_size, null: false + t.string :checksum + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :key ], unique: true + end + + create_table :active_storage_attachments, id: primary_key_type do |t| + t.string :name, null: false + t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type + t.references :blob, null: false, type: foreign_key_type + + if connection.supports_datetime_with_precision? + t.datetime :created_at, precision: 6, null: false + else + t.datetime :created_at, null: false + end + + t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + + create_table :active_storage_variant_records, id: primary_key_type do |t| + t.belongs_to :blob, null: false, index: false, type: foreign_key_type + t.string :variation_digest, null: false + + t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + def primary_and_foreign_key_types + config = Rails.configuration.generators + setting = config.options[config.orm][:primary_key_type] + primary_key_type = setting || :primary_key + foreign_key_type = setting || :bigint + [ primary_key_type, foreign_key_type ] + end +end diff --git a/db/migrate/20250507082751_create_images.rb b/db/migrate/20250507082751_create_images.rb new file mode 100644 index 0000000..163e6d4 --- /dev/null +++ b/db/migrate/20250507082751_create_images.rb @@ -0,0 +1,9 @@ +class CreateImages < ActiveRecord::Migration[8.0] + def change + create_table :images do |t| + t.string :title + + t.timestamps + end + end +end diff --git a/db/migrate/20250508115812_create_users.rb b/db/migrate/20250508115812_create_users.rb new file mode 100644 index 0000000..1d931f3 --- /dev/null +++ b/db/migrate/20250508115812_create_users.rb @@ -0,0 +1,12 @@ +class CreateUsers < ActiveRecord::Migration[8.0] + def change + create_table :users do |t| + t.string :name + t.string :status + t.string :email + t.string :password_digest + + t.timestamps + end + end +end diff --git a/db/migrate/20250508131043_drop_notes_table.rb b/db/migrate/20250508131043_drop_notes_table.rb new file mode 100644 index 0000000..6bb7112 --- /dev/null +++ b/db/migrate/20250508131043_drop_notes_table.rb @@ -0,0 +1,5 @@ +class DropNotesTable < ActiveRecord::Migration[8.0] + def change + drop_table :notes + end +end diff --git a/db/migrate/20250515134517_create_posts.rb b/db/migrate/20250515134517_create_posts.rb new file mode 100644 index 0000000..a118eb8 --- /dev/null +++ b/db/migrate/20250515134517_create_posts.rb @@ -0,0 +1,14 @@ +class CreatePosts < ActiveRecord::Migration[8.0] + def change + create_table :posts do |t| + t.string :title + t.text :content + t.boolean :pinned + t.references :user, null: false, foreign_key: true + t.references :image, null: false, foreign_key: true + t.string :type + + t.timestamps + end + end +end diff --git a/db/migrate/20250515134851_create_tags.rb b/db/migrate/20250515134851_create_tags.rb new file mode 100644 index 0000000..391a7fc --- /dev/null +++ b/db/migrate/20250515134851_create_tags.rb @@ -0,0 +1,10 @@ +class CreateTags < ActiveRecord::Migration[8.0] + def change + create_table :tags do |t| + t.string :title + t.string :color + + t.timestamps + end + end +end diff --git a/db/migrate/20250515135623_create_taggings.rb b/db/migrate/20250515135623_create_taggings.rb new file mode 100644 index 0000000..505d687 --- /dev/null +++ b/db/migrate/20250515135623_create_taggings.rb @@ -0,0 +1,10 @@ +class CreateTaggings < ActiveRecord::Migration[8.0] + def change + create_table :taggings do |t| + t.references :tag, null: false, foreign_key: true + t.references :taggable, polymorphic: true, null: false + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index db88925..edbe99a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,11 +10,83 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[8.0].define(version: 2025_05_06_085403) do - create_table "notes", force: :cascade do |t| +ActiveRecord::Schema[8.0].define(version: 2025_05_15_135623) do + create_table "active_storage_attachments", force: :cascade do |t| + t.string "name", null: false + t.string "record_type", null: false + t.bigint "record_id", null: false + t.bigint "blob_id", null: false + t.datetime "created_at", null: false + t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id" + t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true + end + + create_table "active_storage_blobs", force: :cascade do |t| + t.string "key", null: false + t.string "filename", null: false + t.string "content_type" + t.text "metadata" + t.string "service_name", null: false + t.bigint "byte_size", null: false + t.string "checksum" + t.datetime "created_at", null: false + t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true + end + + create_table "active_storage_variant_records", force: :cascade do |t| + t.bigint "blob_id", null: false + t.string "variation_digest", null: false + t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true + end + + create_table "images", force: :cascade do |t| t.string "title" - t.text "body" t.datetime "created_at", null: false t.datetime "updated_at", null: false end + + create_table "posts", force: :cascade do |t| + t.string "title" + t.text "content" + t.boolean "pinned" + t.integer "user_id", null: false + t.integer "image_id", null: false + t.string "type" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["image_id"], name: "index_posts_on_image_id" + t.index ["user_id"], name: "index_posts_on_user_id" + end + + create_table "taggings", force: :cascade do |t| + t.integer "tag_id", null: false + t.string "taggable_type", null: false + t.integer "taggable_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["tag_id"], name: "index_taggings_on_tag_id" + t.index ["taggable_type", "taggable_id"], name: "index_taggings_on_taggable" + end + + create_table "tags", force: :cascade do |t| + t.string "title" + t.string "color" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "users", force: :cascade do |t| + t.string "name" + t.string "status" + t.string "email" + t.string "password_digest" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" + add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" + add_foreign_key "posts", "images" + add_foreign_key "posts", "users" + add_foreign_key "taggings", "tags" end diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb new file mode 100644 index 0000000..4c379c9 --- /dev/null +++ b/test/controllers/sessions_controller_test.rb @@ -0,0 +1,19 @@ +require "test_helper" + +class SessionsControllerTest < ActionDispatch::IntegrationTest + test "should get new" do + get new_sessions_path + assert_response :success + end + + test "should get create" do + post sessions_path, params: { email: "test@email.com", password: "testpassword" } + assert_redirected_to root_path + end + + test "should get destroy" do + post sessions_path, params: { email: "test@email.com", password: "testpassword" } + delete sessions_path + assert_redirected_to root_path + end +end diff --git a/test/controllers/test/images_controller_test.rb b/test/controllers/test/images_controller_test.rb new file mode 100644 index 0000000..9536bf7 --- /dev/null +++ b/test/controllers/test/images_controller_test.rb @@ -0,0 +1,21 @@ +require "test_helper" +include ActiveJob::TestHelper + +class Test::ImagesControllerTest < ActionDispatch::IntegrationTest + test "should get index" do + get test_images_path + assert_response :success + end + + test "should get create" do + file = fixture_file_upload("test_image.jpg", "image/jpeg") + post test_images_path, params: { image: { file: file, title: "test" } } + assert_redirected_to test_images_path + end + + teardown do + perform_enqueued_jobs do + ActiveStorage::Blob.all.each(&:purge_later) + end + end +end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb new file mode 100644 index 0000000..66cae48 --- /dev/null +++ b/test/controllers/users_controller_test.rb @@ -0,0 +1,38 @@ +require "test_helper" + +class UsersControllerTest < ActionDispatch::IntegrationTest + setup do + @user = users(:one) # Assuming you have a fixture or factory for @user + end + test "should get new" do + get new_user_path + assert_response :success + end + + test "should get create" do + post users_path + assert_response :success + + # post users_path, params: { user: { username: "testuser", password: "password123" } } + # assert_redirected_to user_path(User.last) + end + + test "should get edit" do + get edit_user_path(@user) + assert_response :success + end + + test "should get update" do + patch user_path(@user) + assert_response :success + + # Probably also assert a successful redirect later and push correct data params + end + + test "should get destroy" do + delete user_path(@user) + assert_response :success + + # Possibly this one too I suppose + end +end diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep index e69de29..6dadb36 100644 --- a/test/fixtures/files/.keep +++ b/test/fixtures/files/.keep @@ -0,0 +1 @@ +# Keep these, they're silly \ No newline at end of file diff --git a/test/fixtures/files/mermaid_template.png b/test/fixtures/files/mermaid_template.png new file mode 100644 index 0000000..6028901 Binary files /dev/null and b/test/fixtures/files/mermaid_template.png differ diff --git a/test/fixtures/files/test_image.jpg b/test/fixtures/files/test_image.jpg new file mode 100644 index 0000000..96e1de5 Binary files /dev/null and b/test/fixtures/files/test_image.jpg differ diff --git a/test/fixtures/notes.yml b/test/fixtures/images.yml similarity index 82% rename from test/fixtures/notes.yml rename to test/fixtures/images.yml index 6028a9c..64d88ef 100644 --- a/test/fixtures/notes.yml +++ b/test/fixtures/images.yml @@ -2,8 +2,6 @@ one: title: MyString - body: MyText two: title: MyString - body: MyText diff --git a/test/fixtures/posts.yml b/test/fixtures/posts.yml new file mode 100644 index 0000000..7f12185 --- /dev/null +++ b/test/fixtures/posts.yml @@ -0,0 +1,17 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + content: MyText + pinned: false + user: one + image: one + type: + +two: + title: MyString + content: MyText + pinned: false + user: two + image: two + type: diff --git a/test/fixtures/taggings.yml b/test/fixtures/taggings.yml new file mode 100644 index 0000000..b8346f1 --- /dev/null +++ b/test/fixtures/taggings.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + tag: one + taggable: one + taggable_type: Taggable + +two: + tag: two + taggable: two + taggable_type: Taggable diff --git a/test/fixtures/tags.yml b/test/fixtures/tags.yml new file mode 100644 index 0000000..73a1e08 --- /dev/null +++ b/test/fixtures/tags.yml @@ -0,0 +1,9 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + color: MyString + +two: + title: MyString + color: MyString diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml new file mode 100644 index 0000000..687c436 --- /dev/null +++ b/test/fixtures/users.yml @@ -0,0 +1,13 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: testuser + status: test + email: test@email.com + password_digest: <%= BCrypt::Password.create('testpassword') %> + +two: + name: testuser2 + status: dead + email: tester2@email.com + password_digest: <%= BCrypt::Password.create('tpass2') %> \ No newline at end of file diff --git a/test/models/image_test.rb b/test/models/image_test.rb new file mode 100644 index 0000000..8650df9 --- /dev/null +++ b/test/models/image_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class ImageTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/note_test.rb b/test/models/post_test.rb similarity index 65% rename from test/models/note_test.rb rename to test/models/post_test.rb index a7cec16..ff155c4 100644 --- a/test/models/note_test.rb +++ b/test/models/post_test.rb @@ -1,6 +1,6 @@ require "test_helper" -class NoteTest < ActiveSupport::TestCase +class PostTest < ActiveSupport::TestCase # test "the truth" do # assert true # end diff --git a/test/models/tag_test.rb b/test/models/tag_test.rb new file mode 100644 index 0000000..1846cdb --- /dev/null +++ b/test/models/tag_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TagTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/tagging_test.rb b/test/models/tagging_test.rb new file mode 100644 index 0000000..cb5040f --- /dev/null +++ b/test/models/tagging_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class TaggingTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/user_test.rb b/test/models/user_test.rb new file mode 100644 index 0000000..5c07f49 --- /dev/null +++ b/test/models/user_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class UserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end