Commit 4d2c17a9 by Mai Hoang Thai Ha

Finish user signup

parent 76ba878d
Pipeline #1238 canceled with stages
in 0 seconds
require 'active_support/core_ext/string'
# Defines the matching rules for Guard.
guard :minitest, spring: "bin/rails test", all_on_start: false do
watch(%r{^test/(.*)/?(.*)_test\.rb$})
watch('test/test_helper.rb') { 'test' }
watch('config/routes.rb') { interface_tests }
watch(%r{app/views/layouts/*}) { interface_tests }
watch(%r{^app/models/(.*?)\.rb$}) do |matches|
["test/models/#{matches[1]}_test.rb",
"test/integration/microposts_interface_test.rb"]
end
watch(%r{^test/fixtures/(.*?)\.yml$}) do |matches|
"test/models/#{matches[1].singularize}_test.rb"
end
watch(%r{^app/mailers/(.*?)\.rb$}) do |matches|
"test/mailers/#{matches[1]}_test.rb"
end
watch(%r{^app/views/(.*)_mailer/.*$}) do |matches|
"test/mailers/#{matches[1]}_mailer_test.rb"
end
watch(%r{^app/controllers/(.*?)_controller\.rb$}) do |matches|
resource_tests(matches[1])
end
watch(%r{^app/views/([^/]*?)/.*\.html\.erb$}) do |matches|
["test/controllers/#{matches[1]}_controller_test.rb"] +
integration_tests(matches[1])
end
watch(%r{^app/helpers/(.*?)_helper\.rb$}) do |matches|
integration_tests(matches[1])
end
watch('app/views/layouts/application.html.erb') do
'test/integration/site_layout_test.rb'
end
watch('app/helpers/sessions_helper.rb') do
integration_tests << 'test/helpers/sessions_helper_test.rb'
end
watch('app/controllers/sessions_controller.rb') do
['test/controllers/sessions_controller_test.rb',
'test/integration/users_login_test.rb']
end
watch('app/controllers/account_activations_controller.rb') do
'test/integration/users_signup_test.rb'
end
watch(%r{app/views/users/*}) do
resource_tests('users') +
['test/integration/microposts_interface_test.rb']
end
end
# Returns the integration tests corresponding to the given resource.
def integration_tests(resource = :all)
if resource == :all
Dir["test/integration/*"]
else
Dir["test/integration/#{resource}_*.rb"]
end
end
# Returns all tests that hit the interface.
def interface_tests
integration_tests << "test/controllers"
end
# Returns the controller tests corresponding to the given resource.
def controller_test(resource)
"test/controllers/#{resource}_controller_test.rb"
end
# Returns all tests for the given resource.
def resource_tests(resource)
integration_tests(resource) << controller_test(resource)
end
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 400 140" enable-background="new 0 0 400 140" xml:space="preserve">
<style>.a{fill:#c00;}</style>
<title>rails-logo</title>
<g>
<path class="a" d="M346.6,121.5v18.1c0,0,23.4,0,32.7,0c6.7,0,18.2-4.9,18.6-18.6c0-0.6,0-6.5,0-7c0-11.7-9.6-18.6-18.6-18.6
c-4.2,0-16.3,0-16.3,0V87l32.3,0V68.8c0,0-22.2,0-31,0c-8,0-18.7,6.6-18.7,18.9c0,1.2,0,5.2,0,6.3c0,12.3,10.6,18.6,18.7,18.6
c22.5,0.1-5.4,0,15.4,0c0,8.8,0,8.8,0,8.8"/>
<path class="a" d="M171.4,117.1c0,0,17.5-1.5,17.5-24.1s-21.2-24.7-21.2-24.7h-38.2v71.3h19.2v-17.2l16.6,17.2h28.4
L171.4,117.1z M164,102.5h-15.3V86.2h15.4c0,0,4.3,1.6,4.3,8.1S164,102.5,164,102.5z"/>
<path class="a" d="M236.3,68.8c-4.9,0-5.6,0-19.5,0c-13.9,0-18.6,12.6-18.6,18.6c0,13,0,52.2,0,52.2h19.5v-12.5H236v12.5h18.9
c0,0,0-38.5,0-52.2C254.9,72.2,241.1,68.8,236.3,68.8z M236,106.9h-18.4V89.6c0,0,0-3.9,6.1-3.9c5.6,0,1,0,6.7,0
c5.4,0,5.5,3.9,5.5,3.9V106.9z"/>
<rect x="263.8" y="68.8" class="a" width="20.3" height="70.8"/>
<polygon class="a" points="312.6,121.3 312.6,68.8 292.4,68.8 292.4,121.3 292.4,139.6 312.6,139.6 339.9,139.6 339.9,121.3
"/>
<path class="a" d="M9,139.6h79c0,0-15.1-68.9,34.9-96.8c10.9-5.3,45.6-25.1,102.4,16.9c1.8-1.5,3.5-2.7,3.5-2.7
S176.8,5.1,118.9,10.9C89.8,13.5,54,40,33,75S9,139.6,9,139.6z"/>
<path class="a" d="M9,139.6h79c0,0-15.1-68.9,34.9-96.8c10.9-5.3,45.6-25.1,102.4,16.9c1.8-1.5,3.5-2.7,3.5-2.7
S176.8,5.1,118.9,10.9C89.8,13.5,54,40,33,75S9,139.6,9,139.6z"/>
<path class="a" d="M9,139.6h79c0,0-15.1-68.9,34.9-96.8c10.9-5.3,45.6-25.1,102.4,16.9c1.8-1.5,3.5-2.7,3.5-2.7
S176.8,5.1,118.9,10.9C89.7,13.5,53.9,40,32.9,75S9,139.6,9,139.6z"/>
<path class="a" d="M173.6,16.5l0.4-6.7c-0.9-0.5-3.4-1.7-9.7-3.5l-0.4,6.6C167.2,14,170.4,15.2,173.6,16.5z"/>
<path class="a" d="M164.1,37.7l-0.4,6.3c3.3,0.1,6.6,0.5,9.9,1.2l0.4-6.2C170.6,38.3,167.3,37.9,164.1,37.7z"/>
<path class="a" d="M127.1,6.5c0.3,0,0.7,0,1,0l-2-6.1c-3.1,0-6.3,0.2-9.6,0.6l1.9,5.9C121.3,6.6,124.2,6.5,127.1,6.5z"/>
<path class="a" d="M131.9,43.3l2.3,6.9c2.9-1.4,5.8-2.6,8.7-3.5l-2.2-6.6C137.3,41.1,134.4,42.2,131.9,43.3z"/>
<path class="a" d="M86.5,17L82,10.1c-2.5,1.3-5.1,2.7-7.8,4.3l4.6,7C81.4,19.8,83.9,18.3,86.5,17z"/>
<path class="a" d="M107,62l4.8,7.2c1.7-2.5,3.7-4.8,5.9-7.1l-4.5-6.8C110.9,57.4,108.8,59.7,107,62z"/>
<path class="a" d="M92.5,94.2l8.1,6.4c0.4-3.9,1.1-7.8,2.1-11.7l-7.2-5.7C94.2,86.9,93.3,90.6,92.5,94.2z"/>
<path class="a" d="M48.7,46.7l-7.1-6.2c-2.6,2.5-5.1,5-7.4,7.5l7.7,6.6C44,51.9,46.3,49.2,48.7,46.7z"/>
<path class="a" d="M18.5,91.4L7,87.2c-1.9,4.3-4,9.3-5,12l11.5,4.2C14.8,100,16.9,95.1,18.5,91.4z"/>
<path class="a" d="M91,119.6c0.2,5.3,0.7,9.6,1.2,12.6l12,4.3c-0.9-3.9-1.8-8.3-2.4-13L91,119.6z"/>
</g>
</svg>
@import "bootstrap-sprockets";
@import "bootstrap";
/* mixins, variables, etc. */
$gray-medium-light: #eaeaea;
@mixin box_sizing {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
// miscellaneous
.debug_dump {
clear: both;
float: left;
width: 100%;
margin-top: 45px;
@include box_sizing;
}
/* universal */
body {
padding-top: 60px;
}
section {
overflow: auto;
}
textarea {
resize: vertical;
}
.center {
text-align: center;
h1 {
margin-bottom: 10px;
}
}
/* typography */
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1;
}
h1 {
font-size: 3em;
letter-spacing: -2px;
margin-bottom: 30px;
text-align: center;
}
h2 {
font-size: 1.2em;
letter-spacing: -1px;
margin-bottom: 30px;
text-align: center;
font-weight: normal;
color: $gray-light;
}
p {
font-size: 1.1em;
line-height: 1.7em;
}
/* header */
#logo {
float: left;
margin-right: 10px;
font-size: 1.7em;
color: white;
text-transform: uppercase;
letter-spacing: -1px;
padding-top: 9px;
font-weight: bold;
&:hover {
color: white;
text-decoration: none;
}
}
/* footer */
footer {
margin-top: 45px;
padding-top: 5px;
border-top: 1px solid $gray-medium-light;
color: $gray-light;
a {
color: $gray;
&:hover {
color: $gray-darker;
}
}
small {
float: left;
}
ul {
float: right;
list-style: none;
li {
float: left;
margin-left: 15px;
}
}
}
// sidebar
aside {
section.user_info {
margin-top: 20px;
}
section {
padding: 10px 0;
margin-top: 20px;
&:first-child {
border: 0;
padding-top: 0;
}
span {
display: block;
margin-bottom: 3px;
line-height: 1;
}
h1 {
font-style: 1.4em;
text-align: left;
letter-spacing: -1px;
margin-bottom: 3%;
margin-top: 0px;
}
}
}
.gravatar {
float: left;
margin-right: 10px;
}
.gravatar_edit {
margin-top: 15px;
}
// form
input, textarea, select, .uneditable_iput {
border: 1px solid #bbb;
width: 100%;
margin-bottom: 15px;
@include box_sizing;
}
input {
height: auto !important;
}
#error_explanation {
color: red;
ul {
color: red;
margin: 0 0 30px 0;
}
}
.field_with_errors {
@extend .has-error;
.form-control {
color: $state-danger-text;
}
}
\ No newline at end of file
// Place all the styles related to the Users controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: https://sass-lang.com/
class UsersController < ApplicationController
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
flash[:success] = "Welcome to the Sample App!"
redirect_to @user
else
render 'new'
end
end
private
end
module UsersHelper
# Return the Gravatar for the given user
def gravatar_for(user)
gravatar_id = Digest::MD5::hexdigest(user.email.downcase)
gravatar_url = "https://secure.gravatar.com/avatar/#{gravatar_id}"
image_tag(gravatar_url, alt: user.name, class: "gravatar")
end
end
class User < ApplicationRecord
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum:50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum:255 },
format: {with: VALID_EMAIL_REGEX},
uniqueness: true
has_secure_password
validates :password, presence: true, length: {minimum: 6}
end
<footer class="footer">
<small>
The <a href="https://www.railstutorial.org">Ruby on Rails Tutorial</a>
by <a href="https://www.michaelhartl.com">Michael Hartl</a>
</small>
<nav>
<ul>
<li><%= link_to "About", about_path %></li>
<li><%= link_to "Contact", contact_path %></li>
<li><a href="https://news.railstutorial.org">News</a></li>
</ul>
</nav>
</footer>
\ No newline at end of file
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="container">
<%= link_to "sample app", root_path, id: "logo" %>
<nav>
<ul class="nav navbar-nav navbar-right">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Help", help_path %></li>
<li><%= link_to "Log in", '#' %></li>
</ul>
</nav>
</div>
</header>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js">
</script>
<![endif]-->
\ No newline at end of file
<% 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 %>
\ No newline at end of file
<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(model: @user, local: true) do |f| %>
<%= render 'shared/error_messages' %>
<%= f.label :name %>
<%= f.text_field :name, class: 'form-control' %>
<%= f.label :email %>
<%= f.text_field :email, class: 'form-control' %>
<%= f.label :password %>
<%= f.password_field :password, class: 'form-control' %>
<%= f.label :password_confirmation, "Confirmation" %>
<%= f.password_field :password_confirmation, class: 'form-control' %>
<%= f.submit "Create my account", class: "btn btn-primary" %>
<% end %>
</div>
</div>
\ No newline at end of file
<%= provide(:title, @user.name) %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<h1>
<%= gravatar_for @user %>
<%= @user.name %>
</h1>
</section>
</aside>
</div>
\ No newline at end of file
master
* rails-flavored-ruby
static-pages
remotes/heroku/master
remotes/origin/HEAD -> origin/master
remotes/origin/master
remotes/origin/static-pages
class CreateUsers < ActiveRecord::Migration[6.1]
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
class AddIndexToUsersEmails < ActiveRecord::Migration[6.1]
def change
add_index :users, :email, unique: true
end
end
class AddPasswordDigestToUsers < ActiveRecord::Migration[6.1]
def change
add_column :users, :password_digest, :string
end
end
require "test_helper"
class UsersControllerTest < ActionDispatch::IntegrationTest
test "should get new" do
get signup_path
assert_response :success
end
end
#empty
\ No newline at end of file
require "test_helper"
class SiteLayoutTest < ActionDispatch::IntegrationTest
test "layout links" do
get root_path
assert_template 'static_pages/home'
assert_select "a[href=?]", root_path, count: 2
assert_select "a[href=?]", help_path
assert_select "a[href=?]", about_path
assert_select "a[href=?]", contact_path
end
end
require "test_helper"
class UsersSignupTest < ActionDispatch::IntegrationTest
test "invalid signup information" do
get signup_path
assert_no_difference 'User.count' do
post users_path, params: { user: { name: "",
email: "user@invalid",
password: "foo",
password_confirmation: "bar" } }
end
assert_template 'users/new'
end
test "valid signup information" do
get signup_path
assert_difference 'User.count', 1 do
post users_path, params: { user: { name: "Example User",
email: "user@example.com",
password: "password",
password_confirmation: "password" } }
end
follow_redirect!
assert_template 'users/show'
end
end
require "test_helper"
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
test "should be valid" do
assert @user.valid?
end
test "name should be present" do
@user.name = " "
assert_not @user.valid?
end
test "email should be present" do
@user.email = " "
assert_not @user.valid?
end
test "name should not be too long" do
@user.name = "a" * 51
assert_not @user.valid?
end
test "email should not be too long" do
@user.email = "a" * 244 + "@example.com"
assert_not @user.valid?
end
test "email validation should accept valid addresses" do
valid_addresses = %w[user@example.com USER@foo.COM A_US-ER@foo.bar.org
first.last@foo.jp alice+bob@baz.cn]
valid_addresses.each do |valid_addresses|
@user.email = valid_addresses
assert @user.valid?, "#{valid_addresses.inspect} should be valid"
end
end
test "email addresses should be unique" do
duplicate_user = @user.dup
@user.save
assert_not duplicate_user.valid?
end
test "password should be present (nonblank)" do
@user.password = @user.password_confirmation = " " * 6
assert_not @user.valid?
end
test "password should hav a minimum length" do
@user.password = @user.password_confirmation = "a" * 5
assert_not @user.valid?
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment