From deb678886b94d762b5162458002b131bb5414ac3 Mon Sep 17 00:00:00 2001 From: Brittany Jones Date: Tue, 17 Apr 2018 14:49:57 -0700 Subject: [PATCH 1/3] added git log in --- .gitignore | 2 + Gemfile | 4 +- Gemfile.lock | 28 +++++ app/controllers/sessions_controller.rb | 88 +++++++++---- app/models/user.rb | 7 ++ app/views/layouts/application.html.erb | 9 +- config/initializers/omniauth.rb | 3 + config/routes.rb | 6 +- db/migrate/20180417210357_add_uidto_users.rb | 5 + db/migrate/20180417212015_add_uid_to_users.rb | 5 + .../20180417212442_add_provider_to_users.rb | 5 + db/schema.rb | 4 +- test/controllers/works_controller_test.rb | 117 ++++++++++++------ 13 files changed, 214 insertions(+), 69 deletions(-) create mode 100644 config/initializers/omniauth.rb create mode 100644 db/migrate/20180417210357_add_uidto_users.rb create mode 100644 db/migrate/20180417212015_add_uid_to_users.rb create mode 100644 db/migrate/20180417212442_add_provider_to_users.rb diff --git a/.gitignore b/.gitignore index 48fb168f..527ac329 100644 --- a/.gitignore +++ b/.gitignore @@ -13,5 +13,7 @@ !/log/.keep !/tmp/.keep + # Ignore Byebug command history file. .byebug_history +.env diff --git a/Gemfile b/Gemfile index c029c6da..36c10365 100644 --- a/Gemfile +++ b/Gemfile @@ -46,7 +46,6 @@ group :development, :test do # Improve the error message you get in the browser gem 'better_errors' - # Use pry for rails console gem 'pry-rails' end @@ -62,9 +61,12 @@ group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '~> 3.0.5' + gem 'omniauth' + gem 'omniauth-github' # 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..2e180b49 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -63,9 +63,15 @@ GEM coffee-script-source (1.12.2) concurrent-ruby (1.0.5) crass (1.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 +79,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 +89,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 +116,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) @@ -199,6 +224,7 @@ DEPENDENCIES better_errors byebug coffee-rails (~> 4.2) + dotenv-rails foundation-rails jbuilder (~> 2.5) jquery-rails @@ -207,6 +233,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..fbedea66 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -2,33 +2,79 @@ 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}" + + 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.build_from_github(auth_hash[:uid]) + good_save = @user.save + + if good_save + + flash[:success] = "Logged in successfully" + session[:user_id] = @user.id + redirect_to root_path + else + flash[:error] = "Something happened in user creation" + redirect_to root_path + end 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 - return + flash[:success] = "logged in successfully" + session[:user_id] = @user.id + redirect_to root_path end + + else + flash[:error] = "Something happened in user creation" + redirect_to root_path + + end + + + def index + @user = User.find(session[:user_id]) # < recalls the value set in a previous request end - redirect_to root_path end - def logout + def destroy session[:user_id] = nil - flash[:status] = :success - flash[:result_text] = "Successfully logged out" + flash[:success] = "Successfully logged out!" + redirect_to root_path end 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 + return + end + end + redirect_to root_path +end + +def logout + session[:user_id] = nil + flash[:status] = :success + flash[:result_text] = "Successfully logged out" + redirect_to root_path +end diff --git a/app/models/user.rb b/app/models/user.rb index 4cac8fe0..534c1057 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,4 +3,11 @@ class User < ApplicationRecord has_many :ranked_works, through: :votes, source: :work validates :username, uniqueness: true, presence: true + + def self.build_from_github(auth_hash) + return User.create(provider: auth_hash[:provider], uid: auth_hash[:uid], username: auth_hash[:info][:nickname] + ) + end + + end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 82ca0fdc..063b645f 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -25,11 +25,10 @@ <%= link_to "View all users", users_path, class: "button" %>
- <% if @login_user %> - <%= 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" %> + <% if session[:user_id] %> + <%= link_to "Log out", logout_path, method: "delete" , class: "button" %> +<% else %> + <%= link_to "Login with Github", "/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..a792c673 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,11 @@ root 'works#root' get '/login', to: 'sessions#login_form', as: 'login' post '/login', to: 'sessions#login' - post '/logout', to: 'sessions#logout', as: 'logout' + get '/auth/:github/callback', to: 'sessions#create' + get '/auth/github', as: 'github_login' + delete '/logout', to: 'sessions#destroy', as: 'logout' + + resources :works post '/works/:id/upvote', to: 'works#upvote', as: 'upvote' diff --git a/db/migrate/20180417210357_add_uidto_users.rb b/db/migrate/20180417210357_add_uidto_users.rb new file mode 100644 index 00000000..c016d0f5 --- /dev/null +++ b/db/migrate/20180417210357_add_uidto_users.rb @@ -0,0 +1,5 @@ +class AddUidtoUsers < ActiveRecord::Migration[5.0] + def change + add_column :users, :uid, :integer + end +end diff --git a/db/migrate/20180417212015_add_uid_to_users.rb b/db/migrate/20180417212015_add_uid_to_users.rb new file mode 100644 index 00000000..19a7d4d2 --- /dev/null +++ b/db/migrate/20180417212015_add_uid_to_users.rb @@ -0,0 +1,5 @@ +class AddUidToUsers < ActiveRecord::Migration[5.0] + def change + add_column :users, :uid, :integer + end +end diff --git a/db/migrate/20180417212442_add_provider_to_users.rb b/db/migrate/20180417212442_add_provider_to_users.rb new file mode 100644 index 00000000..c58f76a6 --- /dev/null +++ b/db/migrate/20180417212442_add_provider_to_users.rb @@ -0,0 +1,5 @@ +class AddProviderToUsers < ActiveRecord::Migration[5.0] + def change + add_column :users, :provider, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 6bc8ba5c..12166690 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: 20180417212442) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -19,6 +19,8 @@ t.string "username" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "uid" + t.string "provider" 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..04308dcd 100644 --- a/test/controllers/works_controller_test.rb +++ b/test/controllers/works_controller_test.rb @@ -4,15 +4,40 @@ describe "root" do it "succeeds with all media types" do # Precondition: there is at least one media of each category + Work.where(category: "album").count.must_be :>, 0 + Work.where(category: "movie").count.must_be :>, 0 + Work.where(category: "book").count.must_be :>, 0 + get works_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 + Work.where(category: "album").destroy_all + + # Assumptions + Work.where(category: "album").must_be_empty + Work.where(category: "movie").count.must_be :>, 0 + Work.where(category: "book").count.must_be :>, 0 + + get root_path + + must_respond_with :success end it "succeeds with no media" do + Work.destroy_all + + # Assumptions + Work.where(category: "album").must_be_empty + Work.where(category: "movie").must_be_empty + Work.where(category: "book").must_be_empty + + get root_path + + must_respond_with :success end end @@ -23,94 +48,106 @@ describe "index" do it "succeeds when there are works" do + Work.count.must_be :>=, 1 + get works_path + + must_respond_with :success end it "succeeds when there are no works" do + Work.destroy_all + + Work.count.must_equal 0 + get works_path + must_respond_with :success end + end describe "new" do it "succeeds" do - + get new_work_path + assert_response :success end - end - describe "create" do - it "creates a work with valid data for a real category" do + end +end - end +describe "create" do + it "creates a work with valid data for a real category" do - it "renders bad_request and does not update the DB for bogus data" do + end - end + it "renders bad_request and does not update the DB for bogus data" do - it "renders 400 bad_request for bogus categories" do + end - end + it "renders 400 bad_request for bogus categories" do end - describe "show" do - it "succeeds for an extant work ID" do +end - end +describe "show" do + it "succeeds for an extant work ID" do - it "renders 404 not_found for a bogus work ID" do + end + + it "renders 404 not_found for a bogus work ID" do - end end +end - describe "edit" do - it "succeeds for an extant work ID" do +describe "edit" do + it "succeeds for an extant work ID" do - end + end - it "renders 404 not_found for a bogus work ID" do + it "renders 404 not_found for a bogus work ID" do - end end +end - describe "update" do - it "succeeds for valid data and an extant work ID" do +describe "update" do + it "succeeds for valid data and an extant work ID" do - end + end - it "renders bad_request for bogus data" do + it "renders bad_request for bogus data" do - end + end - it "renders 404 not_found for a bogus work ID" do + it "renders 404 not_found for a bogus work ID" do - end end +end - describe "destroy" do - it "succeeds for an extant work ID" do +describe "destroy" do + it "succeeds for an extant work ID" do - end + end - it "renders 404 not_found and does not update the DB for a bogus work ID" do + it "renders 404 not_found and does not update the DB for a bogus work ID" do - end end +end - describe "upvote" do +describe "upvote" do - it "redirects to the work page if no user is logged in" do + it "redirects to the work page if no user is logged in" do - 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 From b074845495d4d99f0bc2298e0f17e9ba9a7a89f3 Mon Sep 17 00:00:00 2001 From: Brittany Jones Date: Tue, 1 May 2018 23:24:19 -0700 Subject: [PATCH 2/3] final submission --- .gitignore | 1 - Gemfile | 8 +- Gemfile.lock | 16 +- app/controllers/application_controller.rb | 8 + app/controllers/sessions_controller.rb | 79 +--- app/controllers/users_controller.rb | 2 + app/controllers/works_controller.rb | 9 +- app/models/user.rb | 10 +- app/views/layouts/application.html.erb | 10 +- config/routes.rb | 11 +- .../20180502032300_add_email_to_users.rb | 5 + db/schema.rb | 3 +- test/controllers/sessions_controller_test.rb | 45 ++ test/controllers/users_controller_test.rb | 62 +++ test/controllers/works_controller_test.rb | 444 ++++++++++++++---- test/fixtures/users.yml | 6 + test/test_helper.rb | 27 +- 17 files changed, 576 insertions(+), 170 deletions(-) create mode 100644 db/migrate/20180502032300_add_email_to_users.rb diff --git a/.gitignore b/.gitignore index 527ac329..d869f9f9 100644 --- a/.gitignore +++ b/.gitignore @@ -13,7 +13,6 @@ !/log/.keep !/tmp/.keep - # Ignore Byebug command history file. .byebug_history .env diff --git a/Gemfile b/Gemfile index 36c10365..1822dbc4 100644 --- a/Gemfile +++ b/Gemfile @@ -46,8 +46,10 @@ group :development, :test do # Improve the error message you get in the browser gem 'better_errors' + # Use pry for rails console gem 'pry-rails' + gem 'binding_of_caller' end group :test do @@ -61,13 +63,15 @@ group :development do # Access an IRB console on exception pages or by using <%= console %> anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '~> 3.0.5' - gem 'omniauth' - gem 'omniauth-github' # 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 gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +gem "omniauth" +gem "omniauth-github" diff --git a/Gemfile.lock b/Gemfile.lock index 2e180b49..1a5a0319 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -40,7 +40,7 @@ GEM tzinfo (~> 1.1) ansi (1.5.0) arel (7.1.4) - autoprefixer-rails (8.2.0) + autoprefixer-rails (8.3.0) execjs babel-source (5.8.35) babel-transpiler (0.7.0) @@ -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) @@ -62,7 +64,8 @@ GEM execjs coffee-script-source (1.12.2) concurrent-ruby (1.0.5) - crass (1.0.3) + crass (1.0.4) + debug_inspector (0.0.3) dotenv (2.2.2) dotenv-rails (2.2.2) dotenv (= 2.2.2) @@ -142,7 +145,7 @@ GEM method_source (~> 0.9.0) pry-rails (0.3.6) pry (>= 0.10.4) - puma (3.11.3) + puma (3.11.4) rack (2.0.4) rack-test (0.6.3) rack (>= 1.0) @@ -200,14 +203,14 @@ GEM thor (0.20.0) thread_safe (0.3.6) tilt (2.0.8) - turbolinks (5.1.0) + turbolinks (5.1.1) turbolinks-source (~> 5.1) turbolinks-source (5.1.0) tzinfo (1.2.5) thread_safe (~> 0.1) - uglifier (4.1.8) + uglifier (4.1.9) execjs (>= 0.3.0, < 3) - web-console (3.5.1) + web-console (3.6.0) actionview (>= 5.0) activemodel (>= 5.0) bindex (>= 0.4.0) @@ -222,6 +225,7 @@ PLATFORMS DEPENDENCIES autoprefixer-rails better_errors + binding_of_caller byebug coffee-rails (~> 4.2) dotenv-rails diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c12c7c17..6b2c9f03 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -14,4 +14,12 @@ def find_user @login_user = User.find_by(id: session[:user_id]) end end + + def require_login + if @login_user.nil? + flash[:status] = :failure + flash[:result_text] = "You must be logged in to view this section" + redirect_to root_path + end + end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index fbedea66..63bdea6f 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -1,80 +1,49 @@ class SessionsController < ApplicationController - def login_form - end - + before_action :require_login, except: [:login] - def create + def login 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.build_from_github(auth_hash[:uid]) - good_save = @user.save + if auth_hash[:uid] + # @user = User.find_by(uid: auth_hash[:uid], provider: 'github') + @user = User.find_by(uid: auth_hash[:uid], provider: params[:provider]) - if good_save + if @user.nil? + @user = User.build_from_provider(auth_hash) + successful_save = @user.save - flash[:success] = "Logged in successfully" + if successful_save session[:user_id] = @user.id + flash[:status] = :success + flash[:result_text] = "Successfully created new user #{@user.username} with ID #{@user.id}" redirect_to root_path else - flash[:error] = "Something happened in user creation" - redirect_to root_path + flash.now[:status] = :failure + flash.now[:result_text] = "Could not log in" + flash.now[:messages] = user.errors.messages + redirect_back fallback_location: auth_callback_path end + else - flash[:success] = "logged in successfully" session[:user_id] = @user.id + flash[:status] = :success + flash[:result_text] = "Successfully logged in as existing user #{@user.username}" redirect_to root_path end else - flash[:error] = "Something happened in user creation" - redirect_to root_path - + flash.now[:status] = :failure + flash.now[:result_text] = "Logging in through GitHub not successful" + redirect_back fallback_location: auth_callback_path end - def index - @user = User.find(session[:user_id]) # < recalls the value set in a previous request - end end - def destroy + def logout session[:user_id] = nil - flash[:success] = "Successfully logged out!" - - redirect_to root_path - end -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 - return - end + flash[:result_text] = "Successfully logged out" + redirect_to root_path end - redirect_to root_path -end - -def logout - session[:user_id] = nil - flash[:status] = :success - flash[:result_text] = "Successfully logged out" - redirect_to root_path end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 73b42652..efdf82c8 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 diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 2020bee4..0d452735 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -1,6 +1,7 @@ class WorksController < ApplicationController # We should always be able to tell what category # of work we're dealing with + before_action :require_login, except: [:root] before_action :category_from_work, except: [:root, :index, :new, :create] def root @@ -26,9 +27,9 @@ def create flash[:result_text] = "Successfully created #{@media_category.singularize} #{@work.id}" redirect_to work_path(@work) else - flash[:status] = :failure - flash[:result_text] = "Could not create #{@media_category.singularize}" - flash[:messages] = @work.errors.messages + flash.now[:status] = :failure + flash.now[:result_text] = "Could not create #{@media_category.singularize}" + flash.now[:messages] = @work.errors.messages render :new, status: :bad_request end end @@ -72,8 +73,6 @@ def upvote flash[:result_text] = "Could not upvote" flash[:messages] = vote.errors.messages end - else - flash[:result_text] = "You must log in to do that" end # Refresh the page to show either the updated vote count diff --git a/app/models/user.rb b/app/models/user.rb index 534c1057..0c8b884b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -4,10 +4,12 @@ class User < ApplicationRecord validates :username, uniqueness: true, presence: true - def self.build_from_github(auth_hash) - return User.create(provider: auth_hash[:provider], uid: auth_hash[:uid], username: auth_hash[:info][:nickname] + def self.build_from_provider(auth_hash) + return User.new( + provider: auth_hash[:provider], + uid: auth_hash[:uid], + email: auth_hash[:info][:email], + username: auth_hash[:info][:nickname] ) end - - end diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 063b645f..7e4ccf53 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -25,10 +25,12 @@ <%= link_to "View all users", users_path, class: "button" %>
- <% if session[:user_id] %> - <%= link_to "Log out", logout_path, method: "delete" , class: "button" %> -<% else %> - <%= link_to "Login with Github", "/auth/github", class: "button" %> + <% if @login_user %> + <%= link_to "Logged in as #{@login_user.username}", user_path(@login_user), class: "button" %> + <%= link_to "Log Out", logout_path, method: :delete, class: "button" %> + <% else %> + <%= link_to "Login with Github", github_login_path, class: "button" %> + <%= link_to "Login with Google", google_login_path, class: "button" %> <% end %>
diff --git a/config/routes.rb b/config/routes.rb index a792c673..78575ab4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,13 +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/:github/callback', to: 'sessions#create' - get '/auth/github', as: 'github_login' - delete '/logout', to: 'sessions#destroy', as: 'logout' + get '/auth/:provider/callback', to: 'sessions#login', as: 'auth_callback' + get '/auth/github', as: 'github_login' + get '/auth/google_oauth2', as: 'google_login' + # get '/login', to: 'sessions#login_form', as: 'login_form' + # post '/login', to: 'sessions#login', as: 'login' + delete '/logout', to: 'sessions#logout', as: 'logout' resources :works post '/works/:id/upvote', to: 'works#upvote', as: 'upvote' diff --git a/db/migrate/20180502032300_add_email_to_users.rb b/db/migrate/20180502032300_add_email_to_users.rb new file mode 100644 index 00000000..ee8639ae --- /dev/null +++ b/db/migrate/20180502032300_add_email_to_users.rb @@ -0,0 +1,5 @@ +class AddEmailToUsers < ActiveRecord::Migration[5.0] + def change + add_column :users, :email, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 12166690..8f9e1f66 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: 20180417212442) do +ActiveRecord::Schema.define(version: 20180502032300) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -21,6 +21,7 @@ t.datetime "updated_at", null: false t.integer "uid" t.string "provider" + t.string "email" 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..13916aee 100644 --- a/test/controllers/sessions_controller_test.rb +++ b/test/controllers/sessions_controller_test.rb @@ -2,4 +2,49 @@ describe SessionsController do + describe "login" do + it "should log in an existing user and redirect to the root path" do + existing_user = users(:dan) + + proc { + login(existing_user) + }.must_change 'User.count', 0 + + session[:user_id].must_equal existing_user.id + flash[:status].must_equal :success + must_respond_with :redirect + must_redirect_to root_path + end + + + it "should redirect to the root path if given invalid user data" do + invalid_user = User.new( + provider: 'github', + ) + + proc { + login(invalid_user) + }.must_change 'User.count', 0 + + session[:user_id].must_equal nil + flash.now[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to auth_callback_path + end + end + + describe "logout" do + it "should log out user and redirect to the root path" do + user_now = users(:dan) + login(user_now) + + logout(user_now) + + session[:user_id].must_equal nil + flash[:status].must_equal :success + flash[:result_text].must_equal "Successfully logged out" + must_respond_with :redirect + must_redirect_to root_path + end + end end diff --git a/test/controllers/users_controller_test.rb b/test/controllers/users_controller_test.rb index d2c5cfbb..c0e6ce39 100644 --- a/test/controllers/users_controller_test.rb +++ b/test/controllers/users_controller_test.rb @@ -2,4 +2,66 @@ describe UsersController do + describe "Logged in users" do + before do + @user = users(:dan) + end + + describe "index" do + it "succeeds when there are users" do + login(@user) + + get users_path + must_respond_with :success + end + end + + describe "show" do + it "succeeds for an extant user ID" do + login(@user) + + get user_path(users(:dan).id) + must_respond_with :success + end + + it "renders 404 not_found for a bogus user ID" do + login(@user) + + get user_path("fake_id") + must_respond_with :not_found + end + end + end + + describe "Guest users" do + describe "index" do + it "cannot access users index" do + get users_path + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + describe "show" do + it "cannot access show for an extant user ID" do + get user_path(users(:dan).id) + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "cannot access show for a bogus user ID" do + get user_path("Fake_user_id") + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + + end end diff --git a/test/controllers/works_controller_test.rb b/test/controllers/works_controller_test.rb index 04308dcd..380efb51 100644 --- a/test/controllers/works_controller_test.rb +++ b/test/controllers/works_controller_test.rb @@ -1,153 +1,425 @@ 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 - Work.where(category: "album").count.must_be :>, 0 - Work.where(category: "movie").count.must_be :>, 0 - Work.where(category: "book").count.must_be :>, 0 - get works_path - must_respond_with :success + describe "Logged in user" do + before do + @user = users(:dan) end - it "succeeds with one media type absent" do - # Precondition: there is at least one media in two of the categories - Work.where(category: "album").destroy_all + describe "root" do + it "succeeds with all media types" do + login(@user) - # Assumptions - Work.where(category: "album").must_be_empty - Work.where(category: "movie").count.must_be :>, 0 - Work.where(category: "book").count.must_be :>, 0 + get root_path - get root_path + must_respond_with :success + end - must_respond_with :success + it "succeeds with one media type absent" do + Work.all.where(category: "album").each do |work| + work.destroy + end + login(@user) + + get root_path + + Work.all.count.wont_equal 0 + Work.all.where(category: "album").count.must_equal 0 + must_respond_with :success + end + + it "succeeds with no media" do + Work.all.each do |work| + work.destroy + end + + login(@user) + + get root_path + must_respond_with :success + end end - it "succeeds with no media" do - Work.destroy_all + CATEGORIES = %w(albums books movies) + INVALID_CATEGORIES = ["nope", "42", "", " ", "albumstrailingtext"] - # Assumptions - Work.where(category: "album").must_be_empty - Work.where(category: "movie").must_be_empty - Work.where(category: "book").must_be_empty + describe "index" do + it "succeeds when there are works" do + login(@user) - get root_path + get works_path - must_respond_with :success + must_respond_with :success + end + it "succeeds when there are no works" do + Work.all.each do |work| + work.destroy + end + login(@user) + + get works_path + + Work.all.count.must_equal 0 + must_respond_with :success + end end - end - CATEGORIES = %w(albums books movies) - INVALID_CATEGORIES = ["nope", "42", "", " ", "albumstrailingtext"] + describe "new" do + it "succeeds" do + login(@user) - describe "index" do - it "succeeds when there are works" do + get new_work_path - Work.count.must_be :>=, 1 - get works_path + must_respond_with :success + end + end - must_respond_with :success + describe "create" do + it "creates a work with valid data for a real category" do + login(@user) + + proc { + post works_path, params: { + work: { + title: "New Work", + category: "movie" + } + } + }.must_change 'Work.count', 1 + + work_id = Work.find_by(title: "New Work").id + + flash[:status].must_equal :success + must_respond_with :redirect + must_redirect_to work_path(work_id) + end + + it "renders bad_request and does not update the DB for bogus data" do + login(@user) + + proc { + post works_path, params: { + work: { + category: "" + } + } + }.must_change 'Work.count', 0 + + flash.now[:status].must_equal :failure + must_respond_with :bad_request + end + + it "renders 400 bad_request for bogus categories" do + login(@user) + + proc { + post works_path, params: { + work: { + title: "New Work", + category: "Fake_Category" + } + } + }.must_change 'Work.count', 0 + + flash.now[:status].must_equal :failure + must_respond_with :bad_request + end end - it "succeeds when there are no works" do - Work.destroy_all + describe "show" do + it "succeeds for an extant work ID" do + login(@user) - Work.count.must_equal 0 + get work_path(works(:album).id) - get works_path - must_respond_with :success + must_respond_with :success + end + + it "renders 404 not_found for a bogus work ID" do + login(@user) + + get work_path("fake_work") + + must_respond_with :not_found + end end - end + describe "edit" do + it "succeeds for an extant work ID" do + login(@user) + + get edit_work_path(works(:album).id) + + must_respond_with :success + end + + it "renders 404 not_found for a bogus work ID" do + login(@user) + + get edit_work_path("Fake_work_id") - describe "new" do - it "succeeds" do - get new_work_path - assert_response :success + must_respond_with :not_found + end end - end -end + describe "update" do + it "succeeds for valid data and an extant work ID" do + login(@user) -describe "create" do - it "creates a work with valid data for a real category" do + put work_path(works(:album).id), params: { + work: { + title: "Old Title" + } + } + flash[:status].must_equal :success + must_respond_with :redirect + must_redirect_to work_path(works(:album).id) + end - end + it "renders 404 not_found for bogus data" do + login(@user) - it "renders bad_request and does not update the DB for bogus data" do + put work_path(works(:album).id), params: { + work: { + category: "Fake_data" + } + } - end + flash.now[:status].must_equal :failure + must_respond_with :not_found + end - it "renders 400 bad_request for bogus categories" do + it "renders 404 not_found for a bogus work ID" do + login(@user) - end + put work_path("Fake_work_id") -end + must_respond_with :not_found + end + end -describe "show" do - it "succeeds for an extant work ID" do + describe "destroy" do + it "succeeds for an extant work ID" do + login(@user) - end + proc { + delete work_path(works(:album).id) + }.must_change 'Work.count', -1 - it "renders 404 not_found for a bogus work ID" do + must_respond_with :redirect + must_redirect_to root_path + end - end -end + it "renders 404 not_found and does not update the DB for a bogus work ID" do + login(@user) -describe "edit" do - it "succeeds for an extant work ID" do + proc { + delete work_path("Fake_work_id") + }.must_change 'Work.count', 0 - end + must_respond_with 404 + end + end - it "renders 404 not_found for a bogus work ID" do + describe "upvote" do + it "succeeds for a logged-in user and a fresh user-vote pair" do + login(@user) - end -end + post upvote_path(works(:movie).id) -describe "update" do - it "succeeds for valid data and an extant work ID" do + flash[:status].must_equal :success + must_respond_with :redirect + must_redirect_to work_path(works(:movie).id) + end - end + it "redirects to the work page if the user has already voted for that work" do + login(@user) - it "renders bad_request for bogus data" do + post upvote_path(works(:album).id) + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to work_path(works(:album).id) + end + end end - it "renders 404 not_found for a bogus work ID" do + describe "Guest users" do + describe "root" do + it "succeeds with all media types" do + get root_path - end -end + must_respond_with :success + end -describe "destroy" do - it "succeeds for an extant work ID" do + it "succeeds with one media type absent" do + Work.all.where(category: "album").each do |work| + work.destroy + end - end + get root_path - it "renders 404 not_found and does not update the DB for a bogus work ID" do + Work.all.count.wont_equal 0 + Work.all.where(category: "album").count.must_equal 0 + must_respond_with :success + end - end -end + it "succeeds with no media" do + Work.all.each do |work| + work.destroy + end -describe "upvote" do + get root_path + must_respond_with :success + end + end - it "redirects to the work page if no user is logged in" do + describe "index" do + it "cannot get to works index path" do + get works_path - end + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end - it "redirects to the work page after the user has logged out" do + describe "new" do + it "cannot get to new work path" do + get new_work_path - end + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + describe "create" do + it "cannot get to create work path" do + post works_path, params: { + work: { + title: "New Work", + category: "album" + } + } + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end - it "succeeds for a logged-in user and a fresh user-vote pair" do + describe "show" do + it "cannot get to show with work id" do + get work_path(works(:album).id) - end + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "cannot get to show page for a bogus work ID" do + get work_path("Fake_work_id") + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + describe "edit" do + it "cannot get to edit page for an extant work ID" do + get edit_work_path(works(:album).id) - it "redirects to the work page if the user has already voted for that work" do + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "cannot get to edit page for a bogus work ID" do + get edit_work_path("foo") + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + describe "update" do + it "cannot update valid data for an extant work ID" do + put work_path(works(:album).id), params: { + work: { + title: "New Title" + } + } + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "cannot get to update with bogus data" do + put work_path(works(:album).id), params: { + work: { + category: "Fake!" + } + } + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "cannot access update for a bogus work ID" do + put work_path("Fake_data") + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + describe "destroy" do + it "cannot access destroy for an extant work ID" do + delete work_path(works(:album).id) + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "cannot access destroy for a bogus work ID" do + delete work_path("Fake_data") + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end + + describe "upvote" do + it "redirects to the work page if no user is logged in" do + post upvote_path(works(:album).id) + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + + it "redirects to the work page after the user has logged out" do + login(users(:dan)) + logout(users(:dan)) + + post upvote_path(works(:album).id) + + flash[:status].must_equal :failure + must_respond_with :redirect + must_redirect_to root_path + end + end end end diff --git a/test/fixtures/users.yml b/test/fixtures/users.yml index e2968d78..32b3574b 100644 --- a/test/fixtures/users.yml +++ b/test/fixtures/users.yml @@ -2,6 +2,12 @@ dan: username: dan + email: dan@gmail.com + uid: 11225 + provider: github kari: username: kari + email: kari@gmail.com + uid: 23235 + provider: github diff --git a/test/test_helper.rb b/test/test_helper.rb index 5b4fb667..f9196b9b 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -4,6 +4,7 @@ require "minitest/rails" require "minitest/skip_dsl" require "minitest/reporters" # for Colorized output +require "omniauth" # For colorful output! Minitest::Reporters.use!( @@ -22,5 +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 + + OmniAuth.config.test_mode = true + end + + def mock_auth_hash(user) + return { + provider: user.provider, + uid: user.uid, + info: { + email: user.email, + name: user.username + } + } + end + + def login(user) + OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(mock_auth_hash(user)) + get auth_callback_path(:github) + end + + def logout(user) + OmniAuth.config.mock_auth[:github] = OmniAuth::AuthHash.new(mock_auth_hash(user)) + delete logout_path + end end From 21507c354b8c6bf3df2e1bda5dad73aa32162e9f Mon Sep 17 00:00:00 2001 From: Brittany Jones Date: Tue, 1 May 2018 23:33:16 -0700 Subject: [PATCH 3/3] took out non working link --- app/views/layouts/application.html.erb | 1 - 1 file changed, 1 deletion(-) diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 7e4ccf53..ccfffada 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -30,7 +30,6 @@ <%= link_to "Log Out", logout_path, method: :delete, class: "button" %> <% else %> <%= link_to "Login with Github", github_login_path, class: "button" %> - <%= link_to "Login with Google", google_login_path, class: "button" %> <% end %>