From f7fa2fb349aadcfe2f10ccf2c237b11fa3d03043 Mon Sep 17 00:00:00 2001 From: knockknockhusthere Date: Tue, 17 Apr 2018 14:48:26 -0700 Subject: [PATCH 1/5] added omniauth and upgrated db to include extra user fields --- .gitignore | 3 + Gemfile | 8 ++ Gemfile.lock | 32 ++++++ app/controllers/sessions_controller.rb | 38 +++++++ app/views/layouts/application.html.erb | 2 +- config/initializers/omniauth.rb | 3 + config/routes.rb | 3 + db/migrate/20180417183001_add_uid.rb | 7 ++ db/schema.rb | 5 +- test/controllers/works_controller_test.rb | 121 ++++++++++++++++++++-- 10 files changed, 212 insertions(+), 10 deletions(-) create mode 100644 config/initializers/omniauth.rb create mode 100644 db/migrate/20180417183001_add_uid.rb diff --git a/.gitignore b/.gitignore index 48fb168f..f70104a2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,8 @@ !/log/.keep !/tmp/.keep +#ignore env file +.env + # Ignore Byebug command history file. .byebug_history diff --git a/Gemfile b/Gemfile index c029c6da..d605f543 100644 --- a/Gemfile +++ b/Gemfile @@ -36,6 +36,9 @@ gem 'jbuilder', '~> 2.5' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development + +gem 'omniauth' +gem'omniauth-github' # Use the Foundation CSS framework gem 'foundation-rails' gem 'autoprefixer-rails' @@ -49,6 +52,9 @@ group :development, :test do # Use pry for rails console gem 'pry-rails' + + gem 'binding_of_caller' + end group :test do @@ -65,6 +71,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..a8a75516 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -51,6 +51,8 @@ GEM erubi (>= 1.0.0) rack (>= 0.9.0) bindex (0.5.0) + binding_of_caller (0.8.0) + debug_inspector (>= 0.0.1) builder (3.2.3) byebug (10.0.2) coderay (1.1.2) @@ -63,9 +65,16 @@ GEM coffee-script-source (1.12.2) concurrent-ruby (1.0.5) crass (1.0.3) + debug_inspector (0.0.3) + 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,6 +82,7 @@ GEM sprockets-es6 (>= 0.9.0) globalid (0.4.1) activesupport (>= 4.2.0) + hashie (3.5.7) i18n (1.0.0) concurrent-ruby (~> 1.0) jbuilder (2.7.0) @@ -82,6 +92,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 +119,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) @@ -197,8 +225,10 @@ PLATFORMS DEPENDENCIES autoprefixer-rails better_errors + binding_of_caller byebug coffee-rails (~> 4.2) + dotenv-rails foundation-rails jbuilder (~> 2.5) jquery-rails @@ -207,6 +237,8 @@ DEPENDENCIES minitest-reporters minitest-skip minitest-spec-rails + omniauth + omniauth-github pg (~> 0.18) pry-rails puma (~> 3.0) diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 5bce99e6..5fa3f5c8 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -2,6 +2,44 @@ class SessionsController < ApplicationController def login_form end + def create + auth_hash = request.env['omniauth.auth'] + + if auth_hash['uid'] + @user = User.find_by(uid: auth_hash[:uid], provider: 'github') + if @user.nil? + # User doesn't match anything in the DB + # Attempt to create a new user + @user = User.new( + username: auth_hash['info']['name'], + email: auth_hash['info']['email'], + uid: auth_hash['uid'], + provider: auth_hash['provider']) + + else + flash[:success] = "Logged in successfully" + redirect_to root_path + end + + session[:user_id] = @user.id + else + flash[:error] = "Could not log in" + redirect_to root_path + end + end + + def index + @user = User.find(session[:user_id]) # < recalls the value set in a previous request + end + + + # def destroy + # session[:user_id] = nil + # flash[:success] = "Successfully logged out!" + # + # redirect_to root_path + # end + def login username = params[:username] if username and user = User.find_by(username: username) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 82ca0fdc..76b9cb89 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -29,7 +29,7 @@ <%= link_to "Logged in as #{@login_user.username}", 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/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..cfe775c0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,4 +9,7 @@ post '/works/:id/upvote', to: 'works#upvote', as: 'upvote' resources :users, only: [:index, :show] + + get "/auth/:provider/callback", to: "sessions#create" + # delete "/logout", to: "sessions#destroy", as: "logout" end diff --git a/db/migrate/20180417183001_add_uid.rb b/db/migrate/20180417183001_add_uid.rb new file mode 100644 index 00000000..c5fdb19e --- /dev/null +++ b/db/migrate/20180417183001_add_uid.rb @@ -0,0 +1,7 @@ +class AddUid < ActiveRecord::Migration[5.0] + def change + add_column :users, :email, :string + add_column :users, :uid, :integer, null: false # this is the identifier provided by GitHub + add_column :users, :provider, :string, null: false # this tells us who provided the identifier + end +end diff --git a/db/schema.rb b/db/schema.rb index 6bc8ba5c..3b998bf1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170407164321) do +ActiveRecord::Schema.define(version: 20180417183001) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -19,6 +19,9 @@ t.string "username" t.datetime "created_at", null: false t.datetime "updated_at", null: false + 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/works_controller_test.rb b/test/controllers/works_controller_test.rb index 0945ca47..bdfab94d 100644 --- a/test/controllers/works_controller_test.rb +++ b/test/controllers/works_controller_test.rb @@ -4,16 +4,26 @@ describe "root" do it "succeeds with all media types" do # Precondition: there is at least one media of each category + works = Work.where(category: "work") + movies = Work.where(category: "movie") + albums = Work.where(category: "album") + get root_path + must_respond_with :success end it "succeeds with one media type absent" do # Precondition: there is at least one media in two of the categories + works = Work.where(category: "work") + albums = Work.where(category: "album") + get root_path + must_respond_with :success end it "succeeds with no media" do - + get root_path + must_respond_with :success end end @@ -22,75 +32,169 @@ describe "index" do it "succeeds when there are works" do - + Work.count.must_be :>, 0 + #act + get works_path + #assert + must_respond_with :success end it "succeeds when there are no works" do + Work.destroy_all + Work.all.length.must_equal 0 + get works_path + must_respond_with :success end end describe "new" do it "succeeds" do - + get new_work_path + must_respond_with :success end end describe "create" do it "creates a work with valid data for a real category" do - + work_data = { + title: 'controller test work', + creator: "testtest", + publication_year: 2003, + category: "movie" + } + old_work_count = Work.count + #Assumptions + Work.new(work_data).must_be :valid? + + #Act + post works_path, params: { work: work_data } + + #assert + #check http response + must_redirect_to work_path(Work.last) + #check database + Work.count.must_equal old_work_count + 1 + Work.last.title.must_equal work_data[:title] end it "renders bad_request and does not update the DB for bogus data" do + old_work_count = Work.count + work_data = { + title: nil, + category: "album" + } + Work.new(work_data).wont_be :valid? + #act + post works_path, params: {work: work_data} + must_respond_with :bad_request + Work.count.must_equal old_work_count end it "renders 400 bad_request for bogus categories" do + old_work_count = Work.count + work_data = { + title: nil, + category: "cotton candy" + } + Work.new(work_data).wont_be :valid? + #act + post works_path, params: {work: work_data} + must_respond_with :bad_request + Work.count.must_equal old_work_count end end describe "show" do it "succeeds for an extant work ID" do - + get work_path(Work.first) + 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 describe "edit" do it "succeeds for an extant work ID" do - + get edit_work_path(Work.first) + must_respond_with :success end it "renders 404 not_found for a bogus work ID" do - + get edit_work_path(Work.last.id + 1) + must_respond_with :not_found end end describe "update" do it "succeeds for valid data and an extant work ID" do + work = Work.first + work_data = work.attributes + work_data[:title] = "some updated title" + + work.assign_attributes(work_data) + work.must_be :valid? + + patch work_path(work), params: {work: work_data} + + must_redirect_to work_path(work) + work.reload + work.title.must_equal work_data[:title] end - it "renders bad_request for bogus data" do + it "renders not_found for bogus data" do + work = Work.first + work_data = work.attributes + work_data[:title] = "" + + work.assign_attributes(work_data) + work.wont_be :valid? + patch work_path(work.id), params: {work: work_data} + + must_respond_with :not_found + work.reload + work.title.wont_equal work_data[:title] end it "renders 404 not_found for a bogus work ID" do + work_id = Work.last.id + 1 + + patch work_path(work_id) + must_respond_with :not_found end end describe "destroy" do it "succeeds for an extant work ID" do + work_id = Work.first.id + old_count = Work.count + delete work_path(work_id) + must_respond_with :success + + must_redirect_to root_path + + Work.count must_equal old_count - 1 + Work.find_by(id: work_id).must_be_nil end it "renders 404 not_found and does not update the DB for a bogus work ID" do + work_id = Work.last.id + 1 + + patch work_path(work_id) + + must_respond_with :not_found end end @@ -102,6 +206,7 @@ end it "redirects to the work page after the user has logged out" do + user_id = User.first.id end From 80eb376239118570ee7121d815d063eafc1a56a0 Mon Sep 17 00:00:00 2001 From: knockknockhusthere Date: Mon, 30 Apr 2018 14:48:00 -0700 Subject: [PATCH 2/5] added sessions controller tests --- app/controllers/application_controller.rb | 6 ++ app/controllers/sessions_controller.rb | 24 +++--- app/controllers/works_controller.rb | 3 +- app/helpers/application_helper.rb | 4 + app/models/user.rb | 10 ++- app/models/work.rb | 1 + app/views/layouts/application.html.erb | 2 +- app/views/users/index.html.erb | 4 +- app/views/users/show.html.erb | 2 +- app/views/works/show.html.erb | 2 +- config/routes.rb | 2 +- ...180417220630_replace_username_with_name.rb | 5 ++ db/schema.rb | 4 +- test/controllers/sessions_controller_test.rb | 35 +++++++++ test/controllers/users_controller_test.rb | 14 ++++ test/controllers/works_controller_test.rb | 77 ++++++++++++++++++- test/fixtures/users.yml | 22 +++++- test/models/user_test.rb | 8 +- test/models/vote_test.rb | 4 +- test/models/work_test.rb | 4 +- test/test_helper.rb | 25 ++++++ 21 files changed, 224 insertions(+), 34 deletions(-) create mode 100644 db/migrate/20180417220630_replace_username_with_name.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c12c7c17..9e5fd92a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -8,6 +8,12 @@ def render_404 raise ActionController::RoutingError.new('Not Found') end + def require_login + @user = User.find_by(id: session[:user_id]) + head :unauthorized unless @user + end + + private def find_user if session[:user_id] diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index 5fa3f5c8..81fd06a7 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -10,21 +10,25 @@ def create if @user.nil? # User doesn't match anything in the DB # Attempt to create a new user - @user = User.new( - username: auth_hash['info']['name'], - email: auth_hash['info']['email'], - uid: auth_hash['uid'], - provider: auth_hash['provider']) - - else + # @user = User.new( + # username: auth_hash['info']['name'], + # email: auth_hash['info']['email'], + # uid: auth_hash['uid'], + # provider: auth_hash['provider']) + user = User.build_from_github(auth_hash) + if @user.save + session[:user_id] = @user.id flash[:success] = "Logged in successfully" redirect_to root_path - end - + else + flash[:error] = "Could not log in" + redirect_to root_path + end + else session[:user_id] = @user.id - else flash[:error] = "Could not log in" redirect_to root_path + end end end diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 2020bee4..99dfcce2 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -2,6 +2,7 @@ class WorksController < ApplicationController # We should always be able to tell what category # of work we're dealing with before_action :category_from_work, except: [:root, :index, :new, :create] + before_action :require_login, except: [:index, :show] def root @albums = Work.best_albums @@ -10,7 +11,7 @@ def root @best_work = Work.order(vote_count: :desc).first end - def index + def index #template method pattern @works_by_category = Work.to_category_hash end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 51b55d86..56d51d6f 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 readable_date(date) + ("" + date.strftime("%A, %b %d") + "").html_safe +end end diff --git a/app/models/user.rb b/app/models/user.rb index 4cac8fe0..76b71510 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -2,5 +2,13 @@ class User < ApplicationRecord has_many :votes has_many :ranked_works, through: :votes, source: :work - validates :username, uniqueness: true, presence: true + validates :name, uniqueness: true, presence: true + + def build_from_github(auth_hash) + @user = User.new( + name: auth_hash['info']['name'], + email: auth_hash['info']['email'], + uid: auth_hash['uid'], + provider: auth_hash['provider']) + end end diff --git a/app/models/work.rb b/app/models/work.rb index c61da303..64eeb798 100644 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -50,3 +50,4 @@ def fix_category end end end + diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 76b9cb89..b96bc014 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -26,7 +26,7 @@
<% if @login_user %> - <%= link_to "Logged in as #{@login_user.username}", user_path(@login_user), class: "button" %> + <%= link_to "Logged in as #{@login_user.name}", user_path(@login_user), class: "button" %> <%= link_to "Log Out", logout_path, method: :post, class: "button" %> <% else %> <%= link_to "Log In", "/auth/github", class: "button" %> 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 @@ - + @@ -10,7 +10,7 @@ <% @users.each do |user| %> - + diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb index d6185ad7..496f4a0b 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 @user.name, user_path(@user) %>

Joined site <%= render_date @user.created_at %>

Votes

diff --git a/app/views/works/show.html.erb b/app/views/works/show.html.erb index 13225855..08e4d8d5 100644 --- a/app/views/works/show.html.erb +++ b/app/views/works/show.html.erb @@ -23,7 +23,7 @@ <% @votes.each do |vote| %> - + <% end %> diff --git a/config/routes.rb b/config/routes.rb index cfe775c0..6fbfcc21 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,6 +10,6 @@ resources :users, only: [:index, :show] - get "/auth/:provider/callback", to: "sessions#create" + get "/auth/:provider/callback", to: "sessions#create", as: 'auth_callback' # delete "/logout", to: "sessions#destroy", as: "logout" end diff --git a/db/migrate/20180417220630_replace_username_with_name.rb b/db/migrate/20180417220630_replace_username_with_name.rb new file mode 100644 index 00000000..5958927a --- /dev/null +++ b/db/migrate/20180417220630_replace_username_with_name.rb @@ -0,0 +1,5 @@ +class ReplaceUsernameWithName < ActiveRecord::Migration[5.0] + def change + rename_column :users, :username, :name + end +end diff --git a/db/schema.rb b/db/schema.rb index 3b998bf1..0b2f99cf 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,13 +10,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180417183001) do +ActiveRecord::Schema.define(version: 20180417220630) 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.string "name" t.datetime "created_at", null: false t.datetime "updated_at", null: false t.string "email" diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb index f641d15c..687205f5 100644 --- a/test/controllers/sessions_controller_test.rb +++ b/test/controllers/sessions_controller_test.rb @@ -1,5 +1,40 @@ require "test_helper" describe SessionsController do + describe 'auth_callback' do + it 'logs in an existing user' do + #arrange + user = User.first + old_user_count = User.count + + login(user) + User.count.must_equal old_user_count + session[:user_id].must_equal user.id + end + + it 'does not log in with insufficient data' do + user = User.new( + provider: 'github', + email: 'test@tester.com', + ) + user.wont_be :valid? + old_user_count = User.count + + login(user) + User.count.must_equal old_user_count + end + + it 'does not log in if the user data is invalid' do + user = User.first + dup_user = User.new( + provider: 'github', + uid: 80085, + email: 'test@tester.com', + name: user.name + ) + end + + #what about if the user is already logged in? + end end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index d2c5cfbb..7af400c0 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -1,5 +1,19 @@ require 'test_helper' describe UsersController do + it 'creates a DB entry for a new user' do + #arrange + user = User.new( + provider: 'github', + uid: 80085, + email: 'test@tester.com', + name: 'test userr' + ) + user.must_be :valid? + old_user_count = User.count + login(user) + User.count.must_equal old_user_count + 1 + session[:user_id].must_equal User.last.id + end end diff --git a/test/controllers/works_controller_test.rb b/test/controllers/works_controller_test.rb index bdfab94d..cf65bb3f 100644 --- a/test/controllers/works_controller_test.rb +++ b/test/controllers/works_controller_test.rb @@ -1,6 +1,14 @@ require 'test_helper' +require 'pry' describe WorksController do + + describe 'logged in user' do + before do + login(User.first) + end + end + describe "root" do it "succeeds with all media types" do # Precondition: there is at least one media of each category @@ -179,13 +187,12 @@ it "succeeds for an extant work ID" do work_id = Work.first.id old_count = Work.count - delete work_path(work_id) - must_respond_with :success + # must_respond_with :success must_redirect_to root_path + Work.count.must_equal old_count - 1 - Work.count must_equal old_count - 1 Work.find_by(id: work_id).must_be_nil end @@ -202,11 +209,15 @@ describe "upvote" do it "redirects to the work page if no user is logged in" do + work = Work.first + vote_count = work.vote_count + post upvote_path(work.id) + + must_redirect_to work_path(work) end it "redirects to the work page after the user has logged out" do - user_id = User.first.id end @@ -218,4 +229,62 @@ end end + + describe 'guest user' do + it 'rejects requests for new book form' do + get new_work_path + must_respond_with :unauthorized + end + + it 'rejects requests to create a book' do + work_data = { + title: 'controller test work', + creator: "testtest", + publication_year: 2003, + category: "movie" + } + old_work_count = Work.count + #Assumptions + Work.new(work_data).must_be :valid? + + #Act + post works_path, params: { work: work_data } + + #assert + #check http response + must_respond_with :unauthorized + #check database + Work.count.must_equal old_work_count + end + + it 'rejects requests for the edit form' do + get edit_work_path(Work.first) + must_respond_with :unauthorized + end + + it 'rejects requests to update a book' do + work = Work.first + work_data = work.attributes + work_data[:title] = "some updated title" + + work.assign_attributes(work_data) + work.must_be :valid? + + patch work_path(work), params: {work: work_data} + + must_respond_with :unauthorized + end + + it 'rejects requests to destroy a book' do + work_id = Work.first.id + old_count = Work.count + delete work_path(work_id) + # must_respond_with :success + + must_redirect_to root_path + must_respond_with :unauthorized + Work.count.must_equal old_count + end + end + end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index e2968d78..2c91210c 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -1,7 +1,25 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html dan: - username: dan + name: dan + uid: 75417541 + email: dandragon@gmail.com + provider: github kari: - username: kari + name: kari + uid: 13371336 + email: karikiwi@gmail.com + provider: github + +ada: + provider: github + uid: 12345 + email: ada@adadevelopersacademy.org + name: countess_ada + +grace: + provider: github + uid: 13371337 + email: grace@hooper.net + name: graceful_hoops diff --git a/test/models/user_test.rb b/test/models/user_test.rb index 793ce7e6..53792b8a 100644 --- a/test/models/user_test.rb +++ b/test/models/user_test.rb @@ -23,20 +23,20 @@ it "requires a username" do user = User.new user.valid?.must_equal false - user.errors.messages.must_include :username + user.errors.messages.must_include :name end it "requires a unique username" do username = "test username" - user1 = User.new(username: username) + user1 = User.new(name: username, uid: 201802018, email: 'angela@ada.com', provider: 'github') # This must go through, so we use create! user1.save! - user2 = User.new(username: username) + user2 = User.new(name: username, uid: 201902018, email: 'angela@aduh.com', provider: 'github') result = user2.save result.must_equal false - user2.errors.messages.must_include :username + user2.errors.messages.must_include :name end diff --git a/test/models/vote_test.rb b/test/models/vote_test.rb index f2615aa1..5958a48d 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(name: 'chris', uid: 201802018, email: 'angela@ada.com', provider: 'github') } + let (:user2) { User.new(name: 'chris', uid: 201802018, email: 'angela@ada.com', 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..4fcf0a9b 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!(name: "user#{i}", uid: 201802018, email: 'angela@ada.com', 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!(name: "user#{i}", uid: 201802018, email: 'angela@ada.com', provider: 'github') end # Create media to vote upon diff --git a/test/test_helper.rb b/test/test_helper.rb index 5b4fb667..7e14ca28 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -23,4 +23,29 @@ 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 + # Once you have enabled test mode, all requests + # to OmniAuth will be short circuited to use the mock authentication hash. + # A request to /auth/provider will redirect immediately to /auth/provider/callback. + 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) + # + # must_redirect_to root_path + end end From 7f0e89a688998b1f052403019562ce9bda58c8c1 Mon Sep 17 00:00:00 2001 From: knockknockhusthere Date: Mon, 30 Apr 2018 15:11:23 -0700 Subject: [PATCH 3/5] user controller tests added --- app/models/user.rb | 2 +- test/controllers/sessions_controller_test.rb | 16 +++++++ test/controllers/users_controller_test.rb | 45 ++++++++++++++------ test/test_helper.rb | 2 +- 4 files changed, 49 insertions(+), 16 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 76b71510..73f25e35 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,7 +5,7 @@ class User < ApplicationRecord validates :name, uniqueness: true, presence: true def build_from_github(auth_hash) - @user = User.new( + return User.new( name: auth_hash['info']['name'], email: auth_hash['info']['email'], uid: auth_hash['uid'], diff --git a/test/controllers/sessions_controller_test.rb b/test/controllers/sessions_controller_test.rb index 687205f5..1f1b5a1f 100644 --- a/test/controllers/sessions_controller_test.rb +++ b/test/controllers/sessions_controller_test.rb @@ -2,6 +2,22 @@ describe SessionsController do describe 'auth_callback' do + # it 'creates a DB entry for a new user' do + # old_user_count = User.count + # + # user = User.new( + # provider: 'github', + # uid: 80085, + # email: 'test@tester.com', + # name: 'test userr' + # ) + # user.must_be :valid? + # + # login(user) + # + # User.count.must_equal old_user_count + 1 + # session[:user_id].must_equal User.last.id + # end it 'logs in an existing user' do #arrange diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index 7af400c0..80787b6d 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -1,19 +1,36 @@ require 'test_helper' describe UsersController do - it 'creates a DB entry for a new user' do - #arrange - user = User.new( - provider: 'github', - uid: 80085, - email: 'test@tester.com', - name: 'test userr' - ) - user.must_be :valid? - old_user_count = User.count - - login(user) - User.count.must_equal old_user_count + 1 - session[:user_id].must_equal User.last.id + + describe 'logged in user' do + + before do + login(User.first) + end + + describe "index" do + it "sends a success response when there are many users" do + User.count.must_be :>, 0 + + get users_path + + must_respond_with :success + end + + end + + describe "show" do + it "sends success if the user exists" do + get user_path(User.first) + must_respond_with :success + end + + it "sends not_found if the user doesnt exist" do + user_id = User.last.id + 1 + get user_path(user_id) + + must_respond_with :not_found + end + end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 7e14ca28..041ba475 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -36,7 +36,7 @@ def mock_auth_hash(user) uid: user.uid, info: { email: user.email, - nickname: user.name + name: user.name } } end From 07233077c4a76fa96260591f43249134c9979157 Mon Sep 17 00:00:00 2001 From: knockknockhusthere Date: Mon, 30 Apr 2018 17:04:40 -0700 Subject: [PATCH 4/5] got upvotes semi working in works controller --- test/controllers/works_controller_test.rb | 375 +++++++++++----------- 1 file changed, 195 insertions(+), 180 deletions(-) diff --git a/test/controllers/works_controller_test.rb b/test/controllers/works_controller_test.rb index cf65bb3f..fc12989f 100644 --- a/test/controllers/works_controller_test.rb +++ b/test/controllers/works_controller_test.rb @@ -4,229 +4,245 @@ describe WorksController do describe 'logged in user' do - before do - login(User.first) - end - end - - describe "root" do - it "succeeds with all media types" do - # Precondition: there is at least one media of each category - works = Work.where(category: "work") - movies = Work.where(category: "movie") - albums = Work.where(category: "album") - get root_path - must_respond_with :success + describe "root" do + it "succeeds with all media types" do + # Precondition: there is at least one media of each category +login(User.first) + works = Work.where(category: "work") + movies = Work.where(category: "movie") + albums = Work.where(category: "album") + + get root_path + must_respond_with :success + end + + it "succeeds with one media type absent" do + # Precondition: there is at least one media in two of the categories + login(User.first) + works = Work.where(category: "work") + albums = Work.where(category: "album") + + get root_path + must_respond_with :success + end + + it "succeeds with no media" do + login(User.first) + get root_path + must_respond_with :success + end end - it "succeeds with one media type absent" do - # Precondition: there is at least one media in two of the categories - works = Work.where(category: "work") - albums = Work.where(category: "album") - - get root_path - must_respond_with :success + CATEGORIES = %w(albums books movies) + INVALID_CATEGORIES = ["nope", "42", "", " ", "albumstrailingtext"] + + describe "index" do + it "succeeds when there are works" do + login(User.first) + Work.count.must_be :>, 0 + #act + get works_path + #assert + must_respond_with :success + end + + it "succeeds when there are no works" do + login(User.first) + Work.destroy_all + Work.all.length.must_equal 0 + get works_path + + must_respond_with :success + end end - it "succeeds with no media" do - get root_path - must_respond_with :success + describe "new" do + it "succeeds" do + login(User.first) + get new_work_path + must_respond_with :success + end end - end - CATEGORIES = %w(albums books movies) - INVALID_CATEGORIES = ["nope", "42", "", " ", "albumstrailingtext"] + describe "create" do + it "creates a work with valid data for a real category" do + login(User.first) + work_data = { + title: 'controller test work', + creator: "testtest", + publication_year: 2003, + category: "movie" + } + old_work_count = Work.count + #Assumptions + Work.new(work_data).must_be :valid? + + #Act + post works_path, params: { work: work_data } + + #assert + #check http response + must_redirect_to work_path(Work.last) + #check database + Work.count.must_equal old_work_count + 1 + Work.last.title.must_equal work_data[:title] + end + + it "renders bad_request and does not update the DB for bogus data" do + login(User.first) + old_work_count = Work.count + work_data = { + title: nil, + category: "album" + } + Work.new(work_data).wont_be :valid? + #act + post works_path, params: {work: work_data} + + must_respond_with :bad_request + Work.count.must_equal old_work_count + end + + it "renders 400 bad_request for bogus categories" do + login(User.first) + old_work_count = Work.count + work_data = { + title: nil, + category: "cotton candy" + } + Work.new(work_data).wont_be :valid? + #act + post works_path, params: {work: work_data} + + must_respond_with :bad_request + Work.count.must_equal old_work_count + end - describe "index" do - it "succeeds when there are works" do - Work.count.must_be :>, 0 - #act - get works_path - #assert - must_respond_with :success end - it "succeeds when there are no works" do - Work.destroy_all - Work.all.length.must_equal 0 - get works_path + describe "show" do + it "succeeds for an extant work ID" do + login(User.first) + get work_path(Work.first) + must_respond_with :success + end - must_respond_with :success - end - end + it "renders 404 not_found for a bogus work ID" do + login(User.first) + work_id = Work.last.id + 1 - describe "new" do - it "succeeds" do - get new_work_path - must_respond_with :success + get work_path(work_id) + must_respond_with :not_found + end end - end - - describe "create" do - it "creates a work with valid data for a real category" do - work_data = { - title: 'controller test work', - creator: "testtest", - publication_year: 2003, - category: "movie" - } - old_work_count = Work.count - #Assumptions - Work.new(work_data).must_be :valid? - #Act - post works_path, params: { work: work_data } - - #assert - #check http response - must_redirect_to work_path(Work.last) - #check database - Work.count.must_equal old_work_count + 1 - Work.last.title.must_equal work_data[:title] + describe "edit" do + it "succeeds for an extant work ID" do + login(User.first) + get edit_work_path(Work.first) + must_respond_with :success + end + + it "renders 404 not_found for a bogus work ID" do + login(User.first) + get edit_work_path(Work.last.id + 1) + must_respond_with :not_found + end end - it "renders bad_request and does not update the DB for bogus data" do - old_work_count = Work.count - work_data = { - title: nil, - category: "album" - } - Work.new(work_data).wont_be :valid? - #act - post works_path, params: {work: work_data} + describe "update" do + it "succeeds for valid data and an extant work ID" do + login(User.first) + work = Work.first + work_data = work.attributes + work_data[:title] = "some updated title" - must_respond_with :bad_request - Work.count.must_equal old_work_count - end + work.assign_attributes(work_data) + work.must_be :valid? - it "renders 400 bad_request for bogus categories" do - old_work_count = Work.count - work_data = { - title: nil, - category: "cotton candy" - } - Work.new(work_data).wont_be :valid? - #act - post works_path, params: {work: work_data} + patch work_path(work), params: {work: work_data} - must_respond_with :bad_request - Work.count.must_equal old_work_count - end + must_redirect_to work_path(work) + work.reload + work.title.must_equal work_data[:title] - end + end - describe "show" do - it "succeeds for an extant work ID" do - get work_path(Work.first) - must_respond_with :success - end + it "renders not_found for bogus data" do + login(User.first) + work = Work.first + work_data = work.attributes + work_data[:title] = "" - it "renders 404 not_found for a bogus work ID" do - work_id = Work.last.id + 1 + work.assign_attributes(work_data) + work.wont_be :valid? - get work_path(work_id) - must_respond_with :not_found - end - end + patch work_path(work.id), params: {work: work_data} - describe "edit" do - it "succeeds for an extant work ID" do - get edit_work_path(Work.first) - must_respond_with :success - end - - it "renders 404 not_found for a bogus work ID" do - get edit_work_path(Work.last.id + 1) - must_respond_with :not_found - end - end - - describe "update" do - it "succeeds for valid data and an extant work ID" do - work = Work.first - work_data = work.attributes - work_data[:title] = "some updated title" - - work.assign_attributes(work_data) - work.must_be :valid? - - patch work_path(work), params: {work: work_data} - - must_redirect_to work_path(work) - work.reload - work.title.must_equal work_data[:title] - - end - - it "renders not_found for bogus data" do - work = Work.first - work_data = work.attributes - work_data[:title] = "" + must_respond_with :not_found + work.reload + work.title.wont_equal work_data[:title] + end - work.assign_attributes(work_data) - work.wont_be :valid? + it "renders 404 not_found for a bogus work ID" do + login(User.first) + work_id = Work.last.id + 1 - patch work_path(work.id), params: {work: work_data} + patch work_path(work_id) - must_respond_with :not_found - work.reload - work.title.wont_equal work_data[:title] + must_respond_with :not_found + end end - it "renders 404 not_found for a bogus work ID" do - work_id = Work.last.id + 1 - - patch work_path(work_id) + describe "destroy" do + it "succeeds for an extant work ID" do + login(User.first) + work_id = Work.first.id + old_count = Work.count + delete work_path(work_id) + # must_respond_with :success - must_respond_with :not_found - end - end + must_redirect_to root_path + Work.count.must_equal old_count - 1 - describe "destroy" do - it "succeeds for an extant work ID" do - work_id = Work.first.id - old_count = Work.count - delete work_path(work_id) - # must_respond_with :success + Work.find_by(id: work_id).must_be_nil + end - must_redirect_to root_path - Work.count.must_equal old_count - 1 + it "renders 404 not_found and does not update the DB for a bogus work ID" do + login(User.first) + work_id = Work.last.id + 1 - Work.find_by(id: work_id).must_be_nil - end + patch work_path(work_id) - it "renders 404 not_found and does not update the DB for a bogus work ID" do - work_id = Work.last.id + 1 - - patch work_path(work_id) - - must_respond_with :not_found + must_respond_with :not_found + end end - end - describe "upvote" do + describe "upvote" do - it "redirects to the work page if no user is logged in" do - work = Work.first - vote_count = work.vote_count + it "redirects to the work page if no user is logged in" do + work = Work.first + vote_count = work.vote_count - post upvote_path(work.id) + post upvote_path(work.id) + must_respond_with :unauthorized + # must_redirect_to work_path(work) - must_redirect_to work_path(work) - end + end - it "redirects to the work page after the user has logged out" do + it "redirects to the work page after the user has logged out" do - end + end - it "succeeds for a logged-in user and a fresh user-vote pair" do + it "succeeds for a logged-in user and a fresh user-vote pair" do - end + end - it "redirects to the work page if the user has already voted for that work" do + it "redirects to the work page if the user has already voted for that work" do + end end end @@ -280,11 +296,10 @@ old_count = Work.count delete work_path(work_id) # must_respond_with :success - - must_redirect_to root_path + # + # must_redirect_to root_path must_respond_with :unauthorized Work.count.must_equal old_count end end - end From 575a020e0670475c08b13ee060f4180164504fe9 Mon Sep 17 00:00:00 2001 From: knockknockhusthere Date: Mon, 30 Apr 2018 23:59:41 -0700 Subject: [PATCH 5/5] works controller testing - cant get upvotes passing --- app/controllers/application_controller.rb | 7 +++-- app/controllers/users_controller.rb | 2 ++ app/controllers/works_controller.rb | 2 +- test/controllers/works_controller_test.rb | 35 ++++++++++++----------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 9e5fd92a..f010aaca 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -9,8 +9,11 @@ def render_404 end def require_login - @user = User.find_by(id: session[:user_id]) - head :unauthorized unless @user + if @login_user.nil? + flash[:status] = :error + flash[:result_text] = "You must be logged in to view this section" + redirect_to root_path + end end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 73b42652..a87a56cf 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -1,4 +1,6 @@ class UsersController < ApplicationController + before_action :require_login, except: [:root] + def index @users = User.all end diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 99dfcce2..7aa072ac 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -2,7 +2,7 @@ class WorksController < ApplicationController # We should always be able to tell what category # of work we're dealing with before_action :category_from_work, except: [:root, :index, :new, :create] - before_action :require_login, except: [:index, :show] + before_action :require_login, except: [:root] def root @albums = Work.best_albums diff --git a/test/controllers/works_controller_test.rb b/test/controllers/works_controller_test.rb index fc12989f..163b84a2 100644 --- a/test/controllers/works_controller_test.rb +++ b/test/controllers/works_controller_test.rb @@ -222,26 +222,27 @@ describe "upvote" do - it "redirects to the work page if no user is logged in" do + it "succeeds for a logged-in user and a fresh user-vote pair" do + login(User.first) + Vote.destroy_all + work = Work.first vote_count = work.vote_count post upvote_path(work.id) - must_respond_with :unauthorized - # must_redirect_to work_path(work) - - end - - it "redirects to the work page after the user has logged out" do - - end - - it "succeeds for a logged-in user and a fresh user-vote pair" do - + work.vote_count.must_equal vote_count + 1 end it "redirects to the work page if the user has already voted for that work" do + login(User.first) + Vote.destroy_all + work = Work.first + post upvote_path(work.id) + vote_count = work.vote_count + post upvote_path(work) + must_respond_with :redirect + work.vote_count.must_equal vote_count end end end @@ -249,7 +250,7 @@ describe 'guest user' do it 'rejects requests for new book form' do get new_work_path - must_respond_with :unauthorized + must_respond_with :redirect end it 'rejects requests to create a book' do @@ -268,14 +269,14 @@ #assert #check http response - must_respond_with :unauthorized + must_respond_with :redirect #check database Work.count.must_equal old_work_count end it 'rejects requests for the edit form' do get edit_work_path(Work.first) - must_respond_with :unauthorized + must_respond_with :redirect end it 'rejects requests to update a book' do @@ -288,7 +289,7 @@ patch work_path(work), params: {work: work_data} - must_respond_with :unauthorized + must_respond_with :redirect end it 'rejects requests to destroy a book' do @@ -298,7 +299,7 @@ # must_respond_with :success # # must_redirect_to root_path - must_respond_with :unauthorized + must_respond_with :redirect Work.count.must_equal old_count end end
UsernameName Votes Joined
<%= link_to user.username, user_path(user) %><%= link_to user.name, user_path(user) %> <%= user.votes.count %> <%= render_date user.created_at %>
<%= link_to vote.user.username, user_path(vote.user) %><%= link_to vote.user.name, user_path(vote.user) %> <%= render_date vote.created_at %>