diff --git a/.gitignore b/.gitignore
index 48fb168f..d869f9f9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,4 @@
# Ignore Byebug command history file.
.byebug_history
+.env
diff --git a/Gemfile b/Gemfile
index c029c6da..734b0142 100644
--- a/Gemfile
+++ b/Gemfile
@@ -8,7 +8,7 @@ git_source(:github) do |repo_name|
end
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
-gem 'rails', '~> 5.0.2'
+gem 'rails', '~> 5.1.6'
# Use postgresql as the database for Active Record
gem 'pg', '~> 0.18'
# Use Puma as the app server
@@ -40,6 +40,9 @@ gem 'jbuilder', '~> 2.5'
gem 'foundation-rails'
gem 'autoprefixer-rails'
+gem 'omniauth'
+gem 'omniauth-github'
+
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug', platform: :mri
@@ -65,6 +68,8 @@ group :development do
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
gem 'spring'
gem 'spring-watcher-listen', '~> 2.0.0'
+
+ gem 'dotenv-rails'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
diff --git a/Gemfile.lock b/Gemfile.lock
index f03db854..06923d6e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,45 +1,45 @@
GEM
remote: https://rubygems.org/
specs:
- actioncable (5.0.7)
- actionpack (= 5.0.7)
- nio4r (>= 1.2, < 3.0)
+ actioncable (5.1.6)
+ actionpack (= 5.1.6)
+ nio4r (~> 2.0)
websocket-driver (~> 0.6.1)
- actionmailer (5.0.7)
- actionpack (= 5.0.7)
- actionview (= 5.0.7)
- activejob (= 5.0.7)
+ actionmailer (5.1.6)
+ actionpack (= 5.1.6)
+ actionview (= 5.1.6)
+ activejob (= 5.1.6)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
- actionpack (5.0.7)
- actionview (= 5.0.7)
- activesupport (= 5.0.7)
+ actionpack (5.1.6)
+ actionview (= 5.1.6)
+ activesupport (= 5.1.6)
rack (~> 2.0)
- rack-test (~> 0.6.3)
+ rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
- actionview (5.0.7)
- activesupport (= 5.0.7)
+ actionview (5.1.6)
+ activesupport (= 5.1.6)
builder (~> 3.1)
- erubis (~> 2.7.0)
+ erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
- activejob (5.0.7)
- activesupport (= 5.0.7)
+ activejob (5.1.6)
+ activesupport (= 5.1.6)
globalid (>= 0.3.6)
- activemodel (5.0.7)
- activesupport (= 5.0.7)
- activerecord (5.0.7)
- activemodel (= 5.0.7)
- activesupport (= 5.0.7)
- arel (~> 7.0)
- activesupport (5.0.7)
+ activemodel (5.1.6)
+ activesupport (= 5.1.6)
+ activerecord (5.1.6)
+ activemodel (= 5.1.6)
+ activesupport (= 5.1.6)
+ arel (~> 8.0)
+ activesupport (5.1.6)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
ansi (1.5.0)
- arel (7.1.4)
+ arel (8.0.0)
autoprefixer-rails (8.2.0)
execjs
babel-source (5.8.35)
@@ -62,10 +62,15 @@ GEM
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.0.5)
- crass (1.0.3)
+ crass (1.0.4)
+ dotenv (2.2.2)
+ dotenv-rails (2.2.2)
+ dotenv (= 2.2.2)
+ railties (>= 3.2, < 6.0)
erubi (1.7.1)
- erubis (2.7.0)
execjs (2.7.0)
+ faraday (0.12.2)
+ multipart-post (>= 1.2, < 3)
ffi (1.9.23)
foundation-rails (6.4.3.0)
railties (>= 3.1.0)
@@ -73,7 +78,8 @@ GEM
sprockets-es6 (>= 0.9.0)
globalid (0.4.1)
activesupport (>= 4.2.0)
- i18n (1.0.0)
+ hashie (3.5.7)
+ i18n (1.0.1)
concurrent-ruby (~> 1.0)
jbuilder (2.7.0)
activesupport (>= 4.2.0)
@@ -82,6 +88,7 @@ GEM
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
+ jwt (1.5.6)
listen (3.0.8)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
@@ -108,9 +115,26 @@ GEM
minitest (~> 5.0)
rails (>= 4.1)
multi_json (1.13.1)
+ multi_xml (0.6.0)
+ multipart-post (2.0.0)
nio4r (2.3.0)
nokogiri (1.8.2)
mini_portile2 (~> 2.3.0)
+ oauth2 (1.4.0)
+ faraday (>= 0.8, < 0.13)
+ jwt (~> 1.0)
+ multi_json (~> 1.3)
+ multi_xml (~> 0.5)
+ rack (>= 1.2, < 3)
+ omniauth (1.8.1)
+ hashie (>= 3.4.6, < 3.6.0)
+ rack (>= 1.6.2, < 3)
+ omniauth-github (1.3.0)
+ omniauth (~> 1.5)
+ omniauth-oauth2 (>= 1.4.0, < 2.0)
+ omniauth-oauth2 (1.5.0)
+ oauth2 (~> 1.1)
+ omniauth (~> 1.2)
pg (0.21.0)
pry (0.11.3)
coderay (~> 1.1.0)
@@ -118,29 +142,29 @@ GEM
pry-rails (0.3.6)
pry (>= 0.10.4)
puma (3.11.3)
- rack (2.0.4)
- rack-test (0.6.3)
- rack (>= 1.0)
- rails (5.0.7)
- actioncable (= 5.0.7)
- actionmailer (= 5.0.7)
- actionpack (= 5.0.7)
- actionview (= 5.0.7)
- activejob (= 5.0.7)
- activemodel (= 5.0.7)
- activerecord (= 5.0.7)
- activesupport (= 5.0.7)
+ rack (2.0.5)
+ rack-test (1.0.0)
+ rack (>= 1.0, < 3)
+ rails (5.1.6)
+ actioncable (= 5.1.6)
+ actionmailer (= 5.1.6)
+ actionpack (= 5.1.6)
+ actionview (= 5.1.6)
+ activejob (= 5.1.6)
+ activemodel (= 5.1.6)
+ activerecord (= 5.1.6)
+ activesupport (= 5.1.6)
bundler (>= 1.3.0)
- railties (= 5.0.7)
+ railties (= 5.1.6)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
- railties (5.0.7)
- actionpack (= 5.0.7)
- activesupport (= 5.0.7)
+ railties (5.1.6)
+ actionpack (= 5.1.6)
+ activesupport (= 5.1.6)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
@@ -199,6 +223,7 @@ DEPENDENCIES
better_errors
byebug
coffee-rails (~> 4.2)
+ dotenv-rails
foundation-rails
jbuilder (~> 2.5)
jquery-rails
@@ -207,10 +232,12 @@ DEPENDENCIES
minitest-reporters
minitest-skip
minitest-spec-rails
+ omniauth
+ omniauth-github
pg (~> 0.18)
pry-rails
puma (~> 3.0)
- rails (~> 5.0.2)
+ rails (~> 5.1.6)
sass-rails (~> 5.0)
spring
spring-watcher-listen (~> 2.0.0)
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index c12c7c17..a8b54748 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -2,16 +2,26 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :find_user
+ # before_action :require_login #____WHY IS THIS NOT WORKING____
def render_404
# DPR: this will actually render a 404 page in production
raise ActionController::RoutingError.new('Not Found')
end
+
private
+ # def require_login
+ # unless session[:user_id]
+ # flash[:failure] = 'You must be logged in to do that'
+ # redirect_to root_path
+ # end
+ # end
+
def find_user
if session[:user_id]
@login_user = User.find_by(id: session[:user_id])
end
end
+
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 5bce99e6..c0ac0d48 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -1,27 +1,22 @@
class SessionsController < ApplicationController
- def login_form
- end
- def login
- username = params[:username]
- if username and user = User.find_by(username: username)
- session[:user_id] = user.id
- flash[:status] = :success
- flash[:result_text] = "Successfully logged in as existing user #{user.username}"
- else
- user = User.new(username: username)
- if user.save
- session[:user_id] = user.id
- flash[:status] = :success
- flash[:result_text] = "Successfully created new user #{user.username} with ID #{user.id}"
- else
- flash.now[:status] = :failure
- flash.now[:result_text] = "Could not log in"
- flash.now[:messages] = user.errors.messages
- render "login_form", status: :bad_request
+ def create
+ auth_hash = request.env['omniauth.auth']
+
+ if auth_hash['uid']
+ user = User.get_user(auth_hash)
+ if user.nil?
+ flash[:result_text] = 'Could not log in'
+ flash[:messages] = user.errors.messages
+ redirect_to root_path
return
end
+ session[:user_id] = user.id
+ flash[:success] = 'Successfully logged in'
+ else
+ flash[:result_text] = "Could not log in"
end
+
redirect_to root_path
end
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 73b42652..618391bf 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,4 +1,6 @@
class UsersController < ApplicationController
+ before_action :require_login
+
def index
@users = User.all
end
@@ -7,4 +9,12 @@ def show
@user = User.find_by(id: params[:id])
render_404 unless @user
end
+
+ private
+
+ def require_login
+ unless session[:user_id]
+ redirect_to root_path
+ end
+ end
end
diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb
index 2020bee4..81168cb0 100644
--- a/app/controllers/works_controller.rb
+++ b/app/controllers/works_controller.rb
@@ -3,6 +3,8 @@ class WorksController < ApplicationController
# of work we're dealing with
before_action :category_from_work, except: [:root, :index, :new, :create]
+ before_action :require_login, except: [:root]
+
def root
@albums = Work.best_albums
@books = Work.best_books
@@ -91,4 +93,12 @@ def category_from_work
render_404 unless @work
@media_category = @work.category.downcase.pluralize
end
+
+ def require_login
+ unless session[:user_id]
+ flash[:failure] = 'You must be logged in to do that'
+ redirect_to root_path
+ end
+ end
+
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 51b55d86..98b4f082 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -2,4 +2,8 @@ module ApplicationHelper
def render_date(date)
date.strftime("%b %e, %Y")
end
+
+ def email_or_name(user)
+ return user.name ? user.name : user.email
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 4cac8fe0..7ca99007 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,6 +1,25 @@
class User < ApplicationRecord
- has_many :votes
+ has_many :votes, dependent: :destroy
has_many :ranked_works, through: :votes, source: :work
- validates :username, uniqueness: true, presence: true
+ validates :uid, presence: true, uniqueness: true
+ validates :provider, presence: true
+ validates :email, presence: true # might be redundant with github needing an email
+
+ def self.get_user(data_hash)
+ user = User.find_by(uid: data_hash[:uid], provider: data_hash[:provider])
+ if user.nil?
+ user_data = {
+ uid: data_hash['uid'],
+ provider: data_hash['provider'],
+ name: data_hash['info']['name'],
+ email: data_hash['info']['email']
+ }
+ user = User.new(user_data)
+ return user.save ? user : nil
+ end
+ return user
+ end
+
+
end
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index 82ca0fdc..04e21ed2 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -26,10 +26,10 @@
<% if @login_user %>
- <%= link_to "Logged in as #{@login_user.username}", user_path(@login_user), class: "button" %>
+ <%= link_to "Logged in as #{email_or_name(@login_user)}", user_path(@login_user), class: "button" %>
<%= link_to "Log Out", logout_path, method: :post, class: "button" %>
<% else %>
- <%= link_to "Log In", login_path, class: "button" %>
+ <%= link_to "Log In", '/auth/github', class: "button" %>
<% end %>
diff --git a/app/views/users/index.html.erb b/app/views/users/index.html.erb
index 83570de1..4cce0922 100644
--- a/app/views/users/index.html.erb
+++ b/app/views/users/index.html.erb
@@ -2,7 +2,7 @@
- Username |
+ Name |
Votes |
Joined |
@@ -10,7 +10,7 @@
<% @users.each do |user| %>
- <%= link_to user.username, user_path(user) %> |
+ <%= link_to user.name, user_path(user) %> |
<%= user.votes.count %> |
<%= render_date user.created_at %> |
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index d6185ad7..e03820e2 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -1,4 +1,4 @@
-User Summary: <%= link_to @user.username, user_path(@user) %>
+User Summary: <%= link_to email_or_name(@user), user_path(@user) %>
Joined site <%= render_date @user.created_at %>
Votes
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
new file mode 100644
index 00000000..fd441612
--- /dev/null
+++ b/config/initializers/omniauth.rb
@@ -0,0 +1,3 @@
+Rails.application.config.middleware.use OmniAuth::Builder do
+ provider :github, ENV["GITHUB_CLIENT_ID"], ENV["GITHUB_CLIENT_SECRET"], scope: "user:email"
+end
diff --git a/config/routes.rb b/config/routes.rb
index a7e8af1d..0b59789e 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,12 +1,14 @@
Rails.application.routes.draw do
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'works#root'
- get '/login', to: 'sessions#login_form', as: 'login'
- post '/login', to: 'sessions#login'
+ get '/auth/:provider/callback', to: 'sessions#create', as: 'auth_callback'
post '/logout', to: 'sessions#logout', as: 'logout'
+
resources :works
post '/works/:id/upvote', to: 'works#upvote', as: 'upvote'
resources :users, only: [:index, :show]
+
+
end
diff --git a/db/migrate/20180417193410_update_user_table.rb b/db/migrate/20180417193410_update_user_table.rb
new file mode 100644
index 00000000..5d5f1644
--- /dev/null
+++ b/db/migrate/20180417193410_update_user_table.rb
@@ -0,0 +1,10 @@
+class UpdateUserTable < ActiveRecord::Migration[5.0]
+ def change
+ remove_column :users, :username
+
+ add_column :users, :name, :string
+ add_column :users, :email, :string
+ add_column :users, :uid, :integer
+ add_column :users, :provider, :string
+ end
+end
diff --git a/db/migrate/20180417194103_users_not_null_columns.rb b/db/migrate/20180417194103_users_not_null_columns.rb
new file mode 100644
index 00000000..fb7f00f4
--- /dev/null
+++ b/db/migrate/20180417194103_users_not_null_columns.rb
@@ -0,0 +1,6 @@
+class UsersNotNullColumns < ActiveRecord::Migration[5.0]
+ def change
+ change_column_null :users, :uid, false
+ change_column_null :users, :provider, false
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 6bc8ba5c..cf306c92 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,15 +10,18 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20170407164321) do
+ActiveRecord::Schema.define(version: 20180417194103) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "users", force: :cascade do |t|
- t.string "username"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
+ t.string "name"
+ t.string "email"
+ t.integer "uid", null: false
+ t.string "provider", null: false
end
create_table "votes", force: :cascade do |t|
diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb
index f641d15c..19a5f9f1 100644
--- a/test/controllers/sessions_controller_test.rb
+++ b/test/controllers/sessions_controller_test.rb
@@ -1,5 +1,82 @@
require "test_helper"
describe SessionsController do
+ describe 'auth_callback' do
+ it 'signs in an existing user' do
+ user = User.first
+ old_user_count = User.count
+ login(user)
+
+ must_redirect_to root_path
+ User.count.must_equal old_user_count
+ session[:user_id].must_equal user.id
+ end
+
+ it 'creates a new DB entry for a new user' do
+ user_data = {
+ name: 'A Name',
+ email: 'name@anemail.com',
+ uid: 99999,
+ provider: 'github'
+ }
+ user = User.new(user_data)
+ user.valid?.must_equal true
+
+ old_user_count = User.count
+
+
+ login(user)
+
+ must_redirect_to root_path
+ User.count.must_equal old_user_count + 1
+ session[:user_id] = User.last.id
+ end
+
+ it 'will not login a user if not enough information is returned from provider' do
+ user_data = {
+ name: 'A Name',
+ email: 'name@anemail.com',
+ provider: 'github'
+ }
+ user = User.new(user_data)
+ user.valid?.must_equal false
+
+ old_user_count = User.count
+
+
+ login(user)
+
+ must_redirect_to root_path
+ User.count.must_equal old_user_count
+ session[:user_id].must_be_nil
+ end
+
+ it 'will sign in a user that is already signed in' do
+ user = User.first
+ old_user_count = User.count
+
+ login(user)
+ session[:user_id].must_equal user.id
+
+ login(user)
+
+ must_redirect_to root_path
+ User.count.must_equal old_user_count
+ session[:user_id].must_equal user.id
+ end
+ end
+
+ describe 'logout' do
+ it 'logs out a logged in user' do
+ user = User.first
+
+ login(user)
+ session[:user_id].must_equal user.id
+
+ post logout_path
+
+ session[:user_id].must_be_nil
+ end
+ end
end
diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb
index d2c5cfbb..703e26e8 100644
--- a/test/controllers/users_controller_test.rb
+++ b/test/controllers/users_controller_test.rb
@@ -1,5 +1,42 @@
require 'test_helper'
describe UsersController do
+ before do
+ user = users(:dan)
+ login(user)
+ end
+
+ describe 'index' do
+ it 'must respond with success if there is more than one user' do
+ get users_path
+ must_respond_with :success
+ end
+
+ it 'must respond with success if there are no users' do
+ User.destroy_all
+
+ get users_path
+
+ must_respond_with :success
+ end
+ end
+
+ describe 'show' do
+ it 'must respond with success if the user is found' do
+ user = User.first
+
+ get user_path(user.id)
+
+ must_respond_with :success
+ end
+
+ it 'must respond with 404 not found if the user is not found' do
+ user_id = User.last.id + 1
+
+ get user_path(user_id)
+
+ must_respond_with :not_found
+ end
+ end
end
diff --git a/test/controllers/works_controller_test.rb b/test/controllers/works_controller_test.rb
index 0945ca47..bc3a9d7d 100644
--- a/test/controllers/works_controller_test.rb
+++ b/test/controllers/works_controller_test.rb
@@ -1,116 +1,307 @@
require 'test_helper'
describe WorksController do
- describe "root" do
- it "succeeds with all media types" do
- # Precondition: there is at least one media of each category
-
+ describe 'guest user' do
+ describe 'root' do
+ it 'succeeds with all media types' do
+ albums = Work.where(category: 'album')
+ books = Work.where(category: 'book')
+ movies = Work.where(category: 'movie')
+
+ albums.count.must_be :>, 0
+ books.count.must_be :>, 0
+ movies.count.must_be :>, 0
+
+ get root_path
+
+ must_respond_with :success
+ end
+ describe 'show' do
+ it 'redirects back to root if user is not logged in' do
+ get work_path(Work.first.id)
+
+ must_redirect_to root_path
+ end
+ end
+
+ describe 'upvote' do
+ it "redirects to the work page if no user is logged in" do
+ work = Work.first
+ old_count = work.vote_count
+
+ post upvote_path(work.id)
+
+ must_redirect_to root_path
+ Work.first.vote_count.must_equal old_count
+ end
+ end
end
- it "succeeds with one media type absent" do
- # Precondition: there is at least one media in two of the categories
+ end
+ describe 'logged in user' do
+ before do
+ user = users(:dan)
+ login(user)
+ puts session[:user_id]
end
- it "succeeds with no media" do
+ describe "root" do
+ it "succeeds with all media types" do
+ # Precondition: there is at least one media of each category
- end
- end
+ albums = Work.where(category: 'album')
+ books = Work.where(category: 'book')
+ movies = Work.where(category: 'movie')
- CATEGORIES = %w(albums books movies)
- INVALID_CATEGORIES = ["nope", "42", "", " ", "albumstrailingtext"]
+ albums.count.must_be :>, 0
+ books.count.must_be :>, 0
+ movies.count.must_be :>, 0
- describe "index" do
- it "succeeds when there are works" do
+ get root_path
- end
+ must_respond_with :success
- it "succeeds when there are no works" do
+ end
- end
- end
+ it "succeeds with one media type absent" do
+ # Precondition: there is at least one media in two of the categories
+ albums = Work.where(category: 'album')
+ albums.destroy_all
- describe "new" do
- it "succeeds" do
+ albums.count.must_equal 0
- end
- end
+ get root_path
- describe "create" do
- it "creates a work with valid data for a real category" do
+ must_respond_with :success
- end
+ end
- it "renders bad_request and does not update the DB for bogus data" do
+ it "succeeds with no media" do
+ Work.destroy_all
+ get root_path
+
+ must_respond_with :success
+ end
end
- it "renders 400 bad_request for bogus categories" do
+ CATEGORIES = %w(albums books movies)
+ INVALID_CATEGORIES = ["nope", "42", "", " ", "albumstrailingtext"]
- end
+ describe "index" do
+ it "succeeds when there are works" do
+ Work.count.must_be :>, 0
- end
+ get works_path
- describe "show" do
- it "succeeds for an extant work ID" do
+ must_respond_with :success
+ end
- end
+ it "succeeds when there are no works" do
+ Work.destroy_all
+
+ Work.count.must_equal 0
- it "renders 404 not_found for a bogus work ID" do
+ get works_path
+ must_respond_with :success
+ end
end
- end
- describe "edit" do
- it "succeeds for an extant work ID" do
+ describe "new" do
+ it "succeeds" do
+ get new_work_path
+ must_respond_with :success
+ end
end
- it "renders 404 not_found for a bogus work ID" do
+ describe "create" do
+ it "creates a work with valid data for a real category" do
+ work_data = {
+ title: 'A Test Title',
+ category: 'albums'
+ }
- end
- end
+ before_count = Work.count
+ Work.new(work_data).must_be :valid?
- describe "update" do
- it "succeeds for valid data and an extant work ID" do
+ post works_path, params: {work: work_data}
- end
+ work = Work.last
+ must_redirect_to work_path(work.id)
+ Work.count.must_equal before_count + 1
+ end
- it "renders bad_request for bogus data" do
+ it "renders bad_request and does not update the DB for bogus data" do
+ work_data = {
+ title: nil,
+ category: 'albums'
+ }
- end
+ before_count = Work.count
+ Work.new(work_data).wont_be :valid?
- it "renders 404 not_found for a bogus work ID" do
+ post works_path, params: {work: work_data}
- end
- end
+ must_respond_with :bad_request
+ Work.count.must_equal before_count
+ end
- describe "destroy" do
- it "succeeds for an extant work ID" do
+ it "renders 400 bad_request for bogus categories" do
+ work_data = {
+ title: 'Test Title',
+ category: INVALID_CATEGORIES[0]
+ }
+
+ before_count = Work.count
+
+ post works_path, params: {work: work_data}
+
+ must_respond_with :bad_request
+ Work.count.must_equal before_count
+ end
end
- it "renders 404 not_found and does not update the DB for a bogus work ID" do
+ describe "show" do
+ it "succeeds for an extant work ID" do
+ work = Work.first
+
+ get work_path(work.id)
+
+ must_respond_with :success
+ end
+
+ it "renders 404 not_found for a bogus work ID" do
+ work_id = Work.last.id + 1
+
+ get work_path(work_id)
+ must_respond_with :not_found
+ end
end
- end
- describe "upvote" do
+ describe "edit" do
+ it "succeeds for an extant work ID" do
+ work = Work.first
+
+ get edit_work_path(work.id)
+
+ must_respond_with :success
+ end
+
+ it "renders 404 not_found for a bogus work ID" do
+ work_id = Work.last.id + 1
- it "redirects to the work page if no user is logged in" do
+ get work_path(work_id)
+ must_respond_with :not_found
+ end
end
- it "redirects to the work page after the user has logged out" do
+ describe "update" do
+ let (:work) { Work.first }
+
+ it "succeeds for valid data and an extant work ID" do
+ work_params = {
+ title: 'my_title'
+ }
+ work.assign_attributes(work_params)
+
+ work.valid?.must_equal true
+
+ patch work_path(work.id), params: {work: work_params}
+
+ must_redirect_to work_path(work.id)
+ Work.first.title.must_equal 'my_title'
+ end
+
+ it "renders not_found for bogus data" do
+ work_params = {
+ category: INVALID_CATEGORIES[-1]
+ }
+
+ work.assign_attributes(work_params)
+
+ work.valid?.must_equal false
+
+ patch work_path(work.id), params: {work: work_params}
+
+ must_respond_with :not_found
+ work.category.must_equal work_params[:category]
+ work.errors.messages.must_include :category
+ end
+
+ it "renders 404 not_found for a bogus work ID" do
+ work_id = Work.last.id + 1
+ work_params = {
+ title: 'my_title'
+ }
+ work.assign_attributes(work_params)
+ patch work_path(work_id), params: {work: work_params}
+
+ must_respond_with :not_found
+ end
end
- it "succeeds for a logged-in user and a fresh user-vote pair" do
+ describe "destroy" do
+ it "succeeds for an extant work ID" do
+ work = Work.first
+ old_count = Work.count
+
+ delete work_path(work.id)
+
+ must_redirect_to root_path
+ Work.count.must_equal old_count - 1
+ end
+
+ it "renders 404 not_found and does not update the DB for a bogus work ID" do
+ work_id = Work.last.id + 1
+ old_count = Work.count
+ delete work_path(work_id)
+
+ must_respond_with :not_found
+ Work.count.must_equal old_count
+
+ end
end
- it "redirects to the work page if the user has already voted for that work" do
+ describe "upvote" do
+
+ it "succeeds for a logged-in user and a fresh user-vote pair" do
+ user = User.first
+ work = Work.create!(title: 'A new work', category: 'books')
+
+ login(user)
+ session[:user_id].must_equal user.id
+
+ post upvote_path(work.id)
+
+ must_redirect_to work_path(work.id)
+ work.reload
+ work.vote_count.must_equal 1
+ end
+
+ it "redirects to the work page if the user has already voted for that work" do
+ work = works(:another_album)
+ user = users(:dan)
+
+ login(user)
+ session[:user_id].must_equal user.id
+
+ old_vote_count = work.vote_count
+
+ # Act
+ post upvote_path(work.id)
+ # Assert
+ works(:another_album).vote_count.must_equal old_vote_count
+ must_redirect_to work_path(work.id)
+ end
end
end
end
diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml
index e2968d78..b129b75b 100644
--- a/test/fixtures/users.yml
+++ b/test/fixtures/users.yml
@@ -1,7 +1,13 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
dan:
- username: dan
+ name: dan
+ email: dan@adadev.org
+ uid: 11111
+ provider: github
kari:
- username: kari
+ name: kari
+ email: kari@adadev.org
+ uid: 123456
+ provider: github
diff --git a/test/models/user_test.rb b/test/models/user_test.rb
index 793ce7e6..00655a56 100644
--- a/test/models/user_test.rb
+++ b/test/models/user_test.rb
@@ -20,25 +20,29 @@
end
describe "validations" do
- it "requires a username" do
- user = User.new
+ it "requires an email" do
+ user = User.new(uid: 99999, provider: 'github')
user.valid?.must_equal false
- user.errors.messages.must_include :username
+ user.errors.messages.must_include :email
end
- it "requires a unique username" do
- username = "test username"
- user1 = User.new(username: username)
+ it "requires a unique uid" do
+ user1 = User.new(uid: 12345, provider: 'github', email: 'fake@fake.com')
# This must go through, so we use create!
user1.save!
- user2 = User.new(username: username)
+ user2 = User.new(uid: 12345, provider: 'github', email: 'fake2@fake.com')
result = user2.save
result.must_equal false
- user2.errors.messages.must_include :username
+ user2.errors.messages.must_include :uid
end
+ it 'requires a provider' do
+ user = User.new(uid: 99999, email: '29394@ghghgh.com')
+ user.valid?.must_equal false
+ user.errors.messages.must_include :provider
+ end
end
end
diff --git a/test/models/vote_test.rb b/test/models/vote_test.rb
index f2615aa1..7c2ec3bb 100644
--- a/test/models/vote_test.rb
+++ b/test/models/vote_test.rb
@@ -16,8 +16,8 @@
end
describe "validations" do
- let (:user1) { User.new(username: 'chris') }
- let (:user2) { User.new(username: 'chris') }
+ let (:user1) { User.new(email: 'chris@email.com', uid: 12345, provider: 'github') }
+ let (:user2) { User.new(email: 'chris@email.com2', uid: 11111, provider: 'github') }
let (:work1) { Work.new(category: 'book', title: 'House of Leaves') }
let (:work2) { Work.new(category: 'book', title: 'For Whom the Bell Tolls') }
diff --git a/test/models/work_test.rb b/test/models/work_test.rb
index d9c00073..e809683c 100644
--- a/test/models/work_test.rb
+++ b/test/models/work_test.rb
@@ -83,7 +83,7 @@
it "tracks the number of votes" do
work = Work.create!(title: "test title", category: "movie")
4.times do |i|
- user = User.create!(username: "user#{i}")
+ user = User.create!(email: "user#{i}", uid: i, provider: 'github')
Vote.create!(user: user, work: work)
end
work.vote_count.must_equal 4
@@ -97,7 +97,7 @@
# Create users to do the voting
test_users = []
20.times do |i|
- test_users << User.create!(username: "user#{i}")
+ test_users << User.create!(email: "user#{i}", uid: i, provider: 'github')
end
# Create media to vote upon
diff --git a/test/test_helper.rb b/test/test_helper.rb
index 5b4fb667..d2a819b0 100644
--- a/test/test_helper.rb
+++ b/test/test_helper.rb
@@ -23,4 +23,24 @@ 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...
+
+ def setup
+ OmniAuth.config.test_mode = true
+ end
+
+ def mock_auth_hash(user)
+ return {
+ provider: user.provider,
+ uid: user.uid,
+ info: {
+ email: user.email,
+ nickname: user.name
+ }
+ }
+ end
+
+ def login(user)
+ OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(mock_auth_hash(user))
+ get auth_callback_path(:github)
+ end
end