Merge remote-tracking branch 'upstream/with_test_code'
This commit is contained in:
commit
1e860fa797
2
Gemfile
2
Gemfile
|
@ -24,7 +24,7 @@ gem 'jbuilder', '~> 2.0'
|
|||
gem 'sdoc', '~> 0.4.0', group: :doc
|
||||
|
||||
# Use ActiveModel has_secure_password
|
||||
# gem 'bcrypt', '~> 3.1.7'
|
||||
gem 'bcrypt', '~> 3.1.7'
|
||||
|
||||
# Use Unicorn as the app server
|
||||
# gem 'unicorn'
|
||||
|
|
223
Gemfile.lock
223
Gemfile.lock
|
@ -1,223 +0,0 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actionmailer (4.2.5)
|
||||
actionpack (= 4.2.5)
|
||||
actionview (= 4.2.5)
|
||||
activejob (= 4.2.5)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
actionpack (4.2.5)
|
||||
actionview (= 4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
rack (~> 1.6)
|
||||
rack-test (~> 0.6.2)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
activejob (4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
globalid (>= 0.3.0)
|
||||
activemodel (4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
builder (~> 3.1)
|
||||
activerecord (4.2.5)
|
||||
activemodel (= 4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
arel (~> 6.0)
|
||||
activesupport (4.2.5)
|
||||
i18n (~> 0.7)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.3, >= 0.3.4)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.0)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
arel (6.0.3)
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
builder (3.2.2)
|
||||
byebug (9.0.6)
|
||||
capybara (2.11.0)
|
||||
addressable
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
rack-test (>= 0.5.4)
|
||||
xpath (~> 2.0)
|
||||
childprocess (0.5.9)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
coffee-rails (4.1.1)
|
||||
coffee-script (>= 2.2.0)
|
||||
railties (>= 4.0.0, < 5.1.x)
|
||||
coffee-script (2.4.1)
|
||||
coffee-script-source
|
||||
execjs
|
||||
coffee-script-source (1.11.1)
|
||||
concurrent-ruby (1.0.2)
|
||||
database_cleaner (1.5.3)
|
||||
debug_inspector (0.0.2)
|
||||
diff-lcs (1.2.5)
|
||||
erubis (2.7.0)
|
||||
execjs (2.7.0)
|
||||
factory_girl (4.7.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_girl_rails (4.7.0)
|
||||
factory_girl (~> 4.7.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.6.6)
|
||||
i18n (~> 0.5)
|
||||
ffi (1.9.14)
|
||||
globalid (0.3.7)
|
||||
activesupport (>= 4.1.0)
|
||||
i18n (0.7.0)
|
||||
jbuilder (2.6.1)
|
||||
activesupport (>= 3.0.0, < 5.1)
|
||||
multi_json (~> 1.2)
|
||||
jquery-rails (4.2.1)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (1.8.3)
|
||||
launchy (2.4.3)
|
||||
addressable (~> 2.3)
|
||||
libv8 (3.16.14.17)
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.6.4)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mime-types (3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mini_portile2 (2.1.0)
|
||||
minitest (5.10.1)
|
||||
multi_json (1.12.1)
|
||||
nokogiri (1.6.8.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
public_suffix (2.0.4)
|
||||
rack (1.6.5)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (4.2.5)
|
||||
actionmailer (= 4.2.5)
|
||||
actionpack (= 4.2.5)
|
||||
actionview (= 4.2.5)
|
||||
activejob (= 4.2.5)
|
||||
activemodel (= 4.2.5)
|
||||
activerecord (= 4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 4.2.5)
|
||||
sprockets-rails
|
||||
rails-deprecated_sanitizer (1.0.3)
|
||||
activesupport (>= 4.2.0.alpha)
|
||||
rails-dom-testing (1.0.7)
|
||||
activesupport (>= 4.2.0.beta, < 5.0)
|
||||
nokogiri (~> 1.6.0)
|
||||
rails-deprecated_sanitizer (>= 1.0.1)
|
||||
rails-html-sanitizer (1.0.3)
|
||||
loofah (~> 2.0)
|
||||
railties (4.2.5)
|
||||
actionpack (= 4.2.5)
|
||||
activesupport (= 4.2.5)
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rake (11.3.0)
|
||||
rdoc (4.3.0)
|
||||
ref (2.0.0)
|
||||
rspec-core (3.5.4)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-expectations (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-mocks (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-rails (3.5.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-support (3.5.0)
|
||||
rubyzip (1.2.0)
|
||||
sass (3.4.22)
|
||||
sass-rails (5.0.6)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
sdoc (0.4.2)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
rdoc (~> 4.0)
|
||||
selenium-webdriver (3.0.3)
|
||||
childprocess (~> 0.5)
|
||||
rubyzip (~> 1.0)
|
||||
websocket (~> 1.0)
|
||||
spring (2.0.0)
|
||||
activesupport (>= 4.2)
|
||||
sprockets (3.7.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.0)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.3.12)
|
||||
therubyracer (0.12.2)
|
||||
libv8 (~> 3.16.14.0)
|
||||
ref
|
||||
thor (0.19.4)
|
||||
thread_safe (0.3.5)
|
||||
tilt (2.0.5)
|
||||
turbolinks (5.0.1)
|
||||
turbolinks-source (~> 5)
|
||||
turbolinks-source (5.0.0)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.0.4)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
web-console (2.3.0)
|
||||
activemodel (>= 4.0)
|
||||
binding_of_caller (>= 0.7.2)
|
||||
railties (>= 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
websocket (1.2.3)
|
||||
xpath (2.0.0)
|
||||
nokogiri (~> 1.3)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
byebug
|
||||
capybara
|
||||
coffee-rails (~> 4.1.0)
|
||||
database_cleaner
|
||||
factory_girl_rails (~> 4.7.0)
|
||||
faker
|
||||
jbuilder (~> 2.0)
|
||||
jquery-rails
|
||||
launchy
|
||||
rails (= 4.2.5)
|
||||
rspec-rails (~> 3.5.2)
|
||||
sass-rails (~> 5.0)
|
||||
sdoc (~> 0.4.0)
|
||||
selenium-webdriver
|
||||
spring
|
||||
sqlite3
|
||||
therubyracer
|
||||
turbolinks
|
||||
uglifier (>= 1.3.0)
|
||||
web-console (~> 2.0)
|
||||
|
||||
BUNDLED WITH
|
||||
1.13.6
|
|
@ -0,0 +1,3 @@
|
|||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
|
@ -0,0 +1,3 @@
|
|||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the Sessions controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -0,0 +1,3 @@
|
|||
// Place all the styles related to the Users controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
|
@ -2,4 +2,15 @@ class ApplicationController < ActionController::Base
|
|||
# Prevent CSRF attacks by raising an exception.
|
||||
# For APIs, you may want to use :null_session instead.
|
||||
protect_from_forgery with: :exception
|
||||
|
||||
def authenticate
|
||||
render status: :unauthorized, nothing: true unless session['user_id']
|
||||
end
|
||||
|
||||
private
|
||||
def current_user
|
||||
@current_user ||= User.find(session[:user_id]) if session[:user_id]
|
||||
end
|
||||
|
||||
helper_method :current_user
|
||||
end
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
class SessionsController < ApplicationController
|
||||
|
||||
# 除登录之外,其余接口必须在登录状态下访问
|
||||
before_action :authenticate, except: [ :create ]
|
||||
|
||||
def create
|
||||
user = User.find_by(email: params[:email])
|
||||
if user && user.authenticate(params[:password])
|
||||
session[:user_id] = user.id
|
||||
render status: :ok, text: 'login success'
|
||||
else
|
||||
render status: :ok, text: 'account or password is not correct'
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
session.delete :user_id
|
||||
@current_user &&= nil
|
||||
render status: :ok, nothing: true
|
||||
end
|
||||
|
||||
def show
|
||||
render 'show'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,47 @@
|
|||
class UsersController < ApplicationController
|
||||
|
||||
before_action :authenticate, except: [ :emailExist, :usernameExist, :create ]
|
||||
|
||||
def emailExist
|
||||
if checkExist?(:email, params[:email])
|
||||
render :text => 'exist'
|
||||
else
|
||||
render :text => 'not exist'
|
||||
end
|
||||
end
|
||||
|
||||
def usernameExist
|
||||
if checkExist?(:name, params[:username])
|
||||
render :text => 'exist'
|
||||
else
|
||||
render :text => 'not exist'
|
||||
end
|
||||
end
|
||||
|
||||
def create
|
||||
@user = User.new(user_params)
|
||||
if @user.save
|
||||
render status: :created, nothing: true
|
||||
else
|
||||
render json: @user.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@user = current_user
|
||||
if @user.update(user_params)
|
||||
render 'show'
|
||||
else
|
||||
render json:current_user.errors, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
def checkExist?(field_name, value)
|
||||
User.exists?(field_name => value)
|
||||
end
|
||||
|
||||
def user_params
|
||||
params.require(:user).permit(:name, :password, :password_confirmation, :email)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module SessionsHelper
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
module UsersHelper
|
||||
end
|
|
@ -1,3 +1,14 @@
|
|||
class Project < ActiveRecord::Base
|
||||
has_and_belongs_to_many :users
|
||||
|
||||
validate :require_at_least_on_user # 项目中最少要有一个用户
|
||||
validates :name, presence: true, length: { minimum: 1, maximum: 50 }, uniqueness: true
|
||||
|
||||
private
|
||||
|
||||
def require_at_least_on_user
|
||||
if !users || users.size == 0 # 这里使用size,可以智能选择需不需要查询数据库
|
||||
errors[:users] = 'at least one user in the project'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,4 +3,11 @@ class User < ActiveRecord::Base
|
|||
has_and_belongs_to_many :missions
|
||||
|
||||
has_many :notes
|
||||
|
||||
has_secure_password # 等价于验证password_confirm和password是否相等,并且验证password是否存在
|
||||
|
||||
validates :name, presence: true, uniqueness: true, length: { maximum: 30 }
|
||||
validates :email, presence: true, uniqueness: true, length: { maximum: 50},
|
||||
format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i }
|
||||
validates :password, length: { minimum: 6 }
|
||||
end
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
json.extract! current_user, :id, :name, :email, :created_at
|
|
@ -0,0 +1 @@
|
|||
json.extract! @user, :id, :name, :email, :created_at
|
|
@ -0,0 +1,3 @@
|
|||
Time::DATE_FORMATS[:default] = '%Y-%m-%d %H:%M:%S'
|
||||
Time::DATE_FORMATS[:full] = '%Y-%m-%d %H:%M:%S'
|
||||
Time::DATE_FORMATS[:short_ordinal] = lambda { |time| time.strftime("%B #{time.day.ordinalize}") }
|
|
@ -53,4 +53,13 @@ Rails.application.routes.draw do
|
|||
# # (app/controllers/admin/products_controller.rb)
|
||||
# resources :products
|
||||
# end
|
||||
|
||||
get 'users/emailExist' => 'users#emailExist'
|
||||
get 'users/usernameExist' => 'users#usernameExist'
|
||||
post 'users' => 'users#create'
|
||||
patch 'user/current' => 'users#update'
|
||||
|
||||
post 'sessions' => 'sessions#create'
|
||||
delete 'session' => 'sessions#destroy'
|
||||
get 'session' => 'sessions#show'
|
||||
end
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class ChangeContentInComments < ActiveRecord::Migration
|
||||
def change
|
||||
change_column :comments, :content, :text
|
||||
end
|
||||
end
|
|
@ -11,10 +11,10 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20161210055513) do
|
||||
ActiveRecord::Schema.define(version: 20161211080456) do
|
||||
|
||||
create_table "comments", force: :cascade do |t|
|
||||
t.string "content"
|
||||
t.text "content"
|
||||
t.integer "mission_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe SessionsController, type: :controller do
|
||||
|
||||
before :each do
|
||||
@user1 = create(:user)
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
|
||||
# 合法流程校验
|
||||
context 'with legal account' do
|
||||
|
||||
before :each do
|
||||
post :create, email: @user1.email, password: @user1.password
|
||||
end
|
||||
|
||||
it 'should get correct email and password' do
|
||||
actual_email = @user1.email
|
||||
actual_password = @user1.password
|
||||
expect(controller.params[:email]).to eq(actual_email)
|
||||
expect(controller.params[:password]).to eq(actual_password)
|
||||
end
|
||||
|
||||
it 'should authenticate success' do
|
||||
expect(controller.session[:user_id]).to eq @user1.id
|
||||
end
|
||||
|
||||
it 'should get ok and text: login success' do
|
||||
expect(response).to have_http_status :ok
|
||||
expect(response.body).to eq 'login success'
|
||||
end
|
||||
end
|
||||
|
||||
# 非法参数测试
|
||||
context 'with illegal account' do
|
||||
|
||||
before :each do
|
||||
post :create, email: @user1.email, password: 'wrong_password'
|
||||
end
|
||||
|
||||
it 'does not authenticate success' do
|
||||
expect(controller.session[:user_id].nil?).to be true
|
||||
end
|
||||
|
||||
it 'return with 200 and text: account or password is not correct' do
|
||||
expect(response).to have_http_status :ok
|
||||
expect(response.body).to eq 'account or password is not correct'
|
||||
end
|
||||
|
||||
it 'should not raise error without param email or password' do
|
||||
expect {
|
||||
post :create, email: @user1.email
|
||||
}.not_to raise_error
|
||||
expect {
|
||||
post :create, password: 'wrong_password'
|
||||
}.not_to raise_error
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
describe 'DELETE #destroy' do
|
||||
it 'should destroy user id in session' do
|
||||
post :create, email:@user1.email, password: @user1.password
|
||||
expect(controller.session[:user_id].nil?).to be false
|
||||
delete :destroy
|
||||
expect(controller.session[:user_id].nil?).to be true
|
||||
end
|
||||
|
||||
it 'should return 401 without login' do
|
||||
delete :destroy
|
||||
expect(response).to have_http_status :unauthorized
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #show' do
|
||||
|
||||
context 'after login' do
|
||||
before :each do
|
||||
post :create, email:@user1.email, password: @user1.password
|
||||
get :show, format: 'json'
|
||||
end
|
||||
|
||||
it 'should render show template' do
|
||||
expect(response).to render_template 'show'
|
||||
end
|
||||
|
||||
it 'should return user in json' do
|
||||
userInfo = assigns[:current_user]
|
||||
expect(userInfo.id).to eq @user1.id
|
||||
end
|
||||
end
|
||||
|
||||
it 'should renturn 401 without login' do
|
||||
get :show, format: 'json'
|
||||
expect(response).to have_http_status :unauthorized
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,150 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe UsersController, type: :controller do
|
||||
let(:user) { build(:user_with_sequence_number) }
|
||||
let(:user_with_fixed_info){ create(:user)}
|
||||
let(:valid_attributes){ attributes_for(:user) }
|
||||
let(:invalid_attributes){ attributes_for(:user, email: nil, name: 'username2000') }
|
||||
|
||||
describe 'GET #emailExist' do
|
||||
it 'valid email' do
|
||||
get :emailExist, email: user.email
|
||||
expect(response.body).to eq 'not exist'
|
||||
end
|
||||
|
||||
it 'duplicated email' do
|
||||
user = create(:user_with_sequence_number)
|
||||
get :emailExist, email: user.email
|
||||
expect(response.body).to eq 'exist'
|
||||
end
|
||||
|
||||
it 'should not throw exception with no email param' do
|
||||
get :emailExist # 不会失败,则证明没有异常
|
||||
get :emailExist, other_param: 'test'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #usernameExist' do
|
||||
it 'valid username' do
|
||||
get :usernameExist, username: user.name
|
||||
expect(response.body).to eq 'not exist'
|
||||
end
|
||||
|
||||
it 'duplicated username' do
|
||||
user = create(:user_with_sequence_number)
|
||||
get :usernameExist, username: user.name
|
||||
expect(response.body).to eq 'exist'
|
||||
end
|
||||
|
||||
it 'should not throw exception with no username param' do
|
||||
get :usernameExist
|
||||
get :usernameExist, other_param: 'test'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'POST #create' do
|
||||
context 'success with valid attributes' do
|
||||
before :each do
|
||||
post :create, user: valid_attributes
|
||||
end
|
||||
|
||||
it 'should create user' do
|
||||
expect(User.exists?(assigns[:user].id)).to be true
|
||||
end
|
||||
|
||||
it 'should response with 201' do
|
||||
expect(response).to have_http_status :created
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'fail with invalid attributes' do
|
||||
# 已经在model测试中充分验证校对条件,所以这里只对使用电子邮箱为空的非法条件
|
||||
before :each do
|
||||
post :create, user: invalid_attributes
|
||||
end
|
||||
|
||||
it 'does not save the new user' do
|
||||
expect(User.exists? name: 'username2000').to be false
|
||||
end
|
||||
|
||||
it 'should return errors' do
|
||||
error_message = JSON.parse response.body
|
||||
expect(error_message['email'].nil?).to be false
|
||||
expect(error_message['email']).not_to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'deal with params more or less than required' do
|
||||
|
||||
let(:data_to_send) { { :name => 'username', :email => '1261138729@qq.com',
|
||||
:password => 'secret', :password_confirmation => 'secret',
|
||||
:more_field => 'test'} }
|
||||
|
||||
it 'should throw exception without param[:user]' do
|
||||
expect {
|
||||
post :create
|
||||
}.to raise_error ActionController::ParameterMissing
|
||||
end
|
||||
|
||||
it 'should not throw exception' do
|
||||
expect {
|
||||
post :create, user: data_to_send, other_param: 'test'
|
||||
}.to_not raise_error
|
||||
end
|
||||
|
||||
it 'should not accept other params' do
|
||||
post :create, user: data_to_send
|
||||
user = assigns(:user)
|
||||
expect(user.has_attribute? :more_field).to eq false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PATCH #update' do
|
||||
|
||||
context 'with valid attributes' do
|
||||
|
||||
before :each do
|
||||
# 假设已经登录了
|
||||
allow(controller).to receive(:authenticate){ true }
|
||||
allow(controller).to receive(:current_user).and_return(User.find user_with_fixed_info.id)
|
||||
patch :update, user: valid_attributes, format: 'json'
|
||||
end
|
||||
|
||||
it 'should located current user' do
|
||||
expect(assigns[:user]).to eq user_with_fixed_info
|
||||
end
|
||||
|
||||
it 'should render show' do
|
||||
expect(response).to render_template 'show'
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
context 'with invalid attributes' do
|
||||
before :each do
|
||||
# 假设已经登录了
|
||||
allow(controller).to receive(:authenticate){ true }
|
||||
allow(controller).to receive(:current_user).and_return(User.find user_with_fixed_info.id)
|
||||
patch :update, user: invalid_attributes, format: 'json'
|
||||
end
|
||||
|
||||
it 'does not change current user' do
|
||||
expect(assigns[:user]).to eq user_with_fixed_info
|
||||
end
|
||||
|
||||
it 'should return error messages and error status' do
|
||||
error_message = JSON.parse response.body
|
||||
expect(error_message['email'].nil?).to be false
|
||||
expect(error_message['email']).not_to be_empty
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it 'should login first' do
|
||||
patch :update, user:valid_attributes, format: 'json'
|
||||
expect(response).to have_http_status :unauthorized
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
require 'faker'
|
||||
FactoryGirl.define do
|
||||
factory :project do
|
||||
name { Faker::Name.title }
|
||||
sequence(:content){ |n| "This is project content#{n}"}
|
||||
|
||||
after(:build) do |project|
|
||||
3.times { project.users << FactoryGirl.create(:user_with_sequence_number) }
|
||||
end
|
||||
|
||||
factory :project_name_length_gt_20 do
|
||||
name { Faker::Internet.password(51, 51) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,26 @@
|
|||
require 'faker'
|
||||
FactoryGirl.define do
|
||||
factory :user do
|
||||
name { Faker::Name.name }
|
||||
email { Faker::Internet.email }
|
||||
password 'secret'
|
||||
password_confirmation 'secret'
|
||||
|
||||
factory :user_with_sequence_number do
|
||||
sequence(:email){ |n| "email#{n}@example.com" }
|
||||
sequence(:name){ |n| "username#{n}"}
|
||||
end
|
||||
|
||||
factory :user_name_length_gt_30 do
|
||||
name Faker::Internet.password(31, 31)
|
||||
end
|
||||
|
||||
factory :user_email_length_gt_50 do
|
||||
email '12345678901234567890123456789012345678901234567890@qq.com'
|
||||
end
|
||||
|
||||
factory :user_password_length_lt_6 do
|
||||
password { Faker::Internet.password( 0, 5 ) }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,32 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Project, type: :model do
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:project)).to be_valid
|
||||
end
|
||||
|
||||
describe 'users test' do
|
||||
it 'has at least on user' do
|
||||
project_with_no_user = build(:project)
|
||||
project_with_no_user.users = []
|
||||
project_with_no_user.valid?
|
||||
expect(project_with_no_user.errors[:users].size).to eq(1)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'name test' do
|
||||
it 'does not allow absence of name' do
|
||||
expect(build(:project, name: nil)).to_not be_valid
|
||||
end
|
||||
|
||||
it 'length of name in [1,20]' do
|
||||
expect(build(:project_name_length_gt_20)).to_not be_valid
|
||||
end
|
||||
|
||||
it 'does not allow duplicate name' do
|
||||
create(:project, name: 'project1')
|
||||
expect(build(:project, name: 'project1')).to_not be_valid
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,74 @@
|
|||
require 'rails_helper'
|
||||
|
||||
RSpec.describe User, type: :model do
|
||||
|
||||
it 'has a valid factory' do
|
||||
expect(build(:user)).to be_valid
|
||||
end
|
||||
|
||||
describe 'username test' do
|
||||
it 'does not allow absence of username' do
|
||||
expect(build(:user, name: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
it 'does not allow duplicate username' do
|
||||
create(:user_with_sequence_number, name: 'ccx')
|
||||
user_duplicated_name = build(:user_with_sequence_number, name: 'ccx')
|
||||
user_duplicated_name.valid?
|
||||
expect(user_duplicated_name.errors[:name].size).to eq(1)
|
||||
end
|
||||
|
||||
it 'does not allow name length > 30' do
|
||||
expect(build(:user_name_length_gt_30)).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'email test' do
|
||||
it 'does not allow absence of email' do
|
||||
expect(build(:user, email: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
it 'does not allow duplicate email' do
|
||||
create(:user_with_sequence_number, email: '1261138729@qq.com')
|
||||
user_duplicated_email = build(:user_with_sequence_number, email: '1261138729@qq.com')
|
||||
user_duplicated_email.valid?
|
||||
expect(user_duplicated_email.errors[:email].size).to eq(1)
|
||||
end
|
||||
|
||||
it 'does not allow email length > 50' do
|
||||
expect(build(:user_email_length_gt_50)).not_to be_valid
|
||||
end
|
||||
|
||||
it 'email should match /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i' do
|
||||
expect(build(:user, email: '123qq.com')).not_to be_valid
|
||||
expect(build(:user, email: '@qq.com')).not_to be_valid
|
||||
expect(build(:user, email: '123@qq')).not_to be_valid
|
||||
expect(build(:user, email: '123@.com')).not_to be_valid
|
||||
expect(build(:user, email: '123@qq.')).not_to be_valid
|
||||
end
|
||||
end
|
||||
|
||||
describe 'password test' do
|
||||
it 'does not allow password length < 6' do
|
||||
expect(build(:user_password_length_lt_6)).not_to be_valid
|
||||
end
|
||||
|
||||
it 'password_confirmation should match password when password_confirmation not nil' do
|
||||
expect(build(:user, password: '123456', password_confirmation: '654321')).to_not be_valid
|
||||
end
|
||||
|
||||
it 'do not trigger match when password_confirmation nil' do
|
||||
expect(build(:user, password: '123456', password_confirmation: nil)).to be_valid
|
||||
end
|
||||
|
||||
it 'does not allow password absence on create' do
|
||||
expect(build(:user, password: nil, password_confirmation: nil)).to_not be_valid
|
||||
end
|
||||
|
||||
it 'can authenticate' do
|
||||
user = create(:user, password: '123456', password_confirmation: '123456')
|
||||
expect(user.authenticate('123456')).to be_instance_of User
|
||||
expect(user.authenticate('654312')).to be false
|
||||
end
|
||||
end
|
||||
end
|
|
@ -125,7 +125,13 @@ RSpec.configure do |config|
|
|||
config.after(:each) do
|
||||
DatabaseCleaner.clean
|
||||
end
|
||||
|
||||
|
||||
# 使rsepc测试中可以获取jbuilder的结果
|
||||
config.render_views = true
|
||||
|
||||
# 在rspec中可以使用url_helper
|
||||
config.include Rails.application.routes.url_helpers
|
||||
|
||||
# Include Factory Girl syntax to simplify calls to factories
|
||||
config.include FactoryGirl::Syntax::Methods
|
||||
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
content: MyString
|
||||
mission_id:
|
||||
|
||||
two:
|
||||
content: MyString
|
||||
mission_id:
|
|
@ -1,13 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
deadline: 2016-12-10 12:48:43
|
||||
priority: 1
|
||||
status: MyString
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
deadline: 2016-12-10 12:48:43
|
||||
priority: 1
|
||||
status: MyString
|
|
@ -1,9 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
content:
|
||||
user_id:
|
||||
|
||||
two:
|
||||
content:
|
||||
user_id:
|
|
@ -1,9 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
content: MyString
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
content: MyString
|
|
@ -1,7 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
content: MyString
|
||||
|
||||
two:
|
||||
content: MyString
|
|
@ -1,11 +0,0 @@
|
|||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
password_digest: MyString
|
||||
email: MyString
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
password_digest: MyString
|
||||
email: MyString
|
|
@ -1,7 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class CommentTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class MissionTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class NoteTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class ProjectTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class ShareTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
|
@ -1,7 +0,0 @@
|
|||
require 'test_helper'
|
||||
|
||||
class UserTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
|
@ -1,10 +0,0 @@
|
|||
ENV['RAILS_ENV'] ||= 'test'
|
||||
require File.expand_path('../../config/environment', __FILE__)
|
||||
require 'rails/test_help'
|
||||
|
||||
class ActiveSupport::TestCase
|
||||
# Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order.
|
||||
fixtures :all
|
||||
|
||||
# Add more helper methods to be used by all tests here...
|
||||
end
|
Loading…
Reference in New Issue