Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ gem 'bcrypt', '~> 3.1.7'
# Use Capistrano for deployment
# gem 'capistrano-rails', group: :development

gem 'rails-controller-testing'

group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platform: :mri
Expand Down
5 changes: 5 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ GEM
bundler (>= 1.3.0, < 2.0)
railties (= 5.0.1)
sprockets-rails (>= 2.0.0)
rails-controller-testing (1.0.1)
actionpack (~> 5.x)
actionview (~> 5.x)
activesupport (~> 5.x)
rails-dom-testing (2.0.2)
activesupport (>= 4.2.0, < 6.0)
nokogiri (~> 1.6)
Expand Down Expand Up @@ -171,6 +175,7 @@ DEPENDENCIES
pry
puma (~> 3.0)
rails (~> 5.0.1)
rails-controller-testing
sass-rails (~> 5.0)
spring
spring-watcher-listen (~> 2.0.0)
Expand Down
4 changes: 4 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception

def record_not_found
raise ActiveRecord::RecordNotFound.new('Not Found')
end
end
24 changes: 24 additions & 0 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
class UsersController < ApplicationController
def show
@user = User.find_by(slug: params[:slug]) or record_not_found
end

def new
@user = User.new
end

def create
@user = User.new(user_params)
if @user.save
redirect_to user_path(slug: @user.slug)
else
render :new
end
end

private

def user_params
params.require(:user).permit(:username, :email, :password, :password_confirmation)
end
end
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
module PasswordFormat
EIGHT_OR_MORE_CHARACTERS = /\A.{8,}\z/
CONTAINS_A_DIGIT = /\d/
module StringFormat
STARTS_WITH_NON_WHITESPACE = /\A\S/
ENDS_WITH_NON_WHITESPACE = /\S\z/
ONLY_PRINTABLE_CHARACTERS = /\A[[:print:]]*\z/
EIGHT_OR_MORE_CHARACTERS = /\A.{8,}\z/
CONTAINS_A_DIGIT = /\d/
end
24 changes: 20 additions & 4 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
class User < ApplicationRecord
before_save { email.downcase! }
before_validation :generate_slug
validates :username,
presence: true,
length: { maximum: 24 },
uniqueness: { case_sensitive: false }
validates :username, format: { with: StringFormat::ONLY_PRINTABLE_CHARACTERS,
message: 'can only contain printable characters' }
validates :username, format: { with: StringFormat::STARTS_WITH_NON_WHITESPACE,
message: 'can not start with whitespace' }
validates :username, format: { with: StringFormat::ENDS_WITH_NON_WHITESPACE,
message: 'can not end with whitespace' }
validates :email,
presence: true,
length: { maximum: 255 },
format: { with: EmailFormat::EMAIL },
uniqueness: { case_sensitive: false }
validates :slug,
presence: true,
uniqueness: true
has_secure_password
validates :password, format: { with: PasswordFormat::EIGHT_OR_MORE_CHARACTERS,
validates :password, format: { with: StringFormat::EIGHT_OR_MORE_CHARACTERS,
message: 'must have 8 or more characters' }
validates :password, format: { with: PasswordFormat::CONTAINS_A_DIGIT,
validates :password, format: { with: StringFormat::CONTAINS_A_DIGIT,
message: 'must have at least one digit' }
validates :password, format: { with: PasswordFormat::STARTS_WITH_NON_WHITESPACE,
validates :password, format: { with: StringFormat::STARTS_WITH_NON_WHITESPACE,
message: 'can not start with whitespace' }
validates :password, format: { with: PasswordFormat::ENDS_WITH_NON_WHITESPACE,
validates :password, format: { with: StringFormat::ENDS_WITH_NON_WHITESPACE,
message: 'can not end with whitespace' }

private

def generate_slug
self.slug ||= self.username.parameterize if self.username.present?
end
end
12 changes: 12 additions & 0 deletions app/views/shared/_error_messages.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<% if @user.errors.any? %>
<div id="error_explanation">
<div class="alert alert-danger">
The form contains <%= pluralize(@user.errors.count, "error") %>.
</div>
<ul>
<% @user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
21 changes: 21 additions & 0 deletions app/views/users/new.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<% provide(:title, 'Sign Up') %>
<div class="center box1">
<h1>Sign Up</h1>
<%= form_for(@user, url: signup_path) do |f| %>
<%= render 'shared/error_messages' %>

<%= f.label :username %><br>
<%= f.text_field :username %><br>

<%= f.label :email %><br>
<%= f.email_field :email %><br>

<%= f.label :password %><br>
<%= f.password_field :password %><br>

<%= f.label :password_confirmation, "Password Again" %><br>
<%= f.password_field :password_confirmation %><br>

<%= f.submit "Sign me up!" %>
<% end %>
</div>
11 changes: 11 additions & 0 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class="center box1">
<h1><%= @user.username %></h1>
<p>first_name: <%= @user.first_name %></p>
<p>last_name: <%= @user.last_name %></p>
<p>username: <%= @user.first_name %></p>
<p>id: <%= @user.id %></p>
<hr>
<p>description: <%= @user.description %></p>
<p>website: <%= @user.website %></p>
<p>email: <%= @user.email %></p>
</div>
4 changes: 4 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Rails.application.routes.draw do
root 'welcome#index'

resources :users, param: :slug, only: [:show]
get '/signup', to: 'users#new'
post '/signup', to: 'users#create'
end
5 changes: 5 additions & 0 deletions db/migrate/20170111005636_add_slug_to_users.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddSlugToUsers < ActiveRecord::Migration[5.0]
def change
add_column :users, :slug, :string, unique: true
end
end
3 changes: 2 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20170110022729) do
ActiveRecord::Schema.define(version: 20170111005636) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
Expand All @@ -25,6 +25,7 @@
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "password_digest"
t.string "slug"
end

end
8 changes: 1 addition & 7 deletions db/seeds.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1 @@
# This file should contain all the record creation needed to seed the database with its default values.
# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup).
#
# Examples:
#
# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }])
# Character.create(name: 'Luke', movie: movies.first)
User.create(username: 'Alex', password: 'alex@allegroplanet.com', password: 'pass1word', password_confirmation: 'pass1word')
51 changes: 51 additions & 0 deletions test/controllers/users_controller_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
require 'test_helper'

class UsersControllerTest < ActionDispatch::IntegrationTest
def user
@user ||= User.first
end

test 'GET #show is successful' do
get user_path(user.slug)
assert_response :success
end

test 'GET #show renders the "show" template' do
get user_path(user.slug)
assert_template :show
end

test 'GET #new is successful' do
get signup_path
assert_response :success
end

test 'GET #new renders the "new" template' do
get signup_path
assert_template :new
end

test 'POST #create redirects to the user page successfuly' do
valid_new_user_params = {
username: 'Joe Valid',
email: 'valid@email.com',
password: 'valid1pass',
password_confirmation: 'valid1pass'
}

post signup_path, params: { user: valid_new_user_params }
assert_redirected_to '/users/joe-valid'
end

test 'POST #create renders the "new" template when invalid user params are passed' do
invalid_new_user_params = {
username: 'Joe InValid',
email: 'invalidemail',
password: 'pass',
password_confirmation: 'pass2'
}

post signup_path, params: { user: invalid_new_user_params }
assert_template :new
end
end
1 change: 1 addition & 0 deletions test/fixtures/users.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
markoates:
username: markoates
email: marks@example.com
slug: markoates
first_name: Mark
last_name: Oates
website: www.example.com
Expand Down
Loading