Skip to content

Commit

Permalink
Merge pull request #13 from felipejoglar/felipejoglar/add-tests
Browse files Browse the repository at this point in the history
Add tests
  • Loading branch information
felipejoglar authored Mar 16, 2024
2 parents 7734d0c + 74ae8c6 commit b923ada
Show file tree
Hide file tree
Showing 15 changed files with 407 additions and 36 deletions.
5 changes: 1 addition & 4 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ def destroy
private

def authentication_params
{
email: params[:user][:email].strip.downcase,
password: params[:user][:password],
}
params.require(:user).permit(:email, :password)
end
end
8 changes: 4 additions & 4 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
class UsersController < ApplicationController
skip_before_action :authenticate_user!

def new
@user = User.new
end

def create
@user = User.new(user_params)
if @user.save
Expand All @@ -24,10 +28,6 @@ def create
end
end

def new
@user = User.new
end

private

def user_params
Expand Down
4 changes: 3 additions & 1 deletion app/mailers/user_mailer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
class UserMailer < ApplicationMailer

def password_reset
mail to: params[:user].email, subject: "Reset your password"
@user = params[:user]

mail to: @user.email, subject: t("auth.password_reset.mail.subject")
end
end
10 changes: 8 additions & 2 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@
class User < ApplicationRecord
has_secure_password

validates :email, format: {with: URI::MailTo::EMAIL_REGEXP}, presence: true, uniqueness: true
normalizes :email, with: -> (email) { email.strip.downcase }
EMAIL_REQUIREMENTS = URI::MailTo::EMAIL_REGEXP
PASSWORD_REQUIREMENTS = /\A.{12,64}\z/

validates :email, :password, :name, presence: true
validates :email, uniqueness: true
validates :email, format: EMAIL_REQUIREMENTS
validates :password, format: PASSWORD_REQUIREMENTS

normalizes :email, with: -> (email) { email.strip.downcase }

def password_reset_requested
UserMailer.with(user: self, token: generate_token_for(:password_reset))
Expand Down
10 changes: 5 additions & 5 deletions app/views/shared/_form_flash.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
</div>
<% end %>
<% elsif object&.errors&.any? %>
<% object.errors.messages.each do |_, messages| %>
<div class="message alert">
<div class="message alert">
<% object.errors.messages.each do |_, messages| %>
<% messages.each do |message| %>
<%= message %>
<%= message %><br>
<% end %>
</div>
<% end %>
<% end %>
</div>
<% end %>
1 change: 1 addition & 0 deletions app/views/users/new.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<%= form.label :password_confirmation, class: "label" %>
<%= form.password_field :password_confirmation, placeholder: t("auth.sign_up.placeholder.password_confirmation"), required: true, class: "input #{ "input-error" if error}" %>
</div>
<div class="text-xs mb-4"><%= t("auth.sign_up.password_security") %></div>
<div class="text-center">
<%= form.submit t("auth.signup"), class: "btn-primary mx-0 w-full" %>
</div>
Expand Down
2 changes: 2 additions & 0 deletions config/environments/test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@

config.action_mailer.perform_caching = false

config.action_mailer.default_url_options = { host: "localhost", port: 3000 }

# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
Expand Down
6 changes: 6 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ en:
title: "Create a new account"
subtitle: "Make the best of your time • Boost your productivity"
headline: "Just need a few things to get you going"
password_security: "For your security, we require that passwords be at least 12 characters."
already_signed_up: "Already have an account."

placeholder:
Expand Down Expand Up @@ -72,10 +73,15 @@ en:
confirmation: "Check your email for reset instructions."
expired: "Sorry, your password reset link has expired"

mail:
subject: "Reset your password"

activerecord:
errors:
models:
user:
attributes:
password:
invalid: "Passwords should be at least 12 characters"
password_confirmation:
confirmation: "Passwords must match"
7 changes: 0 additions & 7 deletions test/controllers/landing_controller_test.rb

This file was deleted.

98 changes: 98 additions & 0 deletions test/controllers/password_reset_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# Copyright 2024 Felipe Joglar
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "test_helper"

class PasswordResetControllerTest < ActionDispatch::IntegrationTest
setup do
@name = "Felipe"
@token = create_user_with(name: @name).generate_token_for(:password_reset)
end

test "requesting to create a new password" do
get forgot_password_url

assert_response :ok
assert_select 'h2', I18n .t("auth.forgot_password.title")

post password_url, params: password_reset_params(email: "felipe@taskodoro.com")
follow_redirect!

assert_response :ok
assert_select 'div.notice', I18n.t("auth.password_reset.message.confirmation")
end

test "updating a password" do
get password_edit_url, params: { token: @token }

assert_response :ok
assert_select 'h2', I18n.t("auth.password_reset.title")

patch "#{password_url}?token=#{@token}", params: new_password_params
assert_response :found

follow_redirect!
assert_response :ok
assert_select 'h1', "Welcome #{@name}"
end

test "failing to update a password with invalid token" do
get password_edit_url, params: { token: @token }

assert_response :ok
assert_select 'h2', I18n.t("auth.password_reset.title")

patch "#{password_url}?token=not_valid_token", params: new_password_params

follow_redirect!
assert_response :ok
assert_equal I18n.t("auth.password_reset.message.expired"), flash[:notice]
end

test "failing to update a password with invalid password" do
get password_edit_url, params: { token: @token }

assert_response :ok
assert_select 'h2', I18n.t("auth.password_reset.title")

patch "#{password_url}?token=#{@token}", params: new_password_params(password: "invalid")
assert_response :unprocessable_entity

assert_select 'h2', I18n.t("auth.password_reset.title")
end

private

def create_user_with(name:)
User.create!(
name: name,
email: "felipe@taskodoro.com",
password: "a_valid_password",
password_confirmation: "a_valid_password"
)
end

def password_reset_params(email:)
{ user: { email: email } }
end

def new_password_params(password: "a_valid_password")
{ user:
{
password: password,
password_confirmation: password
}
}
end
end
90 changes: 87 additions & 3 deletions test/controllers/sessions_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,91 @@
# Copyright 2024 Felipe Joglar
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "test_helper"

class SessionsControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end

test "creating a new session" do
email = "felipe@taskodoro.com"
password = "a_valid_password"

get signin_url

assert_response :ok
assert_select 'h2', I18n.t("auth.sign_in.title")

create_user_with(email: email, password: password)

post signin_url, params: login_params(email: email, password: password)
assert session["current_user_id"], "User should be logged in after creation"

follow_redirect!
assert_response :ok
assert_select 'h1', 'Welcome Felipe'
end

test "failing to create a new session" do
email = "felipe@taskodoro.com"
password = "a_valid_password"

get signin_url

assert_response :ok
assert_select 'h2', I18n.t("auth.sign_in.title")

create_user_with(email: email, password: password)

post signin_url, params: login_params(email: "not_signed_up@email.com", password: password)
assert_response :unprocessable_entity

assert_select 'div.alert', 1
end

test "destroy current session" do
email = "felipe@taskodoro.com"
password = "a_valid_password"

create_user_with(email: email, password: password)
post signin_url, params: login_params(email: email, password: password)
assert session["current_user_id"], "User should be logged in after creation"
follow_redirect!

delete signout_url
refute session["current_user_id"]

follow_redirect!
assert_select 'h1', I18n.t("landing.welcome")
end

private

def create_user_with(email:, password:)
User.create!(
name: "Felipe",
email: email,
password: password,
password_confirmation: password
)
end

def login_params(email:, password:)
{
user:
{
email: email,
password: password
}
}
end
end
68 changes: 65 additions & 3 deletions test/controllers/users_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,69 @@
# Copyright 2024 Felipe Joglar
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

require "test_helper"

class UsersControllerTest < ActionDispatch::IntegrationTest
# test "the truth" do
# assert true
# end

test "creating a new user" do
get signup_url

assert_response :ok
assert_select 'h2', I18n.t("auth.sign_up.title")

post signup_url, params: valid_params(name: "Felipe")
assert session["current_user_id"], "User should be logged in after creation"

follow_redirect!
assert_response :ok
assert_select 'h1', 'Welcome Felipe'
end

test "failing to create a new user" do
get signup_url

assert_response :ok
assert_select 'h2', I18n.t("auth.sign_up.title")

post signup_url, params: invalid_params
assert_response :unprocessable_entity

assert_select 'div.alert', 1
end

private

def valid_params(name:, password: "a_valid_password")
{ user:
{
name: name,
email: "avalid@email",
password: password,
password_confirmation: password
}
}
end

def invalid_params
{ user:
{
name: "A name",
email: "avalid@email",
password: "a_valid_password",
password_confirmation: "no_matching_password"
}
}
end
end

Loading

0 comments on commit b923ada

Please sign in to comment.