From 4dd5d756e54e23366458e1f3b9257c4ec08abaa2 Mon Sep 17 00:00:00 2001 From: Laurence Date: Fri, 24 May 2019 12:34:57 +0100 Subject: [PATCH 01/28] Initial commit --- Gemfile | 4 +++- Gemfile.lock | 36 ++++++++++++++++++++++++++++++++++-- app.rb | 9 +++++++++ config.ru | 3 +++ spec/spec_helper.rb | 9 +++++++++ 5 files changed, 58 insertions(+), 3 deletions(-) create mode 100644 app.rb create mode 100644 config.ru diff --git a/Gemfile b/Gemfile index 905e0cf49d..12e1653f73 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,13 @@ source 'https://rubygems.org' -ruby '2.5.0' +ruby '2.6.0' gem 'rake' gem 'rubocop', '0.56.0' +gem 'sinatra' group :test do + gem 'capybara' gem 'rspec' gem 'simplecov', require: false gem 'simplecov-console', require: false diff --git a/Gemfile.lock b/Gemfile.lock index e6b4ce7c9b..c8d67518a1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,18 +1,40 @@ GEM remote: https://rubygems.org/ specs: + addressable (2.6.0) + public_suffix (>= 2.0.2, < 4.0) ansi (1.5.0) ast (2.4.0) + capybara (3.20.2) + addressable + mini_mime (>= 0.1.3) + nokogiri (~> 1.8) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (~> 1.2) + xpath (~> 3.2) diff-lcs (1.3) docile (1.1.5) hirb (0.7.3) json (2.1.0) + mini_mime (1.0.1) + mini_portile2 (2.4.0) + mustermann (1.0.3) + nokogiri (1.10.3) + mini_portile2 (~> 2.4.0) parallel (1.12.1) parser (2.5.1.0) ast (~> 2.4.0) powerpack (0.1.1) + public_suffix (3.0.3) + rack (2.0.7) + rack-protection (2.0.5) + rack + rack-test (1.1.0) + rack (>= 1.0, < 3) rainbow (3.0.0) rake (12.3.0) + regexp_parser (1.5.1) rspec (3.7.0) rspec-core (~> 3.7.0) rspec-expectations (~> 3.7.0) @@ -43,20 +65,30 @@ GEM hirb simplecov simplecov-html (0.10.2) + sinatra (2.0.5) + mustermann (~> 1.0) + rack (~> 2.0) + rack-protection (= 2.0.5) + tilt (~> 2.0) + tilt (2.0.9) unicode-display_width (1.3.2) + xpath (3.2.0) + nokogiri (~> 1.8) PLATFORMS ruby DEPENDENCIES + capybara rake rspec rubocop (= 0.56.0) simplecov simplecov-console + sinatra RUBY VERSION - ruby 2.5.0p0 + ruby 2.6.0p0 BUNDLED WITH - 1.16.1 + 1.17.2 diff --git a/app.rb b/app.rb new file mode 100644 index 0000000000..db6a07e2e0 --- /dev/null +++ b/app.rb @@ -0,0 +1,9 @@ +require 'sinatra/base' + +class Chitter < Sinatra::Base + get '/' do + 'Hello world' + end + + run! if app_file == $0 +end diff --git a/config.ru b/config.ru new file mode 100644 index 0000000000..dfe7fd55ac --- /dev/null +++ b/config.ru @@ -0,0 +1,3 @@ +require_relative './app.rb' + +run Chitter diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 252747d899..c31267bd16 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,15 @@ +ENV['RACK_ENV'] = 'test' + +require_relative '../app.rb' + +require 'capybara' +require 'capybara/rspec' +require 'rspec' require 'simplecov' require 'simplecov-console' +Capybara.app = Chitter + SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::Console, # Want a nice code coverage website? Uncomment this next line! From 7f92bed3d374d78a96c7e0cafafa7af40d2d6729 Mon Sep 17 00:00:00 2001 From: Laurence Date: Sun, 26 May 2019 11:56:47 +0100 Subject: [PATCH 02/28] Satisfied the first and second user stories - implemented the .post and .all class methods for the Peep class --- Gemfile | 1 + Gemfile.lock | 2 ++ app.rb | 13 ++++++++++++- db/migrations/01_create_peeps_table.sql | 1 + lib/peep.rb | 24 ++++++++++++++++++++++++ spec/features/posting_spec.rb | 9 +++++++++ spec/peep_spec.rb | 20 ++++++++++++++++++++ spec/setup_test_database.rb | 7 +++++++ spec/spec_helper.rb | 7 +++++++ views/index.erb | 10 ++++++++++ views/post.erb | 4 ++++ 11 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 db/migrations/01_create_peeps_table.sql create mode 100644 lib/peep.rb create mode 100644 spec/features/posting_spec.rb create mode 100644 spec/peep_spec.rb create mode 100644 spec/setup_test_database.rb create mode 100644 views/index.erb create mode 100644 views/post.erb diff --git a/Gemfile b/Gemfile index 12e1653f73..80657aaa40 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,7 @@ source 'https://rubygems.org' ruby '2.6.0' gem 'rake' +gem 'pg' gem 'rubocop', '0.56.0' gem 'sinatra' diff --git a/Gemfile.lock b/Gemfile.lock index c8d67518a1..356dabd12f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -25,6 +25,7 @@ GEM parallel (1.12.1) parser (2.5.1.0) ast (~> 2.4.0) + pg (1.1.4) powerpack (0.1.1) public_suffix (3.0.3) rack (2.0.7) @@ -80,6 +81,7 @@ PLATFORMS DEPENDENCIES capybara + pg rake rspec rubocop (= 0.56.0) diff --git a/app.rb b/app.rb index db6a07e2e0..a75f7d1ae8 100644 --- a/app.rb +++ b/app.rb @@ -1,8 +1,19 @@ require 'sinatra/base' +require_relative './lib/peep.rb' class Chitter < Sinatra::Base get '/' do - 'Hello world' + @peeps = Peep.all + erb(:index) + end + + get '/peeps/post' do + erb(:post) + end + + post '/peeps/post' do + Peep.post(text: params[:text]) + redirect '/' end run! if app_file == $0 diff --git a/db/migrations/01_create_peeps_table.sql b/db/migrations/01_create_peeps_table.sql new file mode 100644 index 0000000000..b28098082d --- /dev/null +++ b/db/migrations/01_create_peeps_table.sql @@ -0,0 +1 @@ +CREATE TABLE peeps(id SERIAL PRIMARY KEY, text VARCHAR(280)); diff --git a/lib/peep.rb b/lib/peep.rb new file mode 100644 index 0000000000..2997dcbbe6 --- /dev/null +++ b/lib/peep.rb @@ -0,0 +1,24 @@ +require 'pg' + +class Peep + def self.post(text:) + if ENV['ENVIRONMENT'] == 'test' + connection = PG.connect(dbname: 'chitter_test') + else + connection = PG.connect(dbname: 'chitter') + end + + connection.exec("INSERT INTO peeps (text) VALUES('#{text}');") + end + + def self.all + if ENV['ENVIRONMENT'] == 'test' + connection = PG.connect(dbname: 'chitter_test') + else + connection = PG.connect(dbname: 'chitter') + end + + result = connection.exec("SELECT * FROM peeps ORDER BY id DESC;") + result.map { |entry| entry } + end +end diff --git a/spec/features/posting_spec.rb b/spec/features/posting_spec.rb new file mode 100644 index 0000000000..f4234f88b7 --- /dev/null +++ b/spec/features/posting_spec.rb @@ -0,0 +1,9 @@ +feature "clicking 'Peep'" do + scenario "should post your peep on the index page" do + visit '/' + click_button('Post') + fill_in('text', with: 'I feel grrrrrreat') + click_button('Peep') + expect(page).to have_content('I feel grrrrrreat') + end +end diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb new file mode 100644 index 0000000000..a4712aa801 --- /dev/null +++ b/spec/peep_spec.rb @@ -0,0 +1,20 @@ +require_relative '../lib/peep' + +describe Peep do + describe '#post' do + it 'should insert an entry into the peep table' do + Peep.post(text: 'I feel grrrrrreat') + connection = PG.connect(dbname: 'chitter_test') + result = connection.exec("SELECT * FROM peeps") + expect(result.first['text']).to eq('I feel grrrrrreat') + end + end + + describe '#all' do + it 'should produce an array of peep entries' do + Peep.post(text: 'I feel grrrrrreat') + peeps = Peep.all + expect(peeps.first['text']).to eq('I feel grrrrrreat') + end + end +end diff --git a/spec/setup_test_database.rb b/spec/setup_test_database.rb new file mode 100644 index 0000000000..9daeb5f204 --- /dev/null +++ b/spec/setup_test_database.rb @@ -0,0 +1,7 @@ +require 'pg' + +def setup_test_database + connection = PG.connect(dbname: 'chitter_test') + + connection.exec("TRUNCATE peeps") +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index c31267bd16..0d0e981f94 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,12 +1,15 @@ ENV['RACK_ENV'] = 'test' +ENV['ENVIRONMENT'] = 'test' require_relative '../app.rb' +require_relative './setup_test_database' require 'capybara' require 'capybara/rspec' require 'rspec' require 'simplecov' require 'simplecov-console' +require 'sinatra' Capybara.app = Chitter @@ -18,6 +21,10 @@ SimpleCov.start RSpec.configure do |config| + config.before(:each) do + setup_test_database + end + config.after(:suite) do puts puts "\e[33mHave you considered running rubocop? It will help you improve your code!\e[0m" diff --git a/views/index.erb b/views/index.erb new file mode 100644 index 0000000000..e85b6d65a6 --- /dev/null +++ b/views/index.erb @@ -0,0 +1,10 @@ +

Chitter

+<% @peeps.each do |peep| %> +
+ <%= peep['text'] %> +
+<% end %> +
+
+ +
diff --git a/views/post.erb b/views/post.erb new file mode 100644 index 0000000000..3615b773f9 --- /dev/null +++ b/views/post.erb @@ -0,0 +1,4 @@ +
+ + +
From 41989c2063c4c9f2bc04186a58babd72ad18ab3e Mon Sep 17 00:00:00 2001 From: Laurence Date: Sun, 26 May 2019 12:20:08 +0100 Subject: [PATCH 03/28] Added time column --- db/migrations/02_add_time_column.sql | 1 + lib/peep.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 db/migrations/02_add_time_column.sql diff --git a/db/migrations/02_add_time_column.sql b/db/migrations/02_add_time_column.sql new file mode 100644 index 0000000000..8892061ff1 --- /dev/null +++ b/db/migrations/02_add_time_column.sql @@ -0,0 +1 @@ +ALTER TABLE peeps ADD time timestamp DEFAULT NOW(); diff --git a/lib/peep.rb b/lib/peep.rb index 2997dcbbe6..11c8518e70 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -18,7 +18,7 @@ def self.all connection = PG.connect(dbname: 'chitter') end - result = connection.exec("SELECT * FROM peeps ORDER BY id DESC;") + result = connection.exec("SELECT * FROM peeps ORDER BY time DESC;") result.map { |entry| entry } end end From c5a0b9cf3e87aead2d9a04af39a083e0e55d2d48 Mon Sep 17 00:00:00 2001 From: Laurence Date: Sun, 26 May 2019 22:00:01 +0100 Subject: [PATCH 04/28] Added timestamps and sign up page --- Gemfile | 5 +++-- Gemfile.lock | 4 +++- app.rb | 4 ++++ lib/peep.rb | 21 ++++++++++++++++++--- spec/features/index_spec.rb | 8 ++++++++ spec/features/posting_spec.rb | 7 ++----- spec/features/sign_up_spec.rb | 10 ++++++++++ spec/peep_spec.rb | 2 +- spec/spec_helper.rb | 3 ++- spec/web_helpers.rb | 13 +++++++++++++ views/index.erb | 7 ++++++- views/signup.erb | 11 +++++++++++ 12 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 spec/features/index_spec.rb create mode 100644 spec/features/sign_up_spec.rb create mode 100644 spec/web_helpers.rb create mode 100644 views/signup.erb diff --git a/Gemfile b/Gemfile index 80657aaa40..13ea80e54a 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,12 @@ source 'https://rubygems.org' -ruby '2.6.0' +ruby '2.5.0' -gem 'rake' gem 'pg' +gem 'rake' gem 'rubocop', '0.56.0' gem 'sinatra' +gem 'timecop' group :test do gem 'capybara' diff --git a/Gemfile.lock b/Gemfile.lock index 356dabd12f..9811636505 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -72,6 +72,7 @@ GEM rack-protection (= 2.0.5) tilt (~> 2.0) tilt (2.0.9) + timecop (0.9.1) unicode-display_width (1.3.2) xpath (3.2.0) nokogiri (~> 1.8) @@ -88,9 +89,10 @@ DEPENDENCIES simplecov simplecov-console sinatra + timecop RUBY VERSION - ruby 2.6.0p0 + ruby 2.5.0p0 BUNDLED WITH 1.17.2 diff --git a/app.rb b/app.rb index a75f7d1ae8..734a072ca0 100644 --- a/app.rb +++ b/app.rb @@ -16,5 +16,9 @@ class Chitter < Sinatra::Base redirect '/' end + get '/users/signup' do + erb(:signup) + end + run! if app_file == $0 end diff --git a/lib/peep.rb b/lib/peep.rb index 11c8518e70..b8132d5f4e 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,6 +1,13 @@ require 'pg' class Peep + attr_reader :text, :time + + def initialize(text:, time:) + @text = text + @time = time + end + def self.post(text:) if ENV['ENVIRONMENT'] == 'test' connection = PG.connect(dbname: 'chitter_test') @@ -8,7 +15,11 @@ def self.post(text:) connection = PG.connect(dbname: 'chitter') end - connection.exec("INSERT INTO peeps (text) VALUES('#{text}');") + query = "INSERT INTO peeps (text) VALUES('#{text}') + RETURNING text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time;" + + peep = connection.exec(query) + Peep.new(text: peep[0]['text'], time: peep[0]['time']) end def self.all @@ -18,7 +29,11 @@ def self.all connection = PG.connect(dbname: 'chitter') end - result = connection.exec("SELECT * FROM peeps ORDER BY time DESC;") - result.map { |entry| entry } + query = "SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time + FROM peeps + ORDER BY id DESC;" + + result = connection.exec(query) + result.map { |peep| Peep.new(text: peep['text'], time: peep['time']) } end end diff --git a/spec/features/index_spec.rb b/spec/features/index_spec.rb new file mode 100644 index 0000000000..34cca67beb --- /dev/null +++ b/spec/features/index_spec.rb @@ -0,0 +1,8 @@ +feature "index" do + scenario 'should contain multiple peeps' do + post_a_peep + post_another_peep + expect(page).to have_content('I feel grrrrrreat') + expect(page).to have_content('I really do') + end +end diff --git a/spec/features/posting_spec.rb b/spec/features/posting_spec.rb index f4234f88b7..6f9e523573 100644 --- a/spec/features/posting_spec.rb +++ b/spec/features/posting_spec.rb @@ -1,9 +1,6 @@ -feature "clicking 'Peep'" do +feature "clicking 'Peep' and entering text" do scenario "should post your peep on the index page" do - visit '/' - click_button('Post') - fill_in('text', with: 'I feel grrrrrreat') - click_button('Peep') + post_a_peep expect(page).to have_content('I feel grrrrrreat') end end diff --git a/spec/features/sign_up_spec.rb b/spec/features/sign_up_spec.rb new file mode 100644 index 0000000000..d6ea681920 --- /dev/null +++ b/spec/features/sign_up_spec.rb @@ -0,0 +1,10 @@ +feature "clicking 'Sign Up'" do + scenario "should take you to a sign up page" do + visit '/' + click_button 'Sign up' + expect(page).to have_field('email') + expect(page).to have_field('password') + expect(page).to have_field('name') + expect(page).to have_field('username') + end +end diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb index a4712aa801..7b2ec885ce 100644 --- a/spec/peep_spec.rb +++ b/spec/peep_spec.rb @@ -14,7 +14,7 @@ it 'should produce an array of peep entries' do Peep.post(text: 'I feel grrrrrreat') peeps = Peep.all - expect(peeps.first['text']).to eq('I feel grrrrrreat') + expect(peeps.first.text).to eq('I feel grrrrrreat') end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0d0e981f94..9a025b60d9 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -9,7 +9,6 @@ require 'rspec' require 'simplecov' require 'simplecov-console' -require 'sinatra' Capybara.app = Chitter @@ -21,6 +20,8 @@ SimpleCov.start RSpec.configure do |config| + require 'web_helpers' + config.before(:each) do setup_test_database end diff --git a/spec/web_helpers.rb b/spec/web_helpers.rb new file mode 100644 index 0000000000..7c67d9b77a --- /dev/null +++ b/spec/web_helpers.rb @@ -0,0 +1,13 @@ +def post_a_peep + visit '/' + click_button('Post') + fill_in('text', with: 'I feel grrrrrreat') + click_button('Peep') +end + +def post_another_peep + visit '/' + click_button('Post') + fill_in('text', with: 'I really do') + click_button('Peep') +end diff --git a/views/index.erb b/views/index.erb index e85b6d65a6..c423f888bb 100644 --- a/views/index.erb +++ b/views/index.erb @@ -1,7 +1,12 @@

Chitter

+
+ +
<% @peeps.each do |peep| %>
- <%= peep['text'] %> + <%= peep.text %> +
+ <%= peep.time %>
<% end %>
diff --git a/views/signup.erb b/views/signup.erb new file mode 100644 index 0000000000..b03b305ac4 --- /dev/null +++ b/views/signup.erb @@ -0,0 +1,11 @@ +

Sign up

+ +
+ +
+ +
+ +
+ +
From 18b05d8022ac98d0e5874a04d93fb1431a2c2bd0 Mon Sep 17 00:00:00 2001 From: Laurence Date: Sun, 26 May 2019 22:50:23 +0100 Subject: [PATCH 05/28] Signing up adds a user entry to the users database --- db/migrations/03_create_users_table.sql | 1 + lib/peep.rb | 23 +++++++++++--------- lib/user.rb | 28 +++++++++++++++++++++++++ spec/user_spec.rb | 14 +++++++++++++ views/signup.erb | 2 ++ 5 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 db/migrations/03_create_users_table.sql create mode 100644 lib/user.rb create mode 100644 spec/user_spec.rb diff --git a/db/migrations/03_create_users_table.sql b/db/migrations/03_create_users_table.sql new file mode 100644 index 0000000000..31184641fc --- /dev/null +++ b/db/migrations/03_create_users_table.sql @@ -0,0 +1 @@ +CREATE TABLE users(id SERIAL PRIMARY KEY, email VARCHAR(60), password VARCHAR(60), name VARCHAR(60), username VARCHAR(60)); diff --git a/lib/peep.rb b/lib/peep.rb index b8132d5f4e..b5b572dcef 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -3,7 +3,8 @@ class Peep attr_reader :text, :time - def initialize(text:, time:) + def initialize(id:, text:, time:) + @id = id @text = text @time = time end @@ -16,10 +17,10 @@ def self.post(text:) end query = "INSERT INTO peeps (text) VALUES('#{text}') - RETURNING text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time;" + RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time;" - peep = connection.exec(query) - Peep.new(text: peep[0]['text'], time: peep[0]['time']) + peep = connection.exec(query).first + Peep.new(id: peep['id'], text: peep['text'], time: peep['time']) end def self.all @@ -29,11 +30,13 @@ def self.all connection = PG.connect(dbname: 'chitter') end - query = "SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time - FROM peeps - ORDER BY id DESC;" - - result = connection.exec(query) - result.map { |peep| Peep.new(text: peep['text'], time: peep['time']) } + result = connection.exec("SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') + AS time + FROM peeps + ORDER BY id DESC;") + + result.map do |peep| + Peep.new(id: peep['id'], text: peep['text'], time: peep['time']) + end end end diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 0000000000..a2e751ddb6 --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,28 @@ +class User + attr_reader :id, :email, :name, :username + + def initialize(id:, email:, password:, name:, username:) + @id = id + @email = email + @password = password + @name = name + @username = username + end + + def self.sign_up(email:, password:, name:, username:) + if ENV['ENVIRONMENT'] == 'test' + connection = PG.connect(dbname: 'chitter_test') + else + connection = PG.connect(dbname: 'chitter') + end + + query = "INSERT INTO users (email, password, name, username) + VALUES('#{email}', '#{password}', '#{name}', '#{username}') + RETURNING id, email, password, name, username;" + + user = connection.exec(query).first + + User.new(id: user['id'], email: user['email'], password: user['password'], + name: user['name'], username: user['username']) + end +end diff --git a/spec/user_spec.rb b/spec/user_spec.rb new file mode 100644 index 0000000000..d2c6c471e4 --- /dev/null +++ b/spec/user_spec.rb @@ -0,0 +1,14 @@ +require 'user' + +describe User do + describe '#sign_up' do + it 'should add a user to the database' do + user = User.sign_up(email: 'test@test.com', password: 'password123', + name: 'test user', username: 'test_user') + + expect(user.email).to eq('test@test.com') + expect(user.name).to eq('test user') + expect(user.username).to eq('test_user') + end + end +end diff --git a/views/signup.erb b/views/signup.erb index b03b305ac4..3a66160778 100644 --- a/views/signup.erb +++ b/views/signup.erb @@ -8,4 +8,6 @@
+
+ From 5a17362d54b9bcd07c15720c336e9fe8c2375d7f Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 00:06:10 +0100 Subject: [PATCH 06/28] Added database connection class and spec, refactored peep.rb and user.rb --- app.rb | 1 + lib/database_connection.rb | 15 +++++++++++++++ lib/database_connection_setup.rb | 7 +++++++ lib/peep.rb | 25 +++++++------------------ lib/user.rb | 16 ++++++---------- spec/database_connection_spec.rb | 24 ++++++++++++++++++++++++ spec/database_helpers.rb | 11 +++++++++++ 7 files changed, 71 insertions(+), 28 deletions(-) create mode 100644 lib/database_connection.rb create mode 100644 lib/database_connection_setup.rb create mode 100644 spec/database_connection_spec.rb create mode 100644 spec/database_helpers.rb diff --git a/app.rb b/app.rb index 734a072ca0..d7681d5be8 100644 --- a/app.rb +++ b/app.rb @@ -1,5 +1,6 @@ require 'sinatra/base' require_relative './lib/peep.rb' +require_relative './lib/database_connection_setup' class Chitter < Sinatra::Base get '/' do diff --git a/lib/database_connection.rb b/lib/database_connection.rb new file mode 100644 index 0000000000..f535aa1419 --- /dev/null +++ b/lib/database_connection.rb @@ -0,0 +1,15 @@ +require 'pg' + +class DatabaseConnection + def self.setup(dbname) + @connection = PG.connect(dbname: dbname) + end + + def self.connection + @connection + end + + def self.query(sql) + @connection.exec(sql) + end +end diff --git a/lib/database_connection_setup.rb b/lib/database_connection_setup.rb new file mode 100644 index 0000000000..9eee7450a0 --- /dev/null +++ b/lib/database_connection_setup.rb @@ -0,0 +1,7 @@ +require 'database_connection' + +if ENV['ENVIRONMENT'] == 'test' + DatabaseConnection.setup('chitter_test') +else + DatabaseConnection.setup('chitter') +end diff --git a/lib/peep.rb b/lib/peep.rb index b5b572dcef..730af741cb 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,4 +1,4 @@ -require 'pg' +require 'database_connection' class Peep attr_reader :text, :time @@ -10,30 +10,19 @@ def initialize(id:, text:, time:) end def self.post(text:) - if ENV['ENVIRONMENT'] == 'test' - connection = PG.connect(dbname: 'chitter_test') - else - connection = PG.connect(dbname: 'chitter') - end - - query = "INSERT INTO peeps (text) VALUES('#{text}') + sql = "INSERT INTO peeps (text) VALUES('#{text}') RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time;" - peep = connection.exec(query).first + peep = DatabaseConnection.query(sql).first + Peep.new(id: peep['id'], text: peep['text'], time: peep['time']) end def self.all - if ENV['ENVIRONMENT'] == 'test' - connection = PG.connect(dbname: 'chitter_test') - else - connection = PG.connect(dbname: 'chitter') - end + sql = "SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time + FROM peeps ORDER BY id DESC;" - result = connection.exec("SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') - AS time - FROM peeps - ORDER BY id DESC;") + result = DatabaseConnection.query(sql) result.map do |peep| Peep.new(id: peep['id'], text: peep['text'], time: peep['time']) diff --git a/lib/user.rb b/lib/user.rb index a2e751ddb6..7ce6a8ae82 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -1,3 +1,5 @@ +require 'database_connection' + class User attr_reader :id, :email, :name, :username @@ -10,18 +12,12 @@ def initialize(id:, email:, password:, name:, username:) end def self.sign_up(email:, password:, name:, username:) - if ENV['ENVIRONMENT'] == 'test' - connection = PG.connect(dbname: 'chitter_test') - else - connection = PG.connect(dbname: 'chitter') - end + sql = "INSERT INTO users (email, password, name, username) + VALUES('#{email}', '#{password}', '#{name}', '#{username}') + RETURNING id, email, password, name, username;" - query = "INSERT INTO users (email, password, name, username) - VALUES('#{email}', '#{password}', '#{name}', '#{username}') - RETURNING id, email, password, name, username;" + user = DatabaseConnection.query(sql).first - user = connection.exec(query).first - User.new(id: user['id'], email: user['email'], password: user['password'], name: user['name'], username: user['username']) end diff --git a/spec/database_connection_spec.rb b/spec/database_connection_spec.rb new file mode 100644 index 0000000000..03761022f5 --- /dev/null +++ b/spec/database_connection_spec.rb @@ -0,0 +1,24 @@ +require 'database_connection' + +describe DatabaseConnection do + describe '#setup' do + it 'should set up a connection to the database' do + expect(PG).to receive(:connect).with(dbname: 'chitter_test') + + DatabaseConnection.setup('chitter_test') + end + + it 'should be a persistent connection' do + connection = DatabaseConnection.setup('chitter_test') + expect(DatabaseConnection.connection).to eq(connection) + end + end + + describe '#query' do + it 'should execute a query' do + connection = DatabaseConnection.setup('chitter_test') + expect(connection).to receive(:exec).with('SELECT * FROM peeps;') + DatabaseConnection.query('SELECT * FROM peeps;') + end + end +end diff --git a/spec/database_helpers.rb b/spec/database_helpers.rb new file mode 100644 index 0000000000..f9b76ad916 --- /dev/null +++ b/spec/database_helpers.rb @@ -0,0 +1,11 @@ +require 'pg' + +def persisted_data_peeps(id:) + connection = PG.connect(dbname: 'chitter_test') + connection.query("SELECT * FROM peeps WHERE id = '#{id}';") +end + +def persisted_data_users(id:) + connection = PG.connect(dbname: 'chitter_test') + connection.query("SELECT * FROM users WHERE id = '#{id}';") +end From bca4091cfc5e1f30dc824207d255a35d77a561b1 Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 00:22:58 +0100 Subject: [PATCH 07/28] Refactored sql queries in peep.rb, refactored specs to use database helpers --- lib/peep.rb | 6 +++--- spec/peep_spec.rb | 17 +++++++++++------ spec/user_spec.rb | 4 ++++ 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/peep.rb b/lib/peep.rb index 730af741cb..829bfea89c 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,7 +1,7 @@ require 'database_connection' class Peep - attr_reader :text, :time + attr_reader :id, :text, :time def initialize(id:, text:, time:) @id = id @@ -11,7 +11,7 @@ def initialize(id:, text:, time:) def self.post(text:) sql = "INSERT INTO peeps (text) VALUES('#{text}') - RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time;" + RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time;" peep = DatabaseConnection.query(sql).first @@ -20,7 +20,7 @@ def self.post(text:) def self.all sql = "SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time - FROM peeps ORDER BY id DESC;" + FROM peeps ORDER BY id DESC;" result = DatabaseConnection.query(sql) diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb index 7b2ec885ce..31bc5adb77 100644 --- a/spec/peep_spec.rb +++ b/spec/peep_spec.rb @@ -1,20 +1,25 @@ -require_relative '../lib/peep' +require 'peep' +require 'database_helpers' describe Peep do describe '#post' do it 'should insert an entry into the peep table' do - Peep.post(text: 'I feel grrrrrreat') - connection = PG.connect(dbname: 'chitter_test') - result = connection.exec("SELECT * FROM peeps") - expect(result.first['text']).to eq('I feel grrrrrreat') + peep = Peep.post(text: 'I feel grrrrrreat') + persisted_data = persisted_data_peeps(id: peep.id) + + expect(peep).to be_an_instance_of Peep + expect(peep.id).to eq(persisted_data.first['id']) + expect(peep.text).to eq('I feel grrrrrreat') end end describe '#all' do it 'should produce an array of peep entries' do Peep.post(text: 'I feel grrrrrreat') + Peep.post(text: 'I really do') peeps = Peep.all - expect(peeps.first.text).to eq('I feel grrrrrreat') + array = ['I really do', 'I feel grrrrrreat'] + expect(peeps.map { |peep| peep.text }).to eq(array) end end end diff --git a/spec/user_spec.rb b/spec/user_spec.rb index d2c6c471e4..663656b54d 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -1,4 +1,5 @@ require 'user' +require 'database_helpers' describe User do describe '#sign_up' do @@ -6,6 +7,9 @@ user = User.sign_up(email: 'test@test.com', password: 'password123', name: 'test user', username: 'test_user') + persisted_data = persisted_data_users(id: user.id) + + expect(user.id).to eq(persisted_data.first['id']) expect(user.email).to eq('test@test.com') expect(user.name).to eq('test user') expect(user.username).to eq('test_user') From 1c3f12924225ec03e6224ebf5f0a2d3cc869f416 Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 11:35:00 +0100 Subject: [PATCH 08/28] Added unique_email method, added web helper methods --- app.rb | 4 ++++ lib/database_connection_setup.rb | 2 +- lib/peep.rb | 2 +- lib/user.rb | 8 ++++++++ spec/features/sign_up_spec.rb | 8 ++++++++ spec/user_spec.rb | 29 ++++++++++++++++++++++------- spec/web_helpers.rb | 20 ++++++++++++++++++++ 7 files changed, 64 insertions(+), 9 deletions(-) diff --git a/app.rb b/app.rb index d7681d5be8..267ede0f11 100644 --- a/app.rb +++ b/app.rb @@ -21,5 +21,9 @@ class Chitter < Sinatra::Base erb(:signup) end + post '/users/signup' do + p params + end + run! if app_file == $0 end diff --git a/lib/database_connection_setup.rb b/lib/database_connection_setup.rb index 9eee7450a0..591438c79c 100644 --- a/lib/database_connection_setup.rb +++ b/lib/database_connection_setup.rb @@ -1,4 +1,4 @@ -require 'database_connection' +require_relative './database_connection' if ENV['ENVIRONMENT'] == 'test' DatabaseConnection.setup('chitter_test') diff --git a/lib/peep.rb b/lib/peep.rb index 829bfea89c..2ba8f68dc5 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,4 +1,4 @@ -require 'database_connection' +require_relative './database_connection' class Peep attr_reader :id, :text, :time diff --git a/lib/user.rb b/lib/user.rb index 7ce6a8ae82..7bdb7398d3 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -21,4 +21,12 @@ def self.sign_up(email:, password:, name:, username:) User.new(id: user['id'], email: user['email'], password: user['password'], name: user['name'], username: user['username']) end + + def self.unique_email?(email) + sql = "SELECT email FROM users WHERE email = '#{email}';" + + result = DatabaseConnection.query(sql) + + result.count == 0 + end end diff --git a/spec/features/sign_up_spec.rb b/spec/features/sign_up_spec.rb index d6ea681920..41cd96de45 100644 --- a/spec/features/sign_up_spec.rb +++ b/spec/features/sign_up_spec.rb @@ -8,3 +8,11 @@ expect(page).to have_field('username') end end + +feature "using a non-unique email" do + scenario "should return you to the sign up page with a prompt" do + sign_up_user + sign_up_another_user + expect(page).to have_content('Email already in use') + end +end diff --git a/spec/user_spec.rb b/spec/user_spec.rb index 663656b54d..18ee9a9de9 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -2,17 +2,32 @@ require 'database_helpers' describe User do + let(:user_signup) { User.sign_up(email: 'test@test.com', + password: 'password123', + name: 'test user', + username: 'test_user') } + describe '#sign_up' do it 'should add a user to the database' do - user = User.sign_up(email: 'test@test.com', password: 'password123', - name: 'test user', username: 'test_user') + persisted_data = persisted_data_users(id: user_signup.id) - persisted_data = persisted_data_users(id: user.id) + expect(user_signup).to be_an_instance_of(User) + expect(user_signup.id).to eq(persisted_data.first['id']) + expect(user_signup.email).to eq('test@test.com') + expect(user_signup.name).to eq('test user') + expect(user_signup.username).to eq('test_user') + end + end + + describe '#unique_email?' do + it 'should return true if email is unique' do + user_signup + expect(User.unique_email?('unique@unique.com')).to eq(true) + end - expect(user.id).to eq(persisted_data.first['id']) - expect(user.email).to eq('test@test.com') - expect(user.name).to eq('test user') - expect(user.username).to eq('test_user') + it 'should return false if email is not unique' do + user_signup + expect(User.unique_email?('test@test.com')).to eq(false) end end end diff --git a/spec/web_helpers.rb b/spec/web_helpers.rb index 7c67d9b77a..8f7a246a90 100644 --- a/spec/web_helpers.rb +++ b/spec/web_helpers.rb @@ -11,3 +11,23 @@ def post_another_peep fill_in('text', with: 'I really do') click_button('Peep') end + +def sign_up_user + visit '/' + click_button 'Sign up' + fill_in('email', with: 'test@test.com') + fill_in('password', with: 'password123') + fill_in('name', with: 'test user') + fill_in('username', with: 'test_user1') + click_button('Submit') +end + +def sign_up_another_user + visit '/' + click_button 'Sign up' + fill_in('email', with: 'test@test.com') + fill_in('password', with: 'password123') + fill_in('name', with: 'test user') + fill_in('username', with: 'test_user2') + click_button('Submit') +end From f70ad508ecb2f6aada4748ad8d95710522df9dce Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 13:19:10 +0100 Subject: [PATCH 09/28] Added the unique_email? and unique_username? methods to user.rb --- app.rb | 17 +++++++++++++++-- lib/database_connection_setup.rb | 2 +- lib/peep.rb | 2 +- lib/user.rb | 10 ++++++++-- spec/features/sign_up_spec.rb | 12 ++++++++++-- spec/setup_test_database.rb | 1 + spec/user_spec.rb | 22 ++++++++++++++++++---- spec/web_helpers.rb | 12 +++++++++++- views/signup_fail.erb | 15 +++++++++++++++ 9 files changed, 80 insertions(+), 13 deletions(-) create mode 100644 views/signup_fail.erb diff --git a/app.rb b/app.rb index 267ede0f11..388e546cbf 100644 --- a/app.rb +++ b/app.rb @@ -1,8 +1,11 @@ require 'sinatra/base' require_relative './lib/peep.rb' -require_relative './lib/database_connection_setup' +require_relative './lib/user.rb' +require_relative './lib/database_connection_setup.rb' class Chitter < Sinatra::Base + enable :sessions + get '/' do @peeps = Peep.all erb(:index) @@ -22,7 +25,17 @@ class Chitter < Sinatra::Base end post '/users/signup' do - p params + session[:unique_email] = User.unique_email?(params[:email]) + redirect '/users/signup-fail' unless session[:unique_email] + + User.sign_up(email: params[:email], password: params[:password], + name: params[:name], username: params[:username]) + + redirect '/' + end + + get '/users/signup-fail' do + erb(:signup_fail) end run! if app_file == $0 diff --git a/lib/database_connection_setup.rb b/lib/database_connection_setup.rb index 591438c79c..73789b73c0 100644 --- a/lib/database_connection_setup.rb +++ b/lib/database_connection_setup.rb @@ -1,4 +1,4 @@ -require_relative './database_connection' +require_relative './database_connection.rb' if ENV['ENVIRONMENT'] == 'test' DatabaseConnection.setup('chitter_test') diff --git a/lib/peep.rb b/lib/peep.rb index 2ba8f68dc5..fcf5d55cb9 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,4 +1,4 @@ -require_relative './database_connection' +require_relative './database_connection.rb' class Peep attr_reader :id, :text, :time diff --git a/lib/user.rb b/lib/user.rb index 7bdb7398d3..bb310223c2 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -1,4 +1,4 @@ -require 'database_connection' +require_relative './database_connection.rb' class User attr_reader :id, :email, :name, :username @@ -24,9 +24,15 @@ def self.sign_up(email:, password:, name:, username:) def self.unique_email?(email) sql = "SELECT email FROM users WHERE email = '#{email}';" + result = DatabaseConnection.query(sql) + + result.count.zero? + end + def self.unique_username?(username) + sql = "SELECT username FROM users WHERE username = '#{username}';" result = DatabaseConnection.query(sql) - result.count == 0 + result.count.zero? end end diff --git a/spec/features/sign_up_spec.rb b/spec/features/sign_up_spec.rb index 41cd96de45..28d4ccb68f 100644 --- a/spec/features/sign_up_spec.rb +++ b/spec/features/sign_up_spec.rb @@ -12,7 +12,15 @@ feature "using a non-unique email" do scenario "should return you to the sign up page with a prompt" do sign_up_user - sign_up_another_user - expect(page).to have_content('Email already in use') + sign_up_same_email + expect(page).to have_content('Email in use') + end +end + +feature "using a non-unique username" do + scenario "should return you to the sign up page with a prompt" do + sign_up_user + sign_up_same_username + expect(page).to have_content('Username in use') end end diff --git a/spec/setup_test_database.rb b/spec/setup_test_database.rb index 9daeb5f204..89a4d1797e 100644 --- a/spec/setup_test_database.rb +++ b/spec/setup_test_database.rb @@ -4,4 +4,5 @@ def setup_test_database connection = PG.connect(dbname: 'chitter_test') connection.exec("TRUNCATE peeps") + connection.exec("TRUNCATE users") end diff --git a/spec/user_spec.rb b/spec/user_spec.rb index 18ee9a9de9..bc644aac9d 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -2,10 +2,12 @@ require 'database_helpers' describe User do - let(:user_signup) { User.sign_up(email: 'test@test.com', - password: 'password123', - name: 'test user', - username: 'test_user') } + let(:user_signup) do + User.sign_up(email: 'test@test.com', + password: 'password123', + name: 'test user', + username: 'test_user') + end describe '#sign_up' do it 'should add a user to the database' do @@ -30,4 +32,16 @@ expect(User.unique_email?('test@test.com')).to eq(false) end end + + describe '#unique_username?' do + it 'should return true if username is unique' do + user_signup + expect(User.unique_username?('unique_user')).to eq(true) + end + + it 'should return false if username is not unique' do + user_signup + expect(User.unique_username?('test_user')).to eq(false) + end + end end diff --git a/spec/web_helpers.rb b/spec/web_helpers.rb index 8f7a246a90..484c571670 100644 --- a/spec/web_helpers.rb +++ b/spec/web_helpers.rb @@ -22,7 +22,7 @@ def sign_up_user click_button('Submit') end -def sign_up_another_user +def sign_up_same_email visit '/' click_button 'Sign up' fill_in('email', with: 'test@test.com') @@ -31,3 +31,13 @@ def sign_up_another_user fill_in('username', with: 'test_user2') click_button('Submit') end + +def sign_up_same_username + visit '/' + click_button 'Sign up' + fill_in('email', with: 'unique@unique.com') + fill_in('password', with: 'password123') + fill_in('name', with: 'test user') + fill_in('username', with: 'test_user1') + click_button('Submit') +end diff --git a/views/signup_fail.erb b/views/signup_fail.erb new file mode 100644 index 0000000000..da2e7a7149 --- /dev/null +++ b/views/signup_fail.erb @@ -0,0 +1,15 @@ +

Sign up

+ +

Email in use

+ +
+ +
+ +
+ +
+ +
+ +
From af9d7fd0c01cc72b692de5dc87d9a4ef8e2c0cfd Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 13:50:15 +0100 Subject: [PATCH 10/28] Added prompts to signup fail page --- app.rb | 8 ++++++-- lib/database_connection.rb | 8 ++++---- views/signup_fail.erb | 2 +- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app.rb b/app.rb index 388e546cbf..6b3c34f621 100644 --- a/app.rb +++ b/app.rb @@ -26,7 +26,10 @@ class Chitter < Sinatra::Base post '/users/signup' do session[:unique_email] = User.unique_email?(params[:email]) - redirect '/users/signup-fail' unless session[:unique_email] + + unless session[:unique_email] && User.unique_username?(params[:username]) + redirect '/users/signup/fail' + end User.sign_up(email: params[:email], password: params[:password], name: params[:name], username: params[:username]) @@ -34,7 +37,8 @@ class Chitter < Sinatra::Base redirect '/' end - get '/users/signup-fail' do + get '/users/signup/fail' do + session[:unique_email] ? @fail = 'Username in use' : @fail = 'Email in use' erb(:signup_fail) end diff --git a/lib/database_connection.rb b/lib/database_connection.rb index f535aa1419..1d019533b9 100644 --- a/lib/database_connection.rb +++ b/lib/database_connection.rb @@ -5,11 +5,11 @@ def self.setup(dbname) @connection = PG.connect(dbname: dbname) end - def self.connection - @connection - end - def self.query(sql) @connection.exec(sql) end + + class << self + attr_reader :connection + end end diff --git a/views/signup_fail.erb b/views/signup_fail.erb index da2e7a7149..42c9432b17 100644 --- a/views/signup_fail.erb +++ b/views/signup_fail.erb @@ -1,6 +1,6 @@

Sign up

-

Email in use

+

<%= @fail %>

From 4073c16d1295a16a971dbcd63a7dd25423f62664 Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 14:19:19 +0100 Subject: [PATCH 11/28] Added tests for showing name/ username, added userid column to peeps --- app.rb | 9 +++++++-- db/migrations/04_add_userid_column.sql | 1 + spec/features/index_spec.rb | 7 +++++++ spec/peep_spec.rb | 6 ++++++ 4 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 db/migrations/04_add_userid_column.sql diff --git a/app.rb b/app.rb index 6b3c34f621..7de0f21c9e 100644 --- a/app.rb +++ b/app.rb @@ -8,6 +8,8 @@ class Chitter < Sinatra::Base get '/' do @peeps = Peep.all + @name = session[:name] + @username = session[:username] erb(:index) end @@ -31,8 +33,11 @@ class Chitter < Sinatra::Base redirect '/users/signup/fail' end - User.sign_up(email: params[:email], password: params[:password], - name: params[:name], username: params[:username]) + user = User.sign_up(email: params[:email], password: params[:password], + name: params[:name], username: params[:username]) + + session[:name] = user.name + session[:username] = user.username redirect '/' end diff --git a/db/migrations/04_add_userid_column.sql b/db/migrations/04_add_userid_column.sql new file mode 100644 index 0000000000..b0f49ce9c1 --- /dev/null +++ b/db/migrations/04_add_userid_column.sql @@ -0,0 +1 @@ +ALTER TABLE peeps ADD userid INT; diff --git a/spec/features/index_spec.rb b/spec/features/index_spec.rb index 34cca67beb..2180729070 100644 --- a/spec/features/index_spec.rb +++ b/spec/features/index_spec.rb @@ -5,4 +5,11 @@ expect(page).to have_content('I feel grrrrrreat') expect(page).to have_content('I really do') end + + scenario 'should show name and user handle of poster after signing up' do + sign_up_user + post_a_peep + expect(page).to have_content('test user') + expect(page).to have_content('@test_user1') + end end diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb index 31bc5adb77..f901ea4999 100644 --- a/spec/peep_spec.rb +++ b/spec/peep_spec.rb @@ -22,4 +22,10 @@ expect(peeps.map { |peep| peep.text }).to eq(array) end end + + describe '#get_user' do + it 'should return the name and username of the peep poster' do + + end + end end From f36bcee365ea5b67186366e1c1ad23cbcd13d0b6 Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 15:04:11 +0100 Subject: [PATCH 12/28] Post button only appears on index page if you are signed in --- app.rb | 8 +++----- lib/peep.rb | 14 +++++++++----- lib/user.rb | 2 -- spec/features/index_spec.rb | 6 ++++++ spec/features/posting_spec.rb | 1 + spec/peep_spec.rb | 14 +++++--------- views/index.erb | 2 ++ 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app.rb b/app.rb index 7de0f21c9e..d920dca69f 100644 --- a/app.rb +++ b/app.rb @@ -8,8 +8,7 @@ class Chitter < Sinatra::Base get '/' do @peeps = Peep.all - @name = session[:name] - @username = session[:username] + @signed_up = !session[:userid].nil? erb(:index) end @@ -18,7 +17,7 @@ class Chitter < Sinatra::Base end post '/peeps/post' do - Peep.post(text: params[:text]) + Peep.post(text: params[:text], userid: session[:userid]) redirect '/' end @@ -36,8 +35,7 @@ class Chitter < Sinatra::Base user = User.sign_up(email: params[:email], password: params[:password], name: params[:name], username: params[:username]) - session[:name] = user.name - session[:username] = user.username + session[:userid] = user.id redirect '/' end diff --git a/lib/peep.rb b/lib/peep.rb index fcf5d55cb9..8f0bee7efd 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -3,19 +3,22 @@ class Peep attr_reader :id, :text, :time - def initialize(id:, text:, time:) + def initialize(id:, text:, time:, userid:) @id = id @text = text @time = time + @userid = userid end - def self.post(text:) + def self.post(text:, userid:) sql = "INSERT INTO peeps (text) VALUES('#{text}') - RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time;" + RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time, + userid;" peep = DatabaseConnection.query(sql).first - Peep.new(id: peep['id'], text: peep['text'], time: peep['time']) + Peep.new(id: peep['id'], text: peep['text'], time: peep['time'], + userid: peep['userid']) end def self.all @@ -25,7 +28,8 @@ def self.all result = DatabaseConnection.query(sql) result.map do |peep| - Peep.new(id: peep['id'], text: peep['text'], time: peep['time']) + Peep.new(id: peep['id'], text: peep['text'], time: peep['time'], + userid: peep['userid']) end end end diff --git a/lib/user.rb b/lib/user.rb index bb310223c2..98b0dc8154 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -25,14 +25,12 @@ def self.sign_up(email:, password:, name:, username:) def self.unique_email?(email) sql = "SELECT email FROM users WHERE email = '#{email}';" result = DatabaseConnection.query(sql) - result.count.zero? end def self.unique_username?(username) sql = "SELECT username FROM users WHERE username = '#{username}';" result = DatabaseConnection.query(sql) - result.count.zero? end end diff --git a/spec/features/index_spec.rb b/spec/features/index_spec.rb index 2180729070..e2128cf166 100644 --- a/spec/features/index_spec.rb +++ b/spec/features/index_spec.rb @@ -1,5 +1,11 @@ feature "index" do + scenario 'should not have Post button if not signed up' do + visit '/' + expect(page).not_to have_selector(:link_or_button, 'Post') + end + scenario 'should contain multiple peeps' do + sign_up_user post_a_peep post_another_peep expect(page).to have_content('I feel grrrrrreat') diff --git a/spec/features/posting_spec.rb b/spec/features/posting_spec.rb index 6f9e523573..fa6aa0d14d 100644 --- a/spec/features/posting_spec.rb +++ b/spec/features/posting_spec.rb @@ -1,5 +1,6 @@ feature "clicking 'Peep' and entering text" do scenario "should post your peep on the index page" do + sign_up_user post_a_peep expect(page).to have_content('I feel grrrrrreat') end diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb index f901ea4999..deb73f87b4 100644 --- a/spec/peep_spec.rb +++ b/spec/peep_spec.rb @@ -2,9 +2,11 @@ require 'database_helpers' describe Peep do + let(:userid) { 123 } + describe '#post' do it 'should insert an entry into the peep table' do - peep = Peep.post(text: 'I feel grrrrrreat') + peep = Peep.post(text: 'I feel grrrrrreat', userid: userid) persisted_data = persisted_data_peeps(id: peep.id) expect(peep).to be_an_instance_of Peep @@ -15,17 +17,11 @@ describe '#all' do it 'should produce an array of peep entries' do - Peep.post(text: 'I feel grrrrrreat') - Peep.post(text: 'I really do') + Peep.post(text: 'I feel grrrrrreat', userid: userid) + Peep.post(text: 'I really do', userid: userid) peeps = Peep.all array = ['I really do', 'I feel grrrrrreat'] expect(peeps.map { |peep| peep.text }).to eq(array) end end - - describe '#get_user' do - it 'should return the name and username of the peep poster' do - - end - end end diff --git a/views/index.erb b/views/index.erb index c423f888bb..50e49bc78a 100644 --- a/views/index.erb +++ b/views/index.erb @@ -10,6 +10,8 @@
<% end %>
+<% if @signed_up %> +<% end %> From 3b3494ba4dcca900f296461afb96bd9e660f7b5a Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 15:47:55 +0100 Subject: [PATCH 13/28] Added get_user method in peep.rb --- lib/peep.rb | 7 ++++++- spec/peep_spec.rb | 19 ++++++++++++++++--- spec/user_spec.rb | 12 ++++++++---- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/peep.rb b/lib/peep.rb index 8f0bee7efd..9d7c0b5a40 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -11,7 +11,7 @@ def initialize(id:, text:, time:, userid:) end def self.post(text:, userid:) - sql = "INSERT INTO peeps (text) VALUES('#{text}') + sql = "INSERT INTO peeps (text, userid) VALUES('#{text}', '#{userid}') RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time, userid;" @@ -32,4 +32,9 @@ def self.all userid: peep['userid']) end end + + def get_user(userid) + sql = "SELECT name, username FROM users WHERE id = #{userid}" + DatabaseConnection.query(sql).first + end end diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb index deb73f87b4..d3c2f5a269 100644 --- a/spec/peep_spec.rb +++ b/spec/peep_spec.rb @@ -16,12 +16,25 @@ end describe '#all' do - it 'should produce an array of peep entries' do + it 'should produce an array of peep objects' do Peep.post(text: 'I feel grrrrrreat', userid: userid) Peep.post(text: 'I really do', userid: userid) peeps = Peep.all - array = ['I really do', 'I feel grrrrrreat'] - expect(peeps.map { |peep| peep.text }).to eq(array) + expect(peeps.all? { |peep| peep.is_a?(Peep) }).to eq(true) + end + end + + describe '#get_user' do + it 'should return the name and username of the peep poster' do + peep = Peep.post(text: 'I feel grrrrrreat', userid: userid) + + sql = "INSERT INTO users (id, email, password, name, username) + VALUES('#{userid}', 'a@a.com', '123', 'Laurence', 'L123');" + + DatabaseConnection.query(sql) + hash = peep.get_user(userid) + expect(hash['name']).to eq('Laurence') + expect(hash['username']).to eq('L123') end end end diff --git a/spec/user_spec.rb b/spec/user_spec.rb index bc644aac9d..bbe1e6074f 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -22,25 +22,29 @@ end describe '#unique_email?' do - it 'should return true if email is unique' do + before(:each) do user_signup + end + + it 'should return true if email is unique' do expect(User.unique_email?('unique@unique.com')).to eq(true) end it 'should return false if email is not unique' do - user_signup expect(User.unique_email?('test@test.com')).to eq(false) end end describe '#unique_username?' do - it 'should return true if username is unique' do + before(:each) do user_signup + end + + it 'should return true if username is unique' do expect(User.unique_username?('unique_user')).to eq(true) end it 'should return false if username is not unique' do - user_signup expect(User.unique_username?('test_user')).to eq(false) end end From e2ca37b4fee2d1b96ea81ed45bc9220af3573310 Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 16:41:48 +0100 Subject: [PATCH 14/28] Fully implemented the sign up feature --- lib/peep.rb | 7 ++++--- views/index.erb | 3 +++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/peep.rb b/lib/peep.rb index 9d7c0b5a40..ec52c47056 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,7 +1,7 @@ require_relative './database_connection.rb' class Peep - attr_reader :id, :text, :time + attr_reader :id, :text, :time, :userid def initialize(id:, text:, time:, userid:) @id = id @@ -11,7 +11,7 @@ def initialize(id:, text:, time:, userid:) end def self.post(text:, userid:) - sql = "INSERT INTO peeps (text, userid) VALUES('#{text}', '#{userid}') + sql = "INSERT INTO peeps (text, userid) VALUES('#{text}', #{userid}) RETURNING id, text, to_char(time,'HH24:MI - DD Mon YYYY') AS time, userid;" @@ -22,7 +22,8 @@ def self.post(text:, userid:) end def self.all - sql = "SELECT text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time + sql = "SELECT id, text, to_char(time, 'HH24:MI - DD Mon YYYY') AS time, + userid FROM peeps ORDER BY id DESC;" result = DatabaseConnection.query(sql) diff --git a/views/index.erb b/views/index.erb index 50e49bc78a..3a5dcabb4f 100644 --- a/views/index.erb +++ b/views/index.erb @@ -3,6 +3,9 @@ <% @peeps.each do |peep| %> +
+ <% user = peep.get_user(peep.userid) %> + <%= user['name'] %> @<%= user['username'] %>
<%= peep.text %>
From 55b22ddeaf660453bcfea1bf7cf28057c62e2a8a Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 18:55:52 +0100 Subject: [PATCH 15/28] Refactoring --- app.rb | 6 ++--- lib/peep.rb | 4 +-- spec/features/posting_spec.rb | 4 +-- spec/features/sign_up_spec.rb | 26 ------------------- spec/features/signing_up_spec.rb | 13 ++++++++++ .../{index_spec.rb => viewing_index_spec.rb} | 8 +++--- spec/peep_spec.rb | 4 +-- spec/web_helpers.rb | 10 +++---- views/index.erb | 4 ++- views/post.erb | 4 ++- views/signup.erb | 16 +++++++++--- views/signup_fail.erb | 18 +++++++++---- 12 files changed, 62 insertions(+), 55 deletions(-) delete mode 100644 spec/features/sign_up_spec.rb create mode 100644 spec/features/signing_up_spec.rb rename spec/features/{index_spec.rb => viewing_index_spec.rb} (65%) diff --git a/app.rb b/app.rb index d920dca69f..8b0d7f287e 100644 --- a/app.rb +++ b/app.rb @@ -6,7 +6,7 @@ class Chitter < Sinatra::Base enable :sessions - get '/' do + get '/peeps' do @peeps = Peep.all @signed_up = !session[:userid].nil? erb(:index) @@ -18,7 +18,7 @@ class Chitter < Sinatra::Base post '/peeps/post' do Peep.post(text: params[:text], userid: session[:userid]) - redirect '/' + redirect '/peeps' end get '/users/signup' do @@ -37,7 +37,7 @@ class Chitter < Sinatra::Base session[:userid] = user.id - redirect '/' + redirect '/peeps' end get '/users/signup/fail' do diff --git a/lib/peep.rb b/lib/peep.rb index ec52c47056..cd82b32ee8 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -34,8 +34,8 @@ def self.all end end - def get_user(userid) - sql = "SELECT name, username FROM users WHERE id = #{userid}" + def user_info + sql = "SELECT name, username FROM users WHERE id = #{@userid}" DatabaseConnection.query(sql).first end end diff --git a/spec/features/posting_spec.rb b/spec/features/posting_spec.rb index fa6aa0d14d..04510c472a 100644 --- a/spec/features/posting_spec.rb +++ b/spec/features/posting_spec.rb @@ -1,5 +1,5 @@ -feature "clicking 'Peep' and entering text" do - scenario "should post your peep on the index page" do +feature "posting" do + scenario "peeps are visible on the index page after posting" do sign_up_user post_a_peep expect(page).to have_content('I feel grrrrrreat') diff --git a/spec/features/sign_up_spec.rb b/spec/features/sign_up_spec.rb deleted file mode 100644 index 28d4ccb68f..0000000000 --- a/spec/features/sign_up_spec.rb +++ /dev/null @@ -1,26 +0,0 @@ -feature "clicking 'Sign Up'" do - scenario "should take you to a sign up page" do - visit '/' - click_button 'Sign up' - expect(page).to have_field('email') - expect(page).to have_field('password') - expect(page).to have_field('name') - expect(page).to have_field('username') - end -end - -feature "using a non-unique email" do - scenario "should return you to the sign up page with a prompt" do - sign_up_user - sign_up_same_email - expect(page).to have_content('Email in use') - end -end - -feature "using a non-unique username" do - scenario "should return you to the sign up page with a prompt" do - sign_up_user - sign_up_same_username - expect(page).to have_content('Username in use') - end -end diff --git a/spec/features/signing_up_spec.rb b/spec/features/signing_up_spec.rb new file mode 100644 index 0000000000..3d9f3c7bb9 --- /dev/null +++ b/spec/features/signing_up_spec.rb @@ -0,0 +1,13 @@ +feature "signing up" do + scenario "returns you to the sign up page if email is not unique" do + sign_up_user + sign_up_same_email + expect(page).to have_content('Email in use') + end + + scenario "returns you to the sign up page if username is not unique" do + sign_up_user + sign_up_same_username + expect(page).to have_content('Username in use') + end +end diff --git a/spec/features/index_spec.rb b/spec/features/viewing_index_spec.rb similarity index 65% rename from spec/features/index_spec.rb rename to spec/features/viewing_index_spec.rb index e2128cf166..3f5b293a20 100644 --- a/spec/features/index_spec.rb +++ b/spec/features/viewing_index_spec.rb @@ -1,10 +1,10 @@ feature "index" do - scenario 'should not have Post button if not signed up' do - visit '/' + scenario 'post button should not appear if not signed up' do + visit '/peeps' expect(page).not_to have_selector(:link_or_button, 'Post') end - scenario 'should contain multiple peeps' do + scenario 'page should have multiple peeps listed' do sign_up_user post_a_peep post_another_peep @@ -12,7 +12,7 @@ expect(page).to have_content('I really do') end - scenario 'should show name and user handle of poster after signing up' do + scenario 'page should show name and user handle with peeps' do sign_up_user post_a_peep expect(page).to have_content('test user') diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb index d3c2f5a269..d18571f2bc 100644 --- a/spec/peep_spec.rb +++ b/spec/peep_spec.rb @@ -24,7 +24,7 @@ end end - describe '#get_user' do + describe '#user_info' do it 'should return the name and username of the peep poster' do peep = Peep.post(text: 'I feel grrrrrreat', userid: userid) @@ -32,7 +32,7 @@ VALUES('#{userid}', 'a@a.com', '123', 'Laurence', 'L123');" DatabaseConnection.query(sql) - hash = peep.get_user(userid) + hash = peep.user_info expect(hash['name']).to eq('Laurence') expect(hash['username']).to eq('L123') end diff --git a/spec/web_helpers.rb b/spec/web_helpers.rb index 484c571670..574538289c 100644 --- a/spec/web_helpers.rb +++ b/spec/web_helpers.rb @@ -1,19 +1,19 @@ def post_a_peep - visit '/' + visit '/peeps' click_button('Post') fill_in('text', with: 'I feel grrrrrreat') click_button('Peep') end def post_another_peep - visit '/' + visit '/peeps' click_button('Post') fill_in('text', with: 'I really do') click_button('Peep') end def sign_up_user - visit '/' + visit '/peeps' click_button 'Sign up' fill_in('email', with: 'test@test.com') fill_in('password', with: 'password123') @@ -23,7 +23,7 @@ def sign_up_user end def sign_up_same_email - visit '/' + visit '/peeps' click_button 'Sign up' fill_in('email', with: 'test@test.com') fill_in('password', with: 'password123') @@ -33,7 +33,7 @@ def sign_up_same_email end def sign_up_same_username - visit '/' + visit '/peeps' click_button 'Sign up' fill_in('email', with: 'unique@unique.com') fill_in('password', with: 'password123') diff --git a/views/index.erb b/views/index.erb index 3a5dcabb4f..5b3448675b 100644 --- a/views/index.erb +++ b/views/index.erb @@ -3,14 +3,16 @@ <% @peeps.each do |peep| %> +

- <% user = peep.get_user(peep.userid) %> + <% user = peep.user_info %> <%= user['name'] %> @<%= user['username'] %>
<%= peep.text %>
<%= peep.time %>
+
<% end %>
<% if @signed_up %> diff --git a/views/post.erb b/views/post.erb index 3615b773f9..81b9d9f5cf 100644 --- a/views/post.erb +++ b/views/post.erb @@ -1,4 +1,6 @@
- +
diff --git a/views/signup.erb b/views/signup.erb index 3a66160778..a2b4c273f7 100644 --- a/views/signup.erb +++ b/views/signup.erb @@ -1,13 +1,21 @@

Sign up

- +
- +
- +
- +
diff --git a/views/signup_fail.erb b/views/signup_fail.erb index 42c9432b17..7e5488989d 100644 --- a/views/signup_fail.erb +++ b/views/signup_fail.erb @@ -1,15 +1,23 @@

Sign up

-

<%= @fail %>

+

<%= @fail %>

- +
- +
- +
- +
From 4d63ea370ba1406bfe0f0c835d731c051862b42e Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 19:06:25 +0100 Subject: [PATCH 16/28] Added welcome message to homepage after signing up --- app.rb | 2 ++ spec/features/logging_in_spec.rb | 2 ++ spec/features/signing_up_spec.rb | 5 +++++ views/index.erb | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 spec/features/logging_in_spec.rb diff --git a/app.rb b/app.rb index 8b0d7f287e..ce4e93fe9b 100644 --- a/app.rb +++ b/app.rb @@ -9,6 +9,7 @@ class Chitter < Sinatra::Base get '/peeps' do @peeps = Peep.all @signed_up = !session[:userid].nil? + @name = session[:name] erb(:index) end @@ -36,6 +37,7 @@ class Chitter < Sinatra::Base name: params[:name], username: params[:username]) session[:userid] = user.id + session[:name] = user.name redirect '/peeps' end diff --git a/spec/features/logging_in_spec.rb b/spec/features/logging_in_spec.rb new file mode 100644 index 0000000000..81271abae9 --- /dev/null +++ b/spec/features/logging_in_spec.rb @@ -0,0 +1,2 @@ +feature "logging in" do +end diff --git a/spec/features/signing_up_spec.rb b/spec/features/signing_up_spec.rb index 3d9f3c7bb9..3ea3e2c759 100644 --- a/spec/features/signing_up_spec.rb +++ b/spec/features/signing_up_spec.rb @@ -10,4 +10,9 @@ sign_up_same_username expect(page).to have_content('Username in use') end + + scenario "takes you to the homepage with your username present" do + sign_up_user + expect(page).to have_content('Welcome, test user') + end end diff --git a/views/index.erb b/views/index.erb index 5b3448675b..4700c70ba1 100644 --- a/views/index.erb +++ b/views/index.erb @@ -1,4 +1,7 @@

Chitter

+<% if @signed_up %> +

Welcome, <%= @name %>

+<% end %>
From 5c912619e502c17a9c42cc9f952f1402f6a66a25 Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 22:02:46 +0100 Subject: [PATCH 17/28] Incorrect email on login produces a prompt --- Gemfile | 2 +- Gemfile.lock | 5 +++-- app.rb | 33 ++++++++++++++++++++++------ lib/user.rb | 12 +++++++++- spec/features/authentication_spec.rb | 21 ++++++++++++++++++ spec/features/logging_in_spec.rb | 2 -- spec/user_spec.rb | 14 ++++++++++++ views/{ => peeps}/index.erb | 13 +++++++++-- views/{ => peeps}/post.erb | 2 +- views/users/login.erb | 15 +++++++++++++ views/{ => users}/signup.erb | 2 +- views/{ => users}/signup_fail.erb | 0 12 files changed, 104 insertions(+), 17 deletions(-) create mode 100644 spec/features/authentication_spec.rb delete mode 100644 spec/features/logging_in_spec.rb rename views/{ => peeps}/index.erb (73%) rename views/{ => peeps}/post.erb (78%) create mode 100644 views/users/login.erb rename views/{ => users}/signup.erb (91%) rename views/{ => users}/signup_fail.erb (100%) diff --git a/Gemfile b/Gemfile index 13ea80e54a..a81fa13251 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ gem 'pg' gem 'rake' gem 'rubocop', '0.56.0' gem 'sinatra' -gem 'timecop' +gem 'sinatra-flash' group :test do gem 'capybara' diff --git a/Gemfile.lock b/Gemfile.lock index 9811636505..42565913c8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -71,8 +71,9 @@ GEM rack (~> 2.0) rack-protection (= 2.0.5) tilt (~> 2.0) + sinatra-flash (0.3.0) + sinatra (>= 1.0.0) tilt (2.0.9) - timecop (0.9.1) unicode-display_width (1.3.2) xpath (3.2.0) nokogiri (~> 1.8) @@ -89,7 +90,7 @@ DEPENDENCIES simplecov simplecov-console sinatra - timecop + sinatra-flash RUBY VERSION ruby 2.5.0p0 diff --git a/app.rb b/app.rb index ce4e93fe9b..d5e114db52 100644 --- a/app.rb +++ b/app.rb @@ -1,32 +1,34 @@ require 'sinatra/base' +require 'sinatra/flash' require_relative './lib/peep.rb' require_relative './lib/user.rb' require_relative './lib/database_connection_setup.rb' class Chitter < Sinatra::Base enable :sessions + register Sinatra::Flash get '/peeps' do @peeps = Peep.all - @signed_up = !session[:userid].nil? + @logged_in = !session[:userid].nil? @name = session[:name] - erb(:index) + erb(:'peeps/index') end get '/peeps/post' do - erb(:post) + erb(:'peeps/post') end - post '/peeps/post' do + post '/peeps' do Peep.post(text: params[:text], userid: session[:userid]) redirect '/peeps' end get '/users/signup' do - erb(:signup) + erb(:'users/signup') end - post '/users/signup' do + post '/users' do session[:unique_email] = User.unique_email?(params[:email]) unless session[:unique_email] && User.unique_username?(params[:username]) @@ -44,7 +46,24 @@ class Chitter < Sinatra::Base get '/users/signup/fail' do session[:unique_email] ? @fail = 'Username in use' : @fail = 'Email in use' - erb(:signup_fail) + erb(:'users/signup_fail') + end + + get '/login/new' do + erb(:'users/login') + end + + post '/login' do + user = User.authenticate(email: params[:email], password: params[:password]) + + if user + session[:userid] = user.id + session[:name] = user.name + redirect '/peeps' + else + flash[:notice] = 'Your email or password is incorrect' + redirect '/login/new' + end end run! if app_file == $0 diff --git a/lib/user.rb b/lib/user.rb index 98b0dc8154..1fa074c5a0 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -14,7 +14,7 @@ def initialize(id:, email:, password:, name:, username:) def self.sign_up(email:, password:, name:, username:) sql = "INSERT INTO users (email, password, name, username) VALUES('#{email}', '#{password}', '#{name}', '#{username}') - RETURNING id, email, password, name, username;" + RETURNING *;" user = DatabaseConnection.query(sql).first @@ -33,4 +33,14 @@ def self.unique_username?(username) result = DatabaseConnection.query(sql) result.count.zero? end + + def self.authenticate(email:, password:) + sql = "SELECT * FROM users WHERE email = '#{email}';" + result = DatabaseConnection.query(sql).first + return if result.nil? + + User.new(id: result['id'], email: result['email'], + password: result['password'], name: result['name'], + username: result['username']) + end end diff --git a/spec/features/authentication_spec.rb b/spec/features/authentication_spec.rb new file mode 100644 index 0000000000..9d277c974a --- /dev/null +++ b/spec/features/authentication_spec.rb @@ -0,0 +1,21 @@ +feature 'authentication' do + scenario 'users can sign in' do + User.sign_up(email: 'a@a.com', password: '123', name: 'test user', + username: 'test_user') + + visit '/peeps' + click_button('Log in') + fill_in('email', with: 'a@a.com') + fill_in('password', with: '123') + click_button('Sign in') + expect(page).to have_content('Welcome, test user') + end + + scenario 'users see an error if their email is incorrect' do + visit '/login/new' + fill_in('email', with: 'a@a.com') + fill_in('password', with: '123') + click_button('Sign in') + expect(page).to have_content('Your email or password is incorrect') + end +end diff --git a/spec/features/logging_in_spec.rb b/spec/features/logging_in_spec.rb deleted file mode 100644 index 81271abae9..0000000000 --- a/spec/features/logging_in_spec.rb +++ /dev/null @@ -1,2 +0,0 @@ -feature "logging in" do -end diff --git a/spec/user_spec.rb b/spec/user_spec.rb index bbe1e6074f..510a008422 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -48,4 +48,18 @@ expect(User.unique_username?('test_user')).to eq(false) end end + + describe '#authenticate' do + it 'should return a user if passed correct login details' do + user = user_signup + authenticated_user = User.authenticate(email: 'test@test.com', + password: 'password123') + + expect(user.id).to eq(authenticated_user.id) + end + + it 'should return nil if email is incorrect' do + expect(User.authenticate(email: 'a@a.com', password: '123')).to be_nil + end + end end diff --git a/views/index.erb b/views/peeps/index.erb similarity index 73% rename from views/index.erb rename to views/peeps/index.erb index 4700c70ba1..ac79beae5f 100644 --- a/views/index.erb +++ b/views/peeps/index.erb @@ -1,10 +1,18 @@

Chitter

-<% if @signed_up %> +<% if @logged_in %>

Welcome, <%= @name %>

<% end %> + +<% if !@logged_in %> +
+ +
+<% end %> +
+ <% @peeps.each do |peep| %>

@@ -18,7 +26,8 @@
<% end %>
-<% if @signed_up %> + +<% if @logged_in %>
diff --git a/views/post.erb b/views/peeps/post.erb similarity index 78% rename from views/post.erb rename to views/peeps/post.erb index 81b9d9f5cf..5aec161421 100644 --- a/views/post.erb +++ b/views/peeps/post.erb @@ -1,4 +1,4 @@ -
+ diff --git a/views/users/login.erb b/views/users/login.erb new file mode 100644 index 0000000000..0ea6564d23 --- /dev/null +++ b/views/users/login.erb @@ -0,0 +1,15 @@ +

+ <%= flash[:notice] %> +

+ + + + + +
diff --git a/views/signup.erb b/views/users/signup.erb similarity index 91% rename from views/signup.erb rename to views/users/signup.erb index a2b4c273f7..07d6581fc2 100644 --- a/views/signup.erb +++ b/views/users/signup.erb @@ -1,6 +1,6 @@

Sign up

-
+ diff --git a/views/signup_fail.erb b/views/users/signup_fail.erb similarity index 100% rename from views/signup_fail.erb rename to views/users/signup_fail.erb From 159948053dd55634c02e7de21b139fbeb8cb1fba Mon Sep 17 00:00:00 2001 From: Laurence Date: Mon, 27 May 2019 22:27:42 +0100 Subject: [PATCH 18/28] Completed login functionality --- app.rb | 15 ++++++--------- lib/user.rb | 2 +- spec/features/authentication_spec.rb | 13 ++++++++++++- spec/user_spec.rb | 5 +++++ views/users/signup.erb | 2 ++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/app.rb b/app.rb index d5e114db52..80c3cd13bf 100644 --- a/app.rb +++ b/app.rb @@ -29,10 +29,12 @@ class Chitter < Sinatra::Base end post '/users' do - session[:unique_email] = User.unique_email?(params[:email]) - - unless session[:unique_email] && User.unique_username?(params[:username]) - redirect '/users/signup/fail' + if !User.unique_email?(params[:email]) + flash[:notice] = 'Email in use' + redirect '/users/signup' + elsif !User.unique_username?(params[:username]) + flash[:notice] = 'Username in use' + redirect '/users/signup' end user = User.sign_up(email: params[:email], password: params[:password], @@ -44,11 +46,6 @@ class Chitter < Sinatra::Base redirect '/peeps' end - get '/users/signup/fail' do - session[:unique_email] ? @fail = 'Username in use' : @fail = 'Email in use' - erb(:'users/signup_fail') - end - get '/login/new' do erb(:'users/login') end diff --git a/lib/user.rb b/lib/user.rb index 1fa074c5a0..368613582e 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -37,7 +37,7 @@ def self.unique_username?(username) def self.authenticate(email:, password:) sql = "SELECT * FROM users WHERE email = '#{email}';" result = DatabaseConnection.query(sql).first - return if result.nil? + return if (result.nil? || password != result['password']) User.new(id: result['id'], email: result['email'], password: result['password'], name: result['name'], diff --git a/spec/features/authentication_spec.rb b/spec/features/authentication_spec.rb index 9d277c974a..a69ed658ec 100644 --- a/spec/features/authentication_spec.rb +++ b/spec/features/authentication_spec.rb @@ -11,11 +11,22 @@ expect(page).to have_content('Welcome, test user') end - scenario 'users see an error if their email is incorrect' do + scenario 'users see a prompt if their email is incorrect' do visit '/login/new' fill_in('email', with: 'a@a.com') fill_in('password', with: '123') click_button('Sign in') expect(page).to have_content('Your email or password is incorrect') end + + scenario 'users see a prompt if their password if incorrect' do + User.sign_up(email: 'a@a.com', password: '123', name: 'test user', + username: 'test_user') + + visit '/login/new' + fill_in('email', with: 'a@a.com') + fill_in('password', with: '1234') + click_button('Sign in') + expect(page).to have_content('Your email or password is incorrect') + end end diff --git a/spec/user_spec.rb b/spec/user_spec.rb index 510a008422..2d79707f86 100644 --- a/spec/user_spec.rb +++ b/spec/user_spec.rb @@ -61,5 +61,10 @@ it 'should return nil if email is incorrect' do expect(User.authenticate(email: 'a@a.com', password: '123')).to be_nil end + + it 'should return nil if password is incorrect' do + user_signup + expect(User.authenticate(email: 'test@test.com', password: '1')).to be_nil + end end end diff --git a/views/users/signup.erb b/views/users/signup.erb index 07d6581fc2..eee9b9f008 100644 --- a/views/users/signup.erb +++ b/views/users/signup.erb @@ -1,5 +1,7 @@

Sign up

+

<%= flash[:notice] %>

+