mirror of
https://github.com/Evolix/chexpire.git
synced 2024-04-29 23:40:49 +02:00
User with devise, basic integration in navbar with simple form & tests
This commit is contained in:
parent
b9b8024233
commit
138b554772
|
@ -24,3 +24,4 @@ install:
|
|||
script:
|
||||
- bundle exec rubocop
|
||||
- bundle exec rails test
|
||||
- bundle exec rails test:system
|
||||
|
|
1
Gemfile
1
Gemfile
|
@ -69,6 +69,7 @@ group :test do
|
|||
gem 'selenium-webdriver'
|
||||
# Easy installation and use of chromedriver to run system tests with Chrome
|
||||
gem 'chromedriver-helper'
|
||||
gem 'launchy'
|
||||
end
|
||||
|
||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||
|
|
12
app/helpers/users_helper.rb
Normal file
12
app/helpers/users_helper.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module UsersHelper
|
||||
# Inject a devise template inside a same container
|
||||
# while translation form keys are still valid
|
||||
# (original partial scope is preserved)
|
||||
def devise_form_container
|
||||
content_for(:devise_form_content) do
|
||||
yield
|
||||
end
|
||||
|
||||
render "shared/devise_form_container"
|
||||
end
|
||||
end
|
|
@ -1 +1,2 @@
|
|||
@import '~bootstrap/scss/bootstrap';
|
||||
@import 'components/users';
|
||||
|
|
5
app/javascript/packs/src/components/users.scss
Normal file
5
app/javascript/packs/src/components/users.scss
Normal file
|
@ -0,0 +1,5 @@
|
|||
.new_user {
|
||||
.form-check-label.boolean {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
35
app/models/user.rb
Normal file
35
app/models/user.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: users
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# confirmation_sent_at :datetime
|
||||
# confirmation_token :string(255)
|
||||
# confirmed_at :datetime
|
||||
# current_sign_in_at :datetime
|
||||
# current_sign_in_ip :string(255)
|
||||
# email :string(255) default(""), not null
|
||||
# encrypted_password :string(255) default(""), not null
|
||||
# last_sign_in_at :datetime
|
||||
# last_sign_in_ip :string(255)
|
||||
# remember_created_at :datetime
|
||||
# reset_password_sent_at :datetime
|
||||
# reset_password_token :string(255)
|
||||
# sign_in_count :integer default(0), not null
|
||||
# unconfirmed_email :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_users_on_confirmation_token (confirmation_token) UNIQUE
|
||||
# index_users_on_email (email) UNIQUE
|
||||
# index_users_on_reset_password_token (reset_password_token) UNIQUE
|
||||
#
|
||||
|
||||
class User < ApplicationRecord
|
||||
# Include default devise modules. Others available are:
|
||||
# :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
|
||||
devise :database_authenticatable, :registerable,
|
||||
:recoverable, :rememberable, :validatable, :confirmable
|
||||
end
|
12
app/views/devise/confirmations/new.html.erb
Normal file
12
app/views/devise/confirmations/new.html.erb
Normal file
|
@ -0,0 +1,12 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.resend_confirmation_instructions') %></h2>
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
|
||||
<%= f.input :email, autofocus: true, autocomplete: "email",
|
||||
label: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %>
|
||||
|
||||
<%= f.button :submit, t('.resend_confirmation_instructions'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
<% end %>
|
|
@ -0,0 +1,4 @@
|
|||
<p><%= t('.greeting', recipient: @email) %></p>
|
||||
|
||||
<p><%= t('.instruction') %></p>
|
||||
<p><%= link_to t('.action'), confirmation_url(@resource, confirmation_token: @token) %></p>
|
7
app/views/devise/mailer/email_changed.html.erb
Normal file
7
app/views/devise/mailer/email_changed.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<p><%= t('.greeting', recipient: @email) %></p>
|
||||
|
||||
<% if @resource.try(:unconfirmed_email?) %>
|
||||
<p><%= t('.message', email: @resource.unconfirmed_email) %></p>
|
||||
<% else %>
|
||||
<p><%= t('.message', email: @resource.email) %></p>
|
||||
<% end %>
|
3
app/views/devise/mailer/password_change.html.erb
Normal file
3
app/views/devise/mailer/password_change.html.erb
Normal file
|
@ -0,0 +1,3 @@
|
|||
<p><%= t('.greeting', recipient: @resource.email) %></p>
|
||||
|
||||
<p><%= t('.message') %></p>
|
|
@ -0,0 +1,8 @@
|
|||
<p><%= t('.greeting', recipient: @resource.email) %></p>
|
||||
|
||||
<p><%= t('.instruction') %></p>
|
||||
|
||||
<p><%= link_to t('.action'), edit_password_url(@resource, reset_password_token: @token) %></p>
|
||||
|
||||
<p><%= t('.instruction_2') %></p>
|
||||
<p><%= t('.instruction_3') %></p>
|
7
app/views/devise/mailer/unlock_instructions.html.erb
Normal file
7
app/views/devise/mailer/unlock_instructions.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<p><%= t('.greeting', recipient: @resource.email) %></p>
|
||||
|
||||
<p><%= t('.message') %></p>
|
||||
|
||||
<p><%= t('.instruction') %></p>
|
||||
|
||||
<p><%= link_to t('.action'), unlock_url(@resource, unlock_token: @token) %></p>
|
16
app/views/devise/passwords/edit.html.erb
Normal file
16
app/views/devise/passwords/edit.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.change_your_password') %></h2>
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
|
||||
<%= f.hidden_field :reset_password_token %>
|
||||
|
||||
<%= f.input :password, label: t('.new_password'), autocomplete: "off",
|
||||
hint: t('devise.shared.minimum_password_length', count: @minimum_password_length) %>
|
||||
|
||||
<%= f.input :password_confirmation, label: t('.confirm_new_password'), autocomplete: "off" %>
|
||||
|
||||
<%= f.button :submit, t('.change_my_password'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
<% end %>
|
11
app/views/devise/passwords/new.html.erb
Normal file
11
app/views/devise/passwords/new.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.forgot_your_password') %></h2>
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
|
||||
<%= f.input :email, autofocus: true, autocomplete: "email" %>
|
||||
|
||||
<%= f.button :submit, t('.send_me_reset_password_instructions'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
<% end %>
|
40
app/views/devise/registrations/edit.html.erb
Normal file
40
app/views/devise/registrations/edit.html.erb
Normal file
|
@ -0,0 +1,40 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.title', resource: resource_name.to_s.humanize) %></h2>
|
||||
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
|
||||
<%= f.input :email, autofocus: true, autocomplete: "email" %>
|
||||
|
||||
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
|
||||
<div class="alert alert-info">
|
||||
<%= t('.currently_waiting_confirmation_for_email', email: resource.unconfirmed_email) %>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<%= f.input :current_password,
|
||||
autocomplete: "off",
|
||||
hint: t('.we_need_your_current_password_to_confirm_your_changes') %>
|
||||
|
||||
<div class="alert border">
|
||||
<h3>Want to change your password ?</h3>
|
||||
<%= f.input :password,
|
||||
autocomplete: "off",
|
||||
hint: (t('devise.shared.minimum_password_length', count: @minimum_password_length)
|
||||
+ " " + t('.leave_blank_if_you_don_t_want_to_change_it'))%>
|
||||
|
||||
<%= f.input :password_confirmation, autocomplete: "off" %>
|
||||
</div>
|
||||
|
||||
|
||||
<%= f.button :submit, t('.update'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<h3 class="mt-5"><%= t('.cancel_my_account') %></h3>
|
||||
|
||||
<p><%= t('.unhappy') %> <%=
|
||||
button_to t('.cancel_my_account'), registration_path(resource_name),
|
||||
class: "btn btn-danger",
|
||||
data: { confirm: t('.are_you_sure') }, method: :delete %></p>
|
||||
|
||||
<%= link_to t('devise.shared.links.back'), :back %>
|
||||
<% end %>
|
16
app/views/devise/registrations/new.html.erb
Normal file
16
app/views/devise/registrations/new.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.sign_up') %></h2>
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
||||
<%= f.input :email, autofocus: true, autocomplete: "email" %>
|
||||
|
||||
<%= f.input :password, autocomplete: "off",
|
||||
hint: t('devise.shared.minimum_password_length', count: @minimum_password_length) %>
|
||||
|
||||
<%= f.input :password_confirmation, autocomplete: "off" %>
|
||||
|
||||
<%= f.button :submit, t('.sign_up'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
<% end %>
|
16
app/views/devise/sessions/new.html.erb
Normal file
16
app/views/devise/sessions/new.html.erb
Normal file
|
@ -0,0 +1,16 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.sign_in') %></h2>
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
||||
<%= f.input :email, autofocus: true, autocomplete: "email" %>
|
||||
<%= f.input :password, autocomplete: "off" %>
|
||||
|
||||
<% if devise_mapping.rememberable? -%>
|
||||
<%= f.input :remember_me, as: :boolean %>
|
||||
<% end -%>
|
||||
|
||||
<%= f.button :submit, t('.sign_in'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
<% end %>
|
25
app/views/devise/shared/_links.html.erb
Normal file
25
app/views/devise/shared/_links.html.erb
Normal file
|
@ -0,0 +1,25 @@
|
|||
<%- if controller_name != 'sessions' %>
|
||||
<%= link_to t(".sign_in"), new_session_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||
<%= link_to t(".sign_up"), new_registration_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||
<%= link_to t(".forgot_your_password"), new_password_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
||||
<%= link_to t('.didn_t_receive_confirmation_instructions'), new_confirmation_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||
<%= link_to t('.didn_t_receive_unlock_instructions'), new_unlock_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.omniauthable? %>
|
||||
<%- resource_class.omniauth_providers.each do |provider| %>
|
||||
<%= link_to t('.sign_in_with_provider', provider: OmniAuth::Utils.camelize(provider)), omniauth_authorize_path(resource_name, provider) %><br />
|
||||
<% end -%>
|
||||
<% end -%>
|
11
app/views/devise/unlocks/new.html.erb
Normal file
11
app/views/devise/unlocks/new.html.erb
Normal file
|
@ -0,0 +1,11 @@
|
|||
<%= devise_form_container do %>
|
||||
<h2><%= t('.resend_unlock_instructions') %></h2>
|
||||
|
||||
<%= simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
|
||||
<%= f.input :email, autofocus: true, autocomplete: "email" %>
|
||||
|
||||
<%= f.button :submit, t('.resend_unlock_instructions'), class: "btn-primary" %>
|
||||
<% end %>
|
||||
|
||||
<%= render "devise/shared/links" %>
|
||||
<% end %>
|
|
@ -10,7 +10,9 @@
|
|||
</head>
|
||||
|
||||
<body>
|
||||
<%= render "shared/navbar" %>
|
||||
<%= render "shared/notices" %>
|
||||
|
||||
<%= yield %>
|
||||
</body>
|
||||
</html>
|
||||
|
|
7
app/views/shared/_devise_form_container.html.erb
Normal file
7
app/views/shared/_devise_form_container.html.erb
Normal file
|
@ -0,0 +1,7 @@
|
|||
<div class="container">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-6">
|
||||
<%= yield :devise_form_content %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
31
app/views/shared/_navbar.html.erb
Normal file
31
app/views/shared/_navbar.html.erb
Normal file
|
@ -0,0 +1,31 @@
|
|||
<nav class="navbar navbar-expand-lg navbar-light bg-light justify-content-between">
|
||||
<%= link_to "Chexpire", root_path, class: "navbar-brand" %>
|
||||
|
||||
|
||||
<div class="my-2 my-lg-0">
|
||||
<% if user_signed_in? %>
|
||||
<div class="navbar-item">
|
||||
<div class="dropdown">
|
||||
<a class="nav-link dropdown-toggle" href="#"
|
||||
id="navbarDropdown" role="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
<%= current_user.email %>
|
||||
</a>
|
||||
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
|
||||
<%= link_to edit_user_registration_path, class: "dropdown-item" do %>
|
||||
<i class="fa fa-user"></i> <%= t(".profile", default: "Profile") %>
|
||||
<% end %>
|
||||
|
||||
<%= link_to destroy_user_session_path, method: :delete, class: "dropdown-item" do %>
|
||||
<i class="fa fa-sign-out"></i> <%= t(".sign_out", default: "Log out") %>
|
||||
<% end %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<!-- Login link (when logged out) -->
|
||||
<%= link_to t(".sign_in"), new_user_session_path, class: "navbar-item navbar-link" %>
|
||||
<%= link_to t(".sign_up"), new_user_registration_path, class: "navbar-item navbar-link" %>
|
||||
<% end %>
|
||||
</div>
|
||||
</nav>
|
|
@ -136,7 +136,7 @@ Devise.setup do |config|
|
|||
# their account can't be confirmed with the token any more.
|
||||
# Default is nil, meaning there is no restriction on how long a user can take
|
||||
# before confirming their account.
|
||||
config.confirm_within = 3.days
|
||||
config.confirm_within = 7.days
|
||||
|
||||
# If true, requires any email changes to be confirmed (exactly the same way as
|
||||
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
||||
|
|
|
@ -1,33 +1,7 @@
|
|||
# Files in the config/locales directory are used for internationalization
|
||||
# and are automatically loaded by Rails. If you want to use locales other
|
||||
# than English, add the necessary files in this directory.
|
||||
#
|
||||
# To use the locales, use `I18n.t`:
|
||||
#
|
||||
# I18n.t 'hello'
|
||||
#
|
||||
# In views, this is aliased to just `t`:
|
||||
#
|
||||
# <%= t('hello') %>
|
||||
#
|
||||
# To use a different locale, set it with `I18n.locale`:
|
||||
#
|
||||
# I18n.locale = :es
|
||||
#
|
||||
# This would use the information in config/locales/es.yml.
|
||||
#
|
||||
# The following keys must be escaped otherwise they will not be retrieved by
|
||||
# the default I18n backend:
|
||||
#
|
||||
# true, false, on, off, yes, no
|
||||
#
|
||||
# Instead, surround them with single quotes.
|
||||
#
|
||||
# en:
|
||||
# 'true': 'foo'
|
||||
#
|
||||
# To learn more, please read the Rails Internationalization guide
|
||||
# available at http://guides.rubyonrails.org/i18n.html.
|
||||
|
||||
en:
|
||||
hello: "Hello world"
|
||||
shared:
|
||||
navbar:
|
||||
sign_up: "Sign up"
|
||||
sign_in: "Sign in"
|
||||
sign_out: "Sign out"
|
||||
profile: "Profile"
|
||||
|
|
|
@ -1,16 +1,45 @@
|
|||
# == Route Map
|
||||
#
|
||||
# Prefix Verb URI Pattern Controller#Action
|
||||
# root GET / pages#home
|
||||
# rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
|
||||
# rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
|
||||
# rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
|
||||
# update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
|
||||
# rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
|
||||
# Prefix Verb URI Pattern Controller#Action
|
||||
# new_user_session GET /users/sign_in(.:format) devise/sessions#new
|
||||
# user_session POST /users/sign_in(.:format) devise/sessions#create
|
||||
# destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
|
||||
# new_user_password GET /users/password/new(.:format) devise/passwords#new
|
||||
# edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
|
||||
# user_password PATCH /users/password(.:format) devise/passwords#update
|
||||
# PUT /users/password(.:format) devise/passwords#update
|
||||
# POST /users/password(.:format) devise/passwords#create
|
||||
# cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
|
||||
# new_user_registration GET /users/sign_up(.:format) devise/registrations#new
|
||||
# edit_user_registration GET /users/edit(.:format) devise/registrations#edit
|
||||
# user_registration PATCH /users(.:format) devise/registrations#update
|
||||
# PUT /users(.:format) devise/registrations#update
|
||||
# DELETE /users(.:format) devise/registrations#destroy
|
||||
# POST /users(.:format) devise/registrations#create
|
||||
# new_user_confirmation GET /users/confirmation/new(.:format) devise/confirmations#new
|
||||
# user_confirmation GET /users/confirmation(.:format) devise/confirmations#show
|
||||
# POST /users/confirmation(.:format) devise/confirmations#create
|
||||
# root GET / pages#home
|
||||
# letter_opener_web /letter_opener LetterOpenerWeb::Engine
|
||||
# rails_service_blob GET /rails/active_storage/blobs/:signed_id/*filename(.:format) active_storage/blobs#show
|
||||
# rails_blob_representation GET /rails/active_storage/representations/:signed_blob_id/:variation_key/*filename(.:format) active_storage/representations#show
|
||||
# rails_disk_service GET /rails/active_storage/disk/:encoded_key/*filename(.:format) active_storage/disk#show
|
||||
# update_rails_disk_service PUT /rails/active_storage/disk/:encoded_token(.:format) active_storage/disk#update
|
||||
# rails_direct_uploads POST /rails/active_storage/direct_uploads(.:format) active_storage/direct_uploads#create
|
||||
#
|
||||
# Routes for LetterOpenerWeb::Engine:
|
||||
# clear_letters DELETE /clear(.:format) letter_opener_web/letters#clear
|
||||
# delete_letter DELETE /:id(.:format) letter_opener_web/letters#destroy
|
||||
# letters GET / letter_opener_web/letters#index
|
||||
# letter GET /:id(/:style)(.:format) letter_opener_web/letters#show
|
||||
# GET /:id/attachments/:file(.:format) letter_opener_web/letters#attachment
|
||||
|
||||
# In order to update the route map above,
|
||||
# run `bundle exec annotate -r` after modifying this file
|
||||
Rails.application.routes.draw do
|
||||
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
||||
devise_for :users
|
||||
root to: "pages#home"
|
||||
|
||||
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
|
||||
end
|
||||
|
|
44
db/migrate/20180523145630_devise_create_users.rb
Normal file
44
db/migrate/20180523145630_devise_create_users.rb
Normal file
|
@ -0,0 +1,44 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class DeviseCreateUsers < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
create_table :users do |t|
|
||||
## Database authenticatable
|
||||
t.string :email, null: false, default: ""
|
||||
t.string :encrypted_password, null: false, default: ""
|
||||
|
||||
## Recoverable
|
||||
t.string :reset_password_token
|
||||
t.datetime :reset_password_sent_at
|
||||
|
||||
## Rememberable
|
||||
t.datetime :remember_created_at
|
||||
|
||||
## Trackable
|
||||
t.integer :sign_in_count, default: 0, null: false
|
||||
t.datetime :current_sign_in_at
|
||||
t.datetime :last_sign_in_at
|
||||
t.string :current_sign_in_ip
|
||||
t.string :last_sign_in_ip
|
||||
|
||||
## Confirmable
|
||||
t.string :confirmation_token
|
||||
t.datetime :confirmed_at
|
||||
t.datetime :confirmation_sent_at
|
||||
t.string :unconfirmed_email # Only if using reconfirmable
|
||||
|
||||
## Lockable
|
||||
# t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts
|
||||
# t.string :unlock_token # Only if unlock strategy is :email or :both
|
||||
# t.datetime :locked_at
|
||||
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
|
||||
add_index :users, :email, unique: true
|
||||
add_index :users, :reset_password_token, unique: true
|
||||
add_index :users, :confirmation_token, unique: true
|
||||
# add_index :users, :unlock_token, unique: true
|
||||
end
|
||||
end
|
24
db/schema.rb
24
db/schema.rb
|
@ -10,6 +10,28 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 0) do
|
||||
ActiveRecord::Schema.define(version: 2018_05_23_145630) do
|
||||
|
||||
create_table "users", options: "ENGINE=InnoDB DEFAULT CHARSET=utf8", force: :cascade do |t|
|
||||
t.string "email", default: "", null: false
|
||||
t.string "encrypted_password", default: "", null: false
|
||||
t.string "reset_password_token"
|
||||
t.datetime "reset_password_sent_at"
|
||||
t.datetime "remember_created_at"
|
||||
t.integer "sign_in_count", default: 0, null: false
|
||||
t.datetime "current_sign_in_at"
|
||||
t.datetime "last_sign_in_at"
|
||||
t.string "current_sign_in_ip"
|
||||
t.string "last_sign_in_ip"
|
||||
t.string "confirmation_token"
|
||||
t.datetime "confirmed_at"
|
||||
t.datetime "confirmation_sent_at"
|
||||
t.string "unconfirmed_email"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||
t.index ["email"], name: "index_users_on_email", unique: true
|
||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
require "test_helper"
|
||||
|
||||
class ApplicationSystemTestCase < ActionDispatch::SystemTestCase
|
||||
driven_by :selenium, using: :chrome, screen_size: [1400, 1400]
|
||||
driven_by :headless_chrome
|
||||
end
|
||||
|
|
39
test/fixtures/users.yml
vendored
Normal file
39
test/fixtures/users.yml
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: users
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# confirmation_sent_at :datetime
|
||||
# confirmation_token :string(255)
|
||||
# confirmed_at :datetime
|
||||
# current_sign_in_at :datetime
|
||||
# current_sign_in_ip :string(255)
|
||||
# email :string(255) default(""), not null
|
||||
# encrypted_password :string(255) default(""), not null
|
||||
# last_sign_in_at :datetime
|
||||
# last_sign_in_ip :string(255)
|
||||
# remember_created_at :datetime
|
||||
# reset_password_sent_at :datetime
|
||||
# reset_password_token :string(255)
|
||||
# sign_in_count :integer default(0), not null
|
||||
# unconfirmed_email :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_users_on_confirmation_token (confirmation_token) UNIQUE
|
||||
# index_users_on_email (email) UNIQUE
|
||||
# index_users_on_reset_password_token (reset_password_token) UNIQUE
|
||||
#
|
||||
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
# This model initially had no columns defined. If you add columns to the
|
||||
# model remove the '{}' from the fixture names and add the columns immediately
|
||||
# below each fixture, per the syntax in the comments below
|
||||
#
|
||||
user1:
|
||||
email: user@chexpire.org
|
||||
encrypted_password: <%= User.new.send(:password_digest, 'password') %>
|
||||
confirmed_at: <%= 1.minute.ago %>
|
36
test/models/user_test.rb
Normal file
36
test/models/user_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# == Schema Information
|
||||
#
|
||||
# Table name: users
|
||||
#
|
||||
# id :bigint(8) not null, primary key
|
||||
# confirmation_sent_at :datetime
|
||||
# confirmation_token :string(255)
|
||||
# confirmed_at :datetime
|
||||
# current_sign_in_at :datetime
|
||||
# current_sign_in_ip :string(255)
|
||||
# email :string(255) default(""), not null
|
||||
# encrypted_password :string(255) default(""), not null
|
||||
# last_sign_in_at :datetime
|
||||
# last_sign_in_ip :string(255)
|
||||
# remember_created_at :datetime
|
||||
# reset_password_sent_at :datetime
|
||||
# reset_password_token :string(255)
|
||||
# sign_in_count :integer default(0), not null
|
||||
# unconfirmed_email :string(255)
|
||||
# created_at :datetime not null
|
||||
# updated_at :datetime not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
# index_users_on_confirmation_token (confirmation_token) UNIQUE
|
||||
# index_users_on_email (email) UNIQUE
|
||||
# index_users_on_reset_password_token (reset_password_token) UNIQUE
|
||||
#
|
||||
|
||||
require "test_helper"
|
||||
|
||||
class UserTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
61
test/system/users_test.rb
Normal file
61
test/system/users_test.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
require "application_system_test_case"
|
||||
|
||||
class UsersTest < ApplicationSystemTestCase
|
||||
test "an user can signup from the homepage and confirm its account" do
|
||||
visit root_path
|
||||
|
||||
click_on I18n.t("shared.navbar.sign_up")
|
||||
email = "new@chexpire.org"
|
||||
password = "password"
|
||||
|
||||
fill_in("user[email]", with: email)
|
||||
fill_in("user[password]", with: password)
|
||||
fill_in("user[password_confirmation]", with: password)
|
||||
|
||||
click_button I18n.t("devise.registrations.new.sign_up")
|
||||
|
||||
assert_equal root_path, page.current_path
|
||||
user = User.find_by!(email: email, confirmed_at: nil)
|
||||
assert_not_nil user
|
||||
|
||||
confirmation_path = user_confirmation_path(confirmation_token: user.confirmation_token)
|
||||
|
||||
confirmation_email = ActionMailer::Base.deliveries.last
|
||||
|
||||
assert confirmation_email.body.include?(confirmation_path)
|
||||
|
||||
visit confirmation_path
|
||||
assert_equal new_user_session_path, page.current_path
|
||||
assert page.has_css?(".alert-success")
|
||||
end
|
||||
|
||||
test "an user can signin from the homepage" do
|
||||
user = users(:user1)
|
||||
visit root_path
|
||||
|
||||
click_on I18n.t("shared.navbar.sign_in")
|
||||
|
||||
fill_in "user[email]", with: user.email
|
||||
fill_in "user[password]", with: "password"
|
||||
|
||||
click_button I18n.t("devise.sessions.new.sign_in")
|
||||
|
||||
assert_equal root_path, page.current_path
|
||||
assert page.has_content?(user.email)
|
||||
end
|
||||
|
||||
test "an user can signout from the homepage" do
|
||||
user = users(:user1)
|
||||
|
||||
login_as user
|
||||
visit root_path
|
||||
|
||||
find ".navbar" do
|
||||
click_on user.email
|
||||
click_on I18n.t("shared.navbar.sign_out")
|
||||
end
|
||||
|
||||
assert_equal root_path, page.current_path
|
||||
assert page.has_content?(I18n.t("shared.navbar.sign_in"))
|
||||
end
|
||||
end
|
|
@ -6,5 +6,17 @@ class ActiveSupport::TestCase
|
|||
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
||||
fixtures :all
|
||||
|
||||
include Warden::Test::Helpers
|
||||
Warden.test_mode!
|
||||
|
||||
# Add more helper methods to be used by all tests here...
|
||||
end
|
||||
|
||||
Capybara.register_driver :headless_chrome do |app|
|
||||
capabilities = Selenium::WebDriver::Remote::Capabilities.chrome(
|
||||
"chromeOptions" => { args: %w[headless disable-gpu] + ["window-size=1280,800"] },
|
||||
)
|
||||
Capybara::Selenium::Driver.new app, browser: :chrome, desired_capabilities: capabilities
|
||||
end
|
||||
Capybara.save_path = Rails.root.join("tmp/capybara")
|
||||
Capybara.javascript_driver = :headless_chrome
|
||||
|
|
Loading…
Reference in a new issue