Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save fguillen/a3803f0a80ed33bbd8b3aa7ce732de58 to your computer and use it in GitHub Desktop.
Save fguillen/a3803f0a80ed33bbd8b3aa7ce732de58 to your computer and use it in GitHub Desktop.
Rails - Implementing Invitation Code mechanism
commit a656816e7d9498d32b52c6c9455e535466623ad9
Author: Fernando
Date: Fri Oct 1 12:23:37 2021 +0200
Invitation workflow
diff --git a/app/controllers/admin/invitations_controller.rb b/app/controllers/admin/invitations_controller.rb
new file mode 100644
index 0000000..93652c0
--- /dev/null
+++ b/app/controllers/admin/invitations_controller.rb
@@ -0,0 +1,53 @@
+class Admin::InvitationsController < Admin::BaseController
+ before_action :require_admin_user
+ before_action :load_invitation, only: [:show, :edit, :update, :destroy]
+
+ def index
+ @invitations = Invitation.order_by_recent
+ end
+
+ def show; end
+
+ def new
+ @invitation = Invitation.new
+ end
+
+ def create
+ @invitation = Invitation.new(invitation_params)
+
+ if @invitation.save
+ redirect_to [:admin, @invitation], notice: t("controllers.invitations.create.success")
+ else
+ flash.now[:alert] = t("controllers.invitations.create.error")
+ render action: :new
+ end
+ end
+
+ def edit; end
+
+ def update
+ if @invitation.update(invitation_params)
+ redirect_to [:admin, @invitation], notice: t("controllers.invitations.update.success")
+ else
+ flash.now[:alert] = t("controllers.invitations.update.error")
+ render action: :edit
+ end
+ end
+
+ def destroy
+ @invitation.destroy
+ redirect_to :admin_invitations, notice: t("controllers.invitations.destroy.success")
+ end
+
+ protected
+
+ def invitation_params
+ params.require(:invitation).permit(:name)
+ end
+
+ private
+
+ def load_invitation
+ @invitation = Invitation.find(params[:id])
+ end
+end
diff --git a/app/controllers/front/front_users_controller.rb b/app/controllers/front/front_users_controller.rb
index 4bd3ad3..dce2e37 100644
--- a/app/controllers/front/front_users_controller.rb
+++ b/app/controllers/front/front_users_controller.rb
@@ -6,11 +6,13 @@ class Front::FrontUsersController < Front::BaseController
def show; end
def new
- @front_user = FrontUser.new
+ @front_user = FrontUser.new(invitation_id: params[:invitation_id])
end
def create
@front_user = FrontUser.new(front_user_params)
+ @front_user.require_invitation = true
+
if @front_user.save
redirect_to [:front, @front_user], notice: t("controllers.front_users.create.success")
else
@@ -57,7 +59,7 @@ class Front::FrontUsersController < Front::BaseController
protected
def front_user_params
- params.require(:front_user).permit(:name, :email, :password, :password_confirmation)
+ params.require(:front_user).permit(:name, :email, :password, :password_confirmation, :invitation_id)
end
private
diff --git a/app/models/front_user.rb b/app/models/front_user.rb
index 8013b2c..86792f8 100644
--- a/app/models/front_user.rb
+++ b/app/models/front_user.rb
@@ -2,6 +2,8 @@ class FrontUser < ApplicationRecord
self.primary_key = :uuid
include HasUuid
+ attr_accessor :require_invitation
+
acts_as_authentic do |config|
config.crypto_provider = ::Authlogic::CryptoProviders::SCrypt
config.session_class = FrontSession
@@ -10,13 +12,16 @@ class FrontUser < ApplicationRecord
has_many :authorizations, class_name: "FrontAuthorization", dependent: :destroy
has_many :posts, dependent: :destroy
has_many :play_gatherings, dependent: :destroy
+ has_one :invitation, dependent: :nullify
validates :name, presence: true
validates :email, presence: true, uniqueness: { case_sensitive: false }, format: { with: RubyRegex::Email }
validates :password, presence: true, on: :create
validates :password, confirmation: true, allow_blank: true
-
validates_with PasswordValidator, unless: -> { password.blank? }
+ validate :invitation_available, on: :create, if: :require_invitation?
+
+ after_commit :use_invitation, on: :create
scope :order_by_recent, -> { order("created_at desc") }
@@ -24,4 +29,27 @@ class FrontUser < ApplicationRecord
reset_perishable_token!
Notifier.front_user_reset_password(self).deliver
end
+
+ def require_invitation?
+ require_invitation
+ end
+
+ def invitation_id
+ self.invitation&.uuid
+ end
+
+ def invitation_id=(id)
+ self.invitation = Invitation.find_by(uuid: id)
+ end
+
+ def invitation_available
+ if invitation.nil? || invitation.used?
+ errors.add(:invitation, "Invitation Code is not found or is already used")
+ end
+ end
+
+ def use_invitation
+ return if invitation.nil?
+ invitation.use!(self)
+ end
end
diff --git a/app/models/invitation.rb b/app/models/invitation.rb
new file mode 100644
index 0000000..dd9ed43
--- /dev/null
+++ b/app/models/invitation.rb
@@ -0,0 +1,22 @@
+class Invitation < ApplicationRecord
+ self.primary_key = :uuid
+ include HasUuid
+
+ belongs_to :front_user, optional: true
+
+ validates :name, presence: true
+
+ scope :order_by_recent, -> { order("created_at desc") }
+ scope :available, -> { where(used_at: nil) }
+
+ def used?
+ used_at != nil
+ end
+
+ def use!(front_user)
+ update!(
+ used_at: Time.now,
+ front_user: front_user
+ )
+ end
+end
diff --git a/app/views/admin/invitations/_form.html.erb b/app/views/admin/invitations/_form.html.erb
new file mode 100644
index 0000000..5cc34d6
--- /dev/null
+++ b/app/views/admin/invitations/_form.html.erb
@@ -0,0 +1,22 @@
+<%= form_for [:admin, @invitation] do |f| %>
+ <%= render "/shared/form_errors", :object => f.object %>
+
+ <fieldset>
+ <legend><%= "Invitation attributes" %></legend>
+ <hr>
+
+ <div class="form-group row">
+ <%= f.label :name, class: "col-sm-2 col-form-label text-right"%>
+
+ <div class="col-sm-10">
+ <%= f.text_field :name, class: "form-control", placeholder: t("activerecord.attributes.invitation.name") %>
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <div class="offset-sm-2 col-sm-10">
+ <%= f.submit class: "btn btn-primary" %>
+ </div>
+ </div>
+ </fieldset>
+<% end %>
diff --git a/app/views/admin/invitations/_list.html.erb b/app/views/admin/invitations/_list.html.erb
new file mode 100644
index 0000000..814fb22
--- /dev/null
+++ b/app/views/admin/invitations/_list.html.erb
@@ -0,0 +1,19 @@
+<table class="table table-striped table-hover">
+ <tr>
+ <th><%= t "activerecord.attributes.invitation.uuid" %></th>
+ <th><%= t "activerecord.attributes.invitation.name" %></th>
+ <th><%= t "activerecord.attributes.invitation.created_at" %></th>
+ <th><%= t "activerecord.attributes.invitation.used_at" %></th>
+ <th><%= t "activerecord.attributes.invitation.front_user.name" %></th>
+ </tr>
+
+ <% invitations.each do |invitation| %>
+ <tr>
+ <td><%= link_to invitation.uuid, [:admin, invitation] %></td>
+ <td><%= invitation.name %></td>
+ <td><%= invitation.created_at.to_s(:datetimedb) %></td>
+ <td><%= invitation.used_at ? invitation.used_at.to_s(:datetimedb) : "-" %></td>
+ <td><%= invitation.front_user ? link_to(invitation.front_user.name, [:admin, invitation.front_user]) : "-" %></td>
+ </tr>
+ <% end %>
+</table>
diff --git a/app/views/admin/invitations/edit.html.erb b/app/views/admin/invitations/edit.html.erb
new file mode 100644
index 0000000..6c77233
--- /dev/null
+++ b/app/views/admin/invitations/edit.html.erb
@@ -0,0 +1,13 @@
+<% title t("views.invitations.edit.title", :invitation_uuid => @invitation.uuid) %>
+
+<ol class="breadcrumb">
+ <li class="breadcrumb-item"><%= link_to t("layouts.breadcrumbs.invitations"), :admin_invitations %></li>
+ <li class="breadcrumb-item"><%= link_to @invitation.uuid, [:admin, @invitation] %></li>
+ <li class="breadcrumb-item active"><%= t "layouts.breadcrumbs.edit" %></li>
+</ol>
+
+<p class="lead">
+ <%= t "views.invitations.edit.text" %>
+</p>
+
+<%= render "form" %>
diff --git a/app/views/admin/invitations/index.html.erb b/app/views/admin/invitations/index.html.erb
new file mode 100644
index 0000000..2068f02
--- /dev/null
+++ b/app/views/admin/invitations/index.html.erb
@@ -0,0 +1,11 @@
+<% title t("views.invitations.index.title") %>
+
+<nav aria-label="breadcrumb">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item active"><%= t "layouts.breadcrumbs.invitations" %></li>
+ </ol>
+</nav>
+
+<p><%= link_to "New Invitation", new_admin_invitation_path, :class => "btn btn-outline-primary" %></p>
+
+<%= render partial: "list", locals: { invitations: @invitations } %>
diff --git a/app/views/admin/invitations/new.html.erb b/app/views/admin/invitations/new.html.erb
new file mode 100644
index 0000000..448dc0e
--- /dev/null
+++ b/app/views/admin/invitations/new.html.erb
@@ -0,0 +1,15 @@
+<% title t("views.invitations.new.title") %>
+
+<nav aria-label="breadcrumb">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item"><%= link_to t("layouts.breadcrumbs.invitations"), :admin_invitations %></li>
+ <li class="breadcrumb-item active"><%= t "layouts.breadcrumbs.new" %></li>
+ </ol>
+</nav>
+
+<p class="lead">
+ <%= t("views.invitations.new.text") %>
+</p>
+
+
+<%= render "form" %>
diff --git a/app/views/admin/invitations/show.html.erb b/app/views/admin/invitations/show.html.erb
new file mode 100644
index 0000000..2ea8de3
--- /dev/null
+++ b/app/views/admin/invitations/show.html.erb
@@ -0,0 +1,24 @@
+<% title t("views.invitations.show.title", :invitation_uuid => @invitation.uuid) %>
+
+<nav aria-label="breadcrumb">
+ <ol class="breadcrumb">
+ <li class="breadcrumb-item"><%= link_to t("layouts.breadcrumbs.invitations"), :admin_invitations %></li>
+ <li class="breadcrumb-item active"><%= @invitation.uuid %></li>
+ </ol>
+</nav>
+
+<dl class="row">
+ <dt class="col-sm-2 text-right"><%= t "activerecord.attributes.invitation.uuid" %></dt><dd class="col-sm-10"><%= @invitation.uuid %></dd>
+ <dt class="col-sm-2 text-right"><%= t "activerecord.attributes.invitation.name" %></dt><dd class="col-sm-10"><%= @invitation.name %></dd>
+ <dt class="col-sm-2 text-right"><%= t "activerecord.attributes.invitation.created_at" %></dt><dd class="col-sm-10"><%= @invitation.created_at.to_s(:datetimedb) %></dd>
+ <dt class="col-sm-2 text-right"><%= t "activerecord.attributes.invitation.used_at" %></dt><dd class="col-sm-10"><%= @invitation.used_at ? @invitation.used_at.to_s(:datetimedb) : "-" %></dd>
+ <dt class="col-sm-2 text-right"><%= t "activerecord.attributes.invitation.front_user.name" %></dt><dd class="col-sm-10"><%= @invitation.front_user ? link_to(@invitation.front_user.name, [:admin, @invitation.front_user]) : "-" %></dd>
+ <dt class="col-sm-2 text-right"><%= t "activerecord.attributes.invitation.link" %></dt><dd class="col-sm-10"><%= link_to new_front_front_user_url(invitation_id: @invitation), new_front_front_user_url(invitation_id: @invitation), target: "_blank" %></dd>
+</dl>
+
+<div class="controls text-right">
+ <p>
+ <%= link_to t("views.invitations.show.edit_button"), edit_admin_invitation_path(@invitation), :class => "btn btn-primary" %>
+ <%= link_to t("views.invitations.show.delete_button"), [:admin, @invitation], :data => { :confirm => t("views.invitations.show.delete_confirmation") }, :method => :delete, :class => "btn btn-danger" %>
+ </p>
+</div>
diff --git a/app/views/front/front_users/_form.html.erb b/app/views/front/front_users/_form.html.erb
index 8ded723..5ce08fd 100644
--- a/app/views/front/front_users/_form.html.erb
+++ b/app/views/front/front_users/_form.html.erb
@@ -4,6 +4,14 @@
<legend><%= "FrontUser attributes" %></legend>
<hr>
+ <div class="row mb-3">
+ <%= f.label :invitation_id, class: "col-sm-2 col-form-label text-end"%>
+ <div class="col-sm-10">
+ <%= f.text_field :invitation_id, class: "form-control", placeholder: t("activerecord.attributes.front_user.invitation_id") %>
+ <div class="form-text">Introduce the Invitation Code.</div>
+ </div>
+ </div>
+
<div class="row mb-3">
<%= f.label :name, class: "col-sm-2 col-form-label text-end"%>
<div class="col-sm-10">
diff --git a/app/views/layouts/admin/_menu.html.erb b/app/views/layouts/admin/_menu.html.erb
index 261266d..4942387 100644
--- a/app/views/layouts/admin/_menu.html.erb
+++ b/app/views/layouts/admin/_menu.html.erb
@@ -8,6 +8,7 @@
<li class="nav-item"><%= link_to t("layouts.menu.admin_users"), :admin_admin_users, class: "nav-link" %></li>
<li class="nav-item"><%= link_to t("layouts.menu.front_users"), :admin_front_users, class: "nav-link" %></li>
<li class="nav-item"><%= link_to t("layouts.menu.posts"), :admin_posts, class: "nav-link" %></li>
+ <li class="nav-item"><%= link_to t("layouts.menu.invitations"), :admin_invitations, class: "nav-link" %></li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false"><%= current_admin_user.name %></a>
diff --git a/config/locales/custom/en.yml b/config/locales/custom/en.yml
index b9ac28e..0a70967 100644
--- a/config/locales/custom/en.yml
+++ b/config/locales/custom/en.yml
@@ -15,11 +15,20 @@ en:
front_user:
created_at: Created at
email: Email
+ invitation_id: Invitation
name: Name
one: FrontUser
password: Password
password_confirmation: Password confirmation
uuid: Uuid
+ invitation:
+ created_at: Created at
+ front_user:
+ name: Name
+ link: Link
+ name: Name
+ used_at: Used at
+ uuid: Uuid
play_gathering:
description: Description
title: Title
@@ -85,6 +94,15 @@ en:
update:
error: Errors were encountered when trying to update Front User
success: Successfully updated Front User
+ invitations:
+ create:
+ error: Error
+ success: Success
+ destroy:
+ success: Success
+ update:
+ error: Error
+ success: Success
play_gatherings:
create:
error: Error
@@ -114,6 +132,7 @@ en:
forgot_password: Forgotten Password
front_sessions: Front sessions
front_users: Front users
+ invitations: Invitations
login_admin: Admin Login
login_front: Login front
new: New
@@ -127,6 +146,7 @@ en:
features: Features
front_users: Front users
home: Home
+ invitations: Invitations
login: Login
logout: Logout
my_posts: See my posts
@@ -191,6 +211,20 @@ en:
delete_confirmation: Delete confirmation
edit_button: Edit button
title: Title
+ invitations:
+ edit:
+ text: Text
+ title: Title
+ index:
+ title: Title
+ new:
+ text: Text
+ title: Title
+ show:
+ delete_button: Delete button
+ delete_confirmation: Delete confirmation
+ edit_button: Edit button
+ title: Title
play_gathering:
sections:
play_sessions: Play sessions
diff --git a/config/routes.rb b/config/routes.rb
index 4e561c1..ef80c10 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -17,6 +17,7 @@ Rails.application.routes.draw do
get "posts", on: :member
end
resources :posts
+ resources :invitations
end
namespace :api do
diff --git a/db/migrate/20211001100637_create_invitations.rb b/db/migrate/20211001100637_create_invitations.rb
new file mode 100644
index 0000000..e4fb931
--- /dev/null
+++ b/db/migrate/20211001100637_create_invitations.rb
@@ -0,0 +1,14 @@
+class CreateInvitations < ActiveRecord::Migration[6.1]
+ def change
+ create_table :invitations, id: false, force: true do |t|
+ t.string :uuid, null: false, limit: 36, index: { unique: true }, primary_key: true
+ t.string :name, null: false
+ t.string :front_user_id, limit: 36
+ t.datetime :used_at
+
+ t.timestamps
+ end
+
+ add_foreign_key :invitations, :front_users, column: :front_user_id, primary_key: "uuid"
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 12575ab..f57ae05 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2021_09_30_161442) do
+ActiveRecord::Schema.define(version: 2021_10_01_100637) do
create_table "active_storage_attachments", charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t|
t.string "name", null: false
@@ -85,6 +85,16 @@ ActiveRecord::Schema.define(version: 2021_09_30_161442) do
t.index ["uuid"], name: "index_front_users_on_uuid", unique: true
end
+ create_table "invitations", primary_key: "uuid", id: { type: :string, limit: 36 }, charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t|
+ t.string "name", null: false
+ t.string "front_user_id", limit: 36
+ t.datetime "used_at"
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["front_user_id"], name: "fk_rails_415b8ee2dd"
+ t.index ["uuid"], name: "index_invitations_on_uuid", unique: true
+ end
+
create_table "play_gatherings", primary_key: "uuid", id: { type: :string, limit: 36 }, charset: "utf8mb4", collation: "utf8mb4_bin", force: :cascade do |t|
t.string "title", null: false
t.text "description", null: false
@@ -164,6 +174,7 @@ ActiveRecord::Schema.define(version: 2021_09_30_161442) do
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 "invitations", "front_users", primary_key: "uuid"
add_foreign_key "play_gatherings", "front_users", primary_key: "uuid"
add_foreign_key "play_sessions", "play_gatherings", primary_key: "uuid"
add_foreign_key "posts", "front_users", primary_key: "uuid"
diff --git a/test/controllers/admin/invitations_controller_test.rb b/test/controllers/admin/invitations_controller_test.rb
new file mode 100644
index 0000000..20dec78
--- /dev/null
+++ b/test/controllers/admin/invitations_controller_test.rb
@@ -0,0 +1,127 @@
+require "test_helper"
+
+class Admin::InvitationsControllerTest < ActionController::TestCase
+ def setup
+ setup_admin_user
+ end
+
+ def test_index
+ invitation_1 = FactoryBot.create(:invitation, created_at: "2020-04-25")
+ invitation_2 = FactoryBot.create(:invitation, created_at: "2020-04-26")
+
+ get :index
+
+ assert_template "admin/invitations/index"
+ assert_primary_keys([invitation_2, invitation_1], assigns(:invitations))
+ end
+
+ def test_show
+ invitation = FactoryBot.create(:invitation)
+
+ get :show, params: { id: invitation }
+
+ assert_template "admin/invitations/show"
+ assert_equal(invitation, assigns(:invitation))
+ end
+
+ def test_new
+ get :new
+ assert_template "admin/invitations/new"
+ assert_not_nil(assigns(:invitation))
+ end
+
+ def test_create_invalid
+ front_user_1 = FactoryBot.create(:front_user)
+
+ Invitation.any_instance.stubs(:valid?).returns(false)
+
+ post(
+ :create,
+ params: {
+ invitation: {
+ name: "INVITATION_NAME"
+ }
+ }
+ )
+
+ assert_template "new"
+ assert_not_nil(flash[:alert])
+ end
+
+ def test_create_valid
+ front_user_1 = FactoryBot.create(:front_user)
+
+ post(
+ :create,
+ params: {
+ invitation: {
+ name: "INVITATION_NAME"
+ }
+ }
+ )
+
+ invitation = Invitation.last
+ assert_redirected_to [:admin, invitation]
+
+ assert_equal("INVITATION_NAME", invitation.name)
+ end
+
+ def test_edit
+ invitation = FactoryBot.create(:invitation)
+
+ get :edit, params: { id: invitation }
+
+ assert_template "edit"
+ assert_equal(invitation, assigns(:invitation))
+ end
+
+ def test_update_invalid
+ invitation = FactoryBot.create(:invitation)
+
+ Invitation.any_instance.stubs(:valid?).returns(false)
+
+ put(
+ :update,
+ params: {
+ id: invitation,
+ invitation: {
+ name: "THE_NEW_NAME"
+ }
+ }
+ )
+
+ assert_template "edit"
+ assert_not_nil(flash[:alert])
+ end
+
+ def test_update_valid
+ invitation = FactoryBot.create(:invitation)
+
+ put(
+ :update,
+ params: {
+ id: invitation,
+ invitation: {
+ name: "THE_NEW_NAME"
+ }
+ }
+ )
+
+ assert_redirected_to [:admin, invitation]
+ assert_not_nil(flash[:notice])
+
+ invitation.reload
+ assert_equal("THE_NEW_NAME", invitation.name)
+ end
+
+ def test_destroy
+ invitation = FactoryBot.create(:invitation)
+
+ delete :destroy, params: { id: invitation }
+
+ assert_redirected_to :admin_invitations
+ assert_not_nil(flash[:notice])
+
+ assert !Invitation.exists?(invitation.id)
+ end
+end
diff --git a/test/controllers/front/front_users_controller_test.rb b/test/controllers/front/front_users_controller_test.rb
index 048ea14..78459f6 100644
--- a/test/controllers/front/front_users_controller_test.rb
+++ b/test/controllers/front/front_users_controller_test.rb
@@ -37,7 +37,28 @@ class Front::FrontUsersControllerTest < ActionController::TestCase
assert_not_nil(flash[:alert])
end
+ def test_create_without_valid_invitation
+ assert_difference("FrontUser.count", 0) do
+ post(
+ :create,
+ params: {
+ front_user: {
+ name: "Front Wadus",
+ email: "email@email.com",
+ password: "Password!",
+ password_confirmation: "Password!"
+ }
+ }
+ )
+ end
+
+ assert_template "new"
+ assert_not_nil(flash[:alert])
+ end
+
def test_create_valid
+ invitation = FactoryBot.create(:invitation)
+
post(
:create,
params: {
@@ -45,7 +66,8 @@ class Front::FrontUsersControllerTest < ActionController::TestCase
name: "Front Wadus",
email: "email@email.com",
password: "Password!",
- password_confirmation: "Password!"
+ password_confirmation: "Password!",
+ invitation_id: invitation
}
}
)
@@ -55,6 +77,11 @@ class Front::FrontUsersControllerTest < ActionController::TestCase
assert_equal("Front Wadus", front_user.name)
assert_equal("email@email.com", front_user.email)
+ assert_equal(invitation, front_user.invitation)
+
+ invitation.reload
+ assert(invitation.used?)
+ assert_equal(front_user, invitation.front_user)
end
def test_edit
diff --git a/test/factories.rb b/test/factories.rb
index f2d94da..f46b531 100644
--- a/test/factories.rb
+++ b/test/factories.rb
@@ -38,4 +38,8 @@ FactoryBot.define do
factory :play_session do
play_gathering
end
+
+ factory :invitation do
+ name { Faker::Lorem.sentence(word_count: 3) }
+ end
end
diff --git a/test/models/front_user_test.rb b/test/models/front_user_test.rb
index 35430ce..194444a 100644
--- a/test/models/front_user_test.rb
+++ b/test/models/front_user_test.rb
@@ -27,4 +27,28 @@ class FrontUserTest < ActiveSupport::TestCase
assert_primary_keys([front_user_3, front_user_2, front_user_1], FrontUser.order_by_recent)
end
+
+ # Invitation :: INI
+ def test_on_create_no_fail_if_no_invitation_but_invitation_no_required
+ front_user = FactoryBot.create(:front_user, invitation_id: nil, require_invitation: false)
+ assert front_user.valid?
+ end
+
+ def test_on_create_fail_if_no_invitation
+ front_user = FactoryBot.build(:front_user, invitation_id: nil, require_invitation: true)
+ refute front_user.valid?
+ end
+
+ def test_on_create_fail_if_used_invitation
+ invitation = FactoryBot.create(:invitation, used_at: Time.now)
+ front_user = FactoryBot.build(:front_user, invitation_id: invitation, require_invitation: true)
+ refute front_user.valid?
+ end
+
+ def test_on_create_with_proper_invitation
+ invitation = FactoryBot.create(:invitation)
+ front_user = FactoryBot.create(:front_user, invitation_id: invitation, require_invitation: true)
+ assert front_user.valid?
+ end
+ # Invitation :: END
end
diff --git a/test/models/invitation_test.rb b/test/models/invitation_test.rb
new file mode 100644
index 0000000..8bb1c0f
--- /dev/null
+++ b/test/models/invitation_test.rb
@@ -0,0 +1,59 @@
+require "test_helper"
+
+class InvitationTest < ActiveSupport::TestCase
+ def test_fixture_is_valid
+ assert FactoryBot.create(:invitation).valid?
+ end
+
+ def test_validations
+ invitation = FactoryBot.build(:invitation)
+ assert(invitation.valid?)
+
+ invitation = FactoryBot.build(:invitation, name: nil)
+ refute(invitation.valid?)
+
+ invitation = FactoryBot.build(:invitation, front_user: nil)
+ assert(invitation.valid?)
+ end
+
+ def test_uuid_on_create
+ invitation = FactoryBot.build(:invitation)
+ assert_nil(invitation.uuid)
+
+ invitation.save!
+
+ assert_not_nil(invitation.uuid)
+ end
+
+ def test_primary_key
+ invitation = FactoryBot.create(:invitation)
+
+ assert_equal(invitation, Invitation.find(invitation.uuid))
+ end
+
+ def test_relations
+ front_user = FactoryBot.create(:front_user)
+
+ invitation = FactoryBot.create(:invitation, front_user: front_user)
+
+ assert_equal(front_user, invitation.front_user)
+ end
+
+ def test_used
+ invitation = FactoryBot.create(:invitation)
+ refute invitation.used?
+
+ invitation.used_at = Time.now
+ assert invitation.used?
+ end
+
+ def test_use
+ front_user = FactoryBot.create(:front_user)
+ invitation = FactoryBot.create(:invitation)
+ refute invitation.used?
+
+ invitation.use!(front_user)
+ assert invitation.used?
+ assert_equal(front_user, invitation.front_user)
+ end
+end
diff --git a/test/models/post_test copy.rb b/test/models/post_test copy.rb
new file mode 100644
index 0000000..4458980
--- /dev/null
+++ b/test/models/post_test copy.rb
@@ -0,0 +1,71 @@
+require "test_helper"
+
+class PostTest < ActiveSupport::TestCase
+ def test_fixture_is_valid
+ assert FactoryBot.create(:post).valid?
+ end
+
+ def test_validations
+ post = FactoryBot.build(:post)
+ assert(post.valid?)
+
+ post = FactoryBot.build(:post, title: nil)
+ refute(post.valid?)
+
+ post = FactoryBot.build(:post, body: nil)
+ refute(post.valid?)
+
+ post = FactoryBot.build(:post, body: "")
+ refute(post.valid?)
+
+ post = FactoryBot.build(:post, body: "A" * 6)
+ refute(post.valid?)
+
+ post = FactoryBot.build(:post, body: "A" * 65_536)
+ refute(post.valid?)
+
+ post = FactoryBot.build(:post, body: "A" * 30)
+ assert(post.valid?)
+
+ post = FactoryBot.build(:post, front_user: nil)
+ refute(post.valid?)
+ end
+
+ def test_uuid_on_create
+ post = FactoryBot.build(:post)
+ assert_nil(post.uuid)
+
+ post.save!
+
+ assert_not_nil(post.uuid)
+ end
+
+ def test_primary_key
+ post = FactoryBot.create(:post)
+
+ assert_equal(post, Post.find(post.uuid))
+ end
+
+ def test_relations
+ front_user = FactoryBot.create(:front_user)
+
+ post = FactoryBot.create(:post, front_user: front_user)
+
+ assert_equal(front_user, post.front_user)
+ end
+
+ def test_tags
+ post = FactoryBot.create(:post, tag_list: ["one", "two"])
+ assert_equal(2, post.tags.count)
+ assert_equal(["one", "two"], post.tag_list)
+ assert_equal(["one", "two"], post.tags.map(&:name))
+
+ post = FactoryBot.create(:post, tag_list: "one, two")
+ assert_equal(2, post.tags.count)
+ assert_equal(["one", "two"], post.tag_list)
+ assert_equal(["one", "two"], post.tags.map(&:name))
+
+ post = FactoryBot.create(:post, tag_list: "One, Two")
+ assert_equal(["one", "two"], post.tag_list)
+ end
+end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment