From c87132a3b7e7ef426da92c6ea017d38ec0318286 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 12:42:40 +0100 Subject: [PATCH 01/56] setup --- Gemfile | 2 ++ Gemfile.lock | 4 +++- app.rb | 15 +++++++++++++++ lib/database_connection.rb | 28 ++++++++++++++++++++++++++++ spec/seeds.sql | 0 spec/spec_helper.rb | 6 ++++++ 6 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 app.rb create mode 100644 lib/database_connection.rb create mode 100644 spec/seeds.sql diff --git a/Gemfile b/Gemfile index b1a320395a..ff34d824e1 100644 --- a/Gemfile +++ b/Gemfile @@ -11,3 +11,5 @@ end group :development, :test do gem 'rubocop', '1.20' end + +gem "pg", "~> 1.4" diff --git a/Gemfile.lock b/Gemfile.lock index 66064703c7..4e481984bc 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,6 +8,7 @@ GEM parallel (1.20.1) parser (3.0.2.0) ast (~> 2.4.1) + pg (1.4.6) rainbow (3.0.0) regexp_parser (2.1.1) rexml (3.2.5) @@ -54,6 +55,7 @@ PLATFORMS ruby DEPENDENCIES + pg (~> 1.4) rspec rubocop (= 1.20) simplecov @@ -63,4 +65,4 @@ RUBY VERSION ruby 3.0.2p107 BUNDLED WITH - 2.2.26 + 2.4.10 diff --git a/app.rb b/app.rb new file mode 100644 index 0000000000..a806c781b7 --- /dev/null +++ b/app.rb @@ -0,0 +1,15 @@ +# file: app.rb + +require_relative 'lib/database_connection' + +# We need to give the database name to the method `connect`. +DatabaseConnection.connect('music_library') + +# Perform a SQL query on the database and get the result set. +sql = 'SELECT id, title FROM albums;' +result = DatabaseConnection.exec_params(sql, []) + +# Print out each record from the result set . +result.each do |record| + p record +end \ No newline at end of file diff --git a/lib/database_connection.rb b/lib/database_connection.rb new file mode 100644 index 0000000000..c8f1ad1d46 --- /dev/null +++ b/lib/database_connection.rb @@ -0,0 +1,28 @@ +# file: lib/database_connection.rb + +require 'pg' + +# This class is a thin "wrapper" around the +# PG library. We'll use it in our project to interact +# with the database using SQL. + +class DatabaseConnection + # This method connects to PostgreSQL using the + # PG gem. We connect to 127.0.0.1, and select + # the database name given in argument. + def self.connect(database_name) + @connection = PG.connect({ host: '127.0.0.1', dbname: database_name }) + end + + # This method executes an SQL query + # on the database, providing some optional parameters + # (you will learn a bit later about when to provide these parameters). + def self.exec_params(query, params) + if @connection.nil? + raise 'DatabaseConnection.exec_params: Cannot run a SQL query as the connection to'\ + 'the database was never opened. Did you make sure to call first the method '\ + '`DatabaseConnection.connect` in your app.rb file (or in your tests spec_helper.rb)?' + end + @connection.exec_params(query, params) + end +end \ No newline at end of file diff --git a/spec/seeds.sql b/spec/seeds.sql new file mode 100644 index 0000000000..e69de29bb2 diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 252747d899..f82884e617 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,6 +1,12 @@ +# file: spec/spec_helper.rb +require 'database_connection' require 'simplecov' require 'simplecov-console' +# Make sure this connects to your test database +# (its name should end with '_test') +DatabaseConnection.connect('your_database_name_test') + SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::Console, # Want a nice code coverage website? Uncomment this next line! From ce566f2601251ff421f201cb49b02e0acc4a9519 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 15:14:05 +0100 Subject: [PATCH 02/56] seeds creation --- recipes/database_table_recipe.md | 125 ++++++++++++++++++ recipes/model_repo_class_recipe.md | 199 +++++++++++++++++++++++++++++ spec/seeds.sql | 15 +++ spec/spec_helper.rb | 2 +- 4 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 recipes/database_table_recipe.md create mode 100644 recipes/model_repo_class_recipe.md diff --git a/recipes/database_table_recipe.md b/recipes/database_table_recipe.md new file mode 100644 index 0000000000..f0b9fb5e1b --- /dev/null +++ b/recipes/database_table_recipe.md @@ -0,0 +1,125 @@ +## 1. Extract nouns from the user stories or specification + +``` +STRAIGHT UP + +As a Maker +So that I can let people know what I am doing +I want to post a message (peep) to chitter + +As a maker +So that I can see what others are saying +I want to see all peeps in reverse chronological order + +As a Maker +So that I can better appreciate the context of a peep +I want to see the time at which it was made + +As a Maker +So that I can post messages on Chitter as me +I want to sign up for Chitter + +HARDER + +As a Maker +So that only I can post messages on Chitter as me +I want to log in to Chitter + +As a Maker +So that I can avoid others posting messages on Chitter as me +I want to log out of Chitter +``` + +``` +Nouns: + +peep, time +maker +``` + +## 2. Infer the Table Name and Columns + +Put the different nouns in this table. Replace the example with your own nouns. + +| Record | Properties | +| --------------------- | ------------------ | +| users | email_address, username, password +| peeps | time, contents, user_id + +1. Name of the first table (always plural): `users` + + Column names: `email_address`, `username`, `password` + +2. Name of the second table (always plural): `peeps` + + Column names: `time`, `contents`, `user_id` + +## 3. Decide the column types. + +[Here's a full documentation of PostgreSQL data types](https://www.postgresql.org/docs/current/datatype.html). + +Most of the time, you'll need either `text`, `int`, `bigint`, `numeric`, or `boolean`. If you're in doubt, do some research or ask your peers. + +Remember to **always** have the primary key `id` as a first column. Its type will always be `SERIAL`. + +``` +# EXAMPLE: + +Table: users +id: SERIAL +email_address: varchar +username: varchar +password: varchar + +Table: peeps +id: SERIAL +time: DATETIME +contents: text +user_id: user_id +``` + +## 4. Decide on The Tables Relationship +``` + +1. Can one user have many posts? YES +2. Can one post have many users? NO + +-> Therefore, +-> An user HAS MANY posts +-> An post BELONGS TO an user + +-> Therefore, the foreign key is on the peeps table. +``` + +## 4. Write the SQL. + +```sql +-- EXAMPLE +-- file: chitter_table.sql + +CREATE TABLE users ( + id SERIAL PRIMARY KEY, + email_address varchar(320), + username varchar(50) NOT NULL, + password varchar(60) NOT NULL); + +-- Then the table with the foreign key first. +CREATE TABLE peeps ( + id SERIAL PRIMARY KEY, + time TIMESTAMP, + contents text, +-- The foreign key name is always {other_table_singular}_id + user_id int, + constraint fk_user foreign key(user_id) + references users(id) + on delete cascade +); +``` + +## 5. Create the tables. + +```bash +psql -h 127.0.0.1 chitter_database < chitter_table.sql +``` + + diff --git a/recipes/model_repo_class_recipe.md b/recipes/model_repo_class_recipe.md new file mode 100644 index 0000000000..915a7c8ceb --- /dev/null +++ b/recipes/model_repo_class_recipe.md @@ -0,0 +1,199 @@ +# {{chitter_database}} Model and Repository Classes Design Recipe + +## 2. Create Test SQL seeds + +Your tests will depend on data stored in PostgreSQL to run. + +If seed data is provided (or you already created it), you can skip this step. + +```sql +-- EXAMPLE +-- (file: spec/seeds_.sql) + +TRUNCATE TABLE peeps, users RESTART IDENTITY; + +-- Encrypt passwords using bcrypt +INSERT INTO users (email_address, username, password) +VALUES ('sidra@fake.com', 'sidra_fake', crypt('12345', gen_salt('bf'))); +INSERT INTO users (email_address, username, password) +VALUES ('bobby@fake.com', 'bobby_fake', crypt('password', gen_salt('bf'))); +INSERT INTO users (email_address, username, password) +VALUES ('tina@fake.com', 'tina_fake', crypt('password123', gen_salt('bf'))); + +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-12-04 12:03:00', 'This is my post, 1'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-13-04 13:03:00', 'Here is my new post, 2'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-14-04 13:03:00', 'Here is my other post, 1'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-15-04 13:03:00', 'User 3 newer post, 3'); + +``` + +```bash +psql -h 127.0.0.1 your_database_name < seeds_{table_name}.sql +``` + +## 3. Define the class names + +Usually, the Model class name will be the capitalised table name (single instead of plural). The same name is then suffixed by `Repository` for the Repository class name. + +```ruby +# EXAMPLE +# Table name: students + +# Model class +# (in lib/student.rb) +class Student +end + +# Repository class +# (in lib/student_repository.rb) +class StudentRepository +end +``` + +## 4. Implement the Model class + +Define the attributes of your Model class. You can usually map the table columns to the attributes of the class, including primary and foreign keys. + +```ruby +# EXAMPLE +# Table name: students + +# Model class +# (in lib/student.rb) + +class Student + + # Replace the attributes by your own columns. + attr_accessor :id, :name, :cohort_name +end + +# The keyword attr_accessor is a special Ruby feature +# which allows us to set and get attributes on an object, +# here's an example: +# +# student = Student.new +# student.name = 'Jo' +# student.name +``` + +*You may choose to test-drive this class, but unless it contains any more logic than the example above, it is probably not needed.* + +## 5. Define the Repository Class interface + +Your Repository class will need to implement methods for each "read" or "write" operation you'd like to run against the database. + +Using comments, define the method signatures (arguments and return value) and what they do - write up the SQL queries that will be used by each method. + +```ruby +# EXAMPLE +# Table name: students + +# Repository class +# (in lib/student_repository.rb) + +class StudentRepository + + # Selecting all records + # No arguments + def all + # Executes the SQL query: + # SELECT id, name, cohort_name FROM students; + + # Returns an array of Student objects. + end + + # Gets a single record by its ID + # One argument: the id (number) + def find(id) + # Executes the SQL query: + # SELECT id, name, cohort_name FROM students WHERE id = $1; + + # Returns a single Student object. + end + + # Add more methods below for each operation you'd like to implement. + + # def create(student) + # end + + # def update(student) + # end + + # def delete(student) + # end +end +``` + +## 6. Write Test Examples + +Write Ruby code that defines the expected behaviour of the Repository class, following your design from the table written in step 5. + +These examples will later be encoded as RSpec tests. + +```ruby +# EXAMPLES + +# 1 +# Get all students + +repo = StudentRepository.new + +students = repo.all + +students.length # => 2 + +students[0].id # => 1 +students[0].name # => 'David' +students[0].cohort_name # => 'April 2022' + +students[1].id # => 2 +students[1].name # => 'Anna' +students[1].cohort_name # => 'May 2022' + +# 2 +# Get a single student + +repo = StudentRepository.new + +student = repo.find(1) + +student.id # => 1 +student.name # => 'David' +student.cohort_name # => 'April 2022' + +# Add more examples for each method +``` + +Encode this example as a test. + +## 7. Reload the SQL seeds before each test run + +Running the SQL code present in the seed file will empty the table and re-insert the seed data. + +This is so you get a fresh table contents every time you run the test suite. + +```ruby +# EXAMPLE + +# file: spec/student_repository_spec.rb + +def reset_students_table + seed_sql = File.read('spec/seeds_students.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'students' }) + connection.exec(seed_sql) +end + +describe StudentRepository do + before(:each) do + reset_students_table + end + + # (your tests will go here). +end +``` + +## 8. Test-drive and implement the Repository class behaviour + +_After each test you write, follow the test-driving process of red, green, refactor to implement the behaviour._ + + diff --git a/spec/seeds.sql b/spec/seeds.sql index e69de29bb2..6f55387ba1 100644 --- a/spec/seeds.sql +++ b/spec/seeds.sql @@ -0,0 +1,15 @@ +TRUNCATE TABLE peeps, users RESTART IDENTITY; + +-- Encrypt passwords using bcrypt +INSERT INTO users (email_address, username, password) +VALUES ('sidra@fake.com', 'sidra_fake', crypt('12345', gen_salt('bf'))); +INSERT INTO users (email_address, username, password) +VALUES ('bobby@fake.com', 'bobby_fake', crypt('password', gen_salt('bf'))); +INSERT INTO users (email_address, username, password) +VALUES ('tina@fake.com', 'tina_fake', crypt('password123', gen_salt('bf'))); + +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-12 12:03:00', 'This is my post', '1'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-13 12:16:00', 'Here is my new post', '2'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-14 12:19:00', 'Here is my other post', '1'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-15 12:10:00', 'User 3 newer post', '3'); + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index f82884e617..b96346c3bc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -5,7 +5,7 @@ # Make sure this connects to your test database # (its name should end with '_test') -DatabaseConnection.connect('your_database_name_test') +DatabaseConnection.connect('chitter_database_test') SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ SimpleCov::Formatter::Console, From 623bf1b1debf175efccc126412405cd58cfbad6c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 16:08:20 +0100 Subject: [PATCH 03/56] add user repo test --- app.rb | 2 +- lib/database_connection.rb | 2 +- lib/user.rb | 3 + lib/user_repository.rb | 29 ++++++ recipes/model_repo_class_recipe.md | 148 ++++++++--------------------- spec/user_repository_spec.rb | 20 ++++ 6 files changed, 94 insertions(+), 110 deletions(-) create mode 100644 lib/user.rb create mode 100644 lib/user_repository.rb create mode 100644 spec/user_repository_spec.rb diff --git a/app.rb b/app.rb index a806c781b7..a692a8f529 100644 --- a/app.rb +++ b/app.rb @@ -12,4 +12,4 @@ # Print out each record from the result set . result.each do |record| p record -end \ No newline at end of file +end diff --git a/lib/database_connection.rb b/lib/database_connection.rb index c8f1ad1d46..f4bde0ff72 100644 --- a/lib/database_connection.rb +++ b/lib/database_connection.rb @@ -25,4 +25,4 @@ def self.exec_params(query, params) end @connection.exec_params(query, params) end -end \ No newline at end of file +end diff --git a/lib/user.rb b/lib/user.rb new file mode 100644 index 0000000000..8e554538c1 --- /dev/null +++ b/lib/user.rb @@ -0,0 +1,3 @@ +class User + attr_accessor :id, :email_address, :user_name, :password +end diff --git a/lib/user_repository.rb b/lib/user_repository.rb new file mode 100644 index 0000000000..20668fe4ec --- /dev/null +++ b/lib/user_repository.rb @@ -0,0 +1,29 @@ +require_relative './user' + +class UserRepository + def all + + end + + def create(new_user) + # encrypted_password = BCrypt::Password.create(new_user.password) + + # sql = ' + # INSERT INTO users (email_address, user_name, password) + # VALUES($1, $2, $3); + # ' + # sql_params = [ + # new_user.email_address, + # new_user.user_name + # encrypted_password + # ] + + # result_set = DatabaseConnection.exec_params(sql, sql_params) + + # return new_user + end + + def find_by_email(email) + end + +end diff --git a/recipes/model_repo_class_recipe.md b/recipes/model_repo_class_recipe.md index 915a7c8ceb..4a3815065a 100644 --- a/recipes/model_repo_class_recipe.md +++ b/recipes/model_repo_class_recipe.md @@ -2,12 +2,7 @@ ## 2. Create Test SQL seeds -Your tests will depend on data stored in PostgreSQL to run. - -If seed data is provided (or you already created it), you can skip this step. - ```sql --- EXAMPLE -- (file: spec/seeds_.sql) TRUNCATE TABLE peeps, users RESTART IDENTITY; @@ -26,142 +21,85 @@ INSERT INTO peeps (time, contents, user_id) VALUES ('2023-14-04 13:03:00', 'Here INSERT INTO peeps (time, contents, user_id) VALUES ('2023-15-04 13:03:00', 'User 3 newer post, 3'); ``` - ```bash psql -h 127.0.0.1 your_database_name < seeds_{table_name}.sql ``` -## 3. Define the class names - -Usually, the Model class name will be the capitalised table name (single instead of plural). The same name is then suffixed by `Repository` for the Repository class name. - -```ruby -# EXAMPLE -# Table name: students - -# Model class -# (in lib/student.rb) -class Student -end - -# Repository class -# (in lib/student_repository.rb) -class StudentRepository -end -``` - ## 4. Implement the Model class -Define the attributes of your Model class. You can usually map the table columns to the attributes of the class, including primary and foreign keys. - ```ruby -# EXAMPLE -# Table name: students +# Table name: user # Model class -# (in lib/student.rb) - -class Student +# (in lib/user.rb) - # Replace the attributes by your own columns. - attr_accessor :id, :name, :cohort_name +class User + attr_accessor :id, :email_address, :user_name, :password end - -# The keyword attr_accessor is a special Ruby feature -# which allows us to set and get attributes on an object, -# here's an example: -# -# student = Student.new -# student.name = 'Jo' -# student.name ``` -*You may choose to test-drive this class, but unless it contains any more logic than the example above, it is probably not needed.* - ## 5. Define the Repository Class interface - -Your Repository class will need to implement methods for each "read" or "write" operation you'd like to run against the database. - -Using comments, define the method signatures (arguments and return value) and what they do - write up the SQL queries that will be used by each method. - ```ruby -# EXAMPLE -# Table name: students +# Table name: users # Repository class -# (in lib/student_repository.rb) +# (in lib/user_repository.rb) -class StudentRepository +class UserRepository - # Selecting all records - # No arguments - def all - # Executes the SQL query: - # SELECT id, name, cohort_name FROM students; + def create(new_user) + encrypted_password = BCrypt::Password.create(new_user.password) - # Returns an array of Student objects. - end + sql = ' + INSERT INTO users (email_address, user_name, password) + VALUES($1, $2, $3); + ' + sql_params = [ + new_user.email_address, + new_user.user_name + encrypted_password + ] - # Gets a single record by its ID - # One argument: the id (number) - def find(id) - # Executes the SQL query: - # SELECT id, name, cohort_name FROM students WHERE id = $1; + result_set = DatabaseConnection.exec_params(sql, sql_params) - # Returns a single Student object. + return new_user end - # Add more methods below for each operation you'd like to implement. - - # def create(student) - # end - - # def update(student) - # end + def find_by_email(email) + sql = 'SELECT id, email_address, user_name, password FROM users WHERE email_address = $1;' + result_set = DatabaseConnection.exec_params(sql, [email_address]) + end - # def delete(student) - # end + def create(student) + end end ``` ## 6. Write Test Examples -Write Ruby code that defines the expected behaviour of the Repository class, following your design from the table written in step 5. - -These examples will later be encoded as RSpec tests. - ```ruby # EXAMPLES -# 1 -# Get all students - -repo = StudentRepository.new - -students = repo.all - -students.length # => 2 +# 1 - Shows all users -students[0].id # => 1 -students[0].name # => 'David' -students[0].cohort_name # => 'April 2022' +repo = UserRepository.new +users = repo.all +expect(users.length).to eq(3) +expect(users.first.user_name).to eq('sidra_fake') -students[1].id # => 2 -students[1].name # => 'Anna' -students[1].cohort_name # => 'May 2022' +# 3 - Create a new user -# 2 -# Get a single student +repo = UserRepository.new -repo = StudentRepository.new +new_user = User.new +new_user.email_address = 'angel@fake.com' +new_user.username = 'angel_fake' +new_user.password = 'password123' # set the plaintext password -student = repo.find(1) +encrypted_password = BCrypt::Password.create(new_user.password) +new_user.password = encrypted_password # set the encrypted password -student.id # => 1 -student.name # => 'David' -student.cohort_name # => 'April 2022' - -# Add more examples for each method +repo.create(new_user) ``` Encode this example as a test. @@ -173,8 +111,6 @@ Running the SQL code present in the seed file will empty the table and re-insert This is so you get a fresh table contents every time you run the test suite. ```ruby -# EXAMPLE - # file: spec/student_repository_spec.rb def reset_students_table @@ -187,13 +123,9 @@ describe StudentRepository do before(:each) do reset_students_table end - - # (your tests will go here). end ``` ## 8. Test-drive and implement the Repository class behaviour -_After each test you write, follow the test-driving process of red, green, refactor to implement the behaviour._ - diff --git a/spec/user_repository_spec.rb b/spec/user_repository_spec.rb new file mode 100644 index 0000000000..f57dca7310 --- /dev/null +++ b/spec/user_repository_spec.rb @@ -0,0 +1,20 @@ +require 'user_repository' + +def reset_users_table + seed_sql = File.read('spec/seeds.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'chitter_database_test' }) + connection.exec(seed_sql) +end + +describe UserRepository do + before(:each) do + reset_users_table + end + + it 'shows all users' do + repo = UserRepository.new + users = repo.all + expect(users.length).to eq(3) + expect(users.first.user_name).to eq('sidra_fake') + end +end From 7a71896ee8edb910fb41aa5d62ccb23aa57ca2c8 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 16:21:26 +0100 Subject: [PATCH 04/56] all user test driven --- lib/user.rb | 2 +- lib/user_repository.rb | 40 +++++++++++++++++++++++++----------- spec/user_repository_spec.rb | 2 +- 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/lib/user.rb b/lib/user.rb index 8e554538c1..6967c2d3d7 100644 --- a/lib/user.rb +++ b/lib/user.rb @@ -1,3 +1,3 @@ class User - attr_accessor :id, :email_address, :user_name, :password + attr_accessor :id, :email_address, :username, :password end diff --git a/lib/user_repository.rb b/lib/user_repository.rb index 20668fe4ec..df0d9db936 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -2,25 +2,41 @@ class UserRepository def all + sql = 'SELECT email_address, username, password FROM users;' + result_set = DatabaseConnection.exec_params(sql, []) + users = [] + + result_set.each do |row| + user = User.new + user.id = row['id'] + user.email_address = row['email_address'] + user.username = row['username'] + user.password = row['password'] + users << user + end + return users end def create(new_user) - # encrypted_password = BCrypt::Password.create(new_user.password) + # encrypted_password = BCrypt::Password.create(new_user.password) + + # sql = 'INSERT INTO users (email_address, username, password) + # VALUES($1, $2, $3);' + # sql_params = [ + # new_user.email_address, + # new_user.user_name + # encrypted_password + # ] - # sql = ' - # INSERT INTO users (email_address, user_name, password) - # VALUES($1, $2, $3); - # ' - # sql_params = [ - # new_user.email_address, - # new_user.user_name - # encrypted_password - # ] + # result_set = DatabaseConnection.exec_params(sql, sql_params) - # result_set = DatabaseConnection.exec_params(sql, sql_params) + # new_user = User.new + # new_user.email_address = email_address + # new_user.user_name = user_name + # new_user.password = password - # return new_user + # return new_user end def find_by_email(email) diff --git a/spec/user_repository_spec.rb b/spec/user_repository_spec.rb index f57dca7310..b38a66dead 100644 --- a/spec/user_repository_spec.rb +++ b/spec/user_repository_spec.rb @@ -15,6 +15,6 @@ def reset_users_table repo = UserRepository.new users = repo.all expect(users.length).to eq(3) - expect(users.first.user_name).to eq('sidra_fake') + expect(users.first.username).to eq('sidra_fake') end end From 159a12a51ead3144c8e6b53e9f4fbb3c1a508207 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 16:29:45 +0100 Subject: [PATCH 05/56] find method complete --- lib/user_repository.rb | 17 +++++++++++++++-- recipes/model_repo_class_recipe.md | 8 ++++++++ spec/user_repository_spec.rb | 7 +++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/lib/user_repository.rb b/lib/user_repository.rb index df0d9db936..a7fb7bf8c9 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -18,6 +18,21 @@ def all return users end + def find_by_email(email) + sql = 'SELECT email_address, username, password FROM users WHERE users.email_address = $1;' + result_set = DatabaseConnection.exec_params(sql, [email]) + user_row = result_set[0] + + user = User.new + user.id = user_row['id'] + user.email_address = user_row['email_address'] + user.username = user_row['username'] + user.password = user_row['password'] + + return user + + end + def create(new_user) # encrypted_password = BCrypt::Password.create(new_user.password) @@ -39,7 +54,5 @@ def create(new_user) # return new_user end - def find_by_email(email) - end end diff --git a/recipes/model_repo_class_recipe.md b/recipes/model_repo_class_recipe.md index 4a3815065a..1a37e31f0e 100644 --- a/recipes/model_repo_class_recipe.md +++ b/recipes/model_repo_class_recipe.md @@ -87,6 +87,12 @@ users = repo.all expect(users.length).to eq(3) expect(users.first.user_name).to eq('sidra_fake') +# 2 - Find a user by email +repo = UserRepository.new +user = repo.find('sidra@fake.com') + +expect(user.username).to eq('sidra_fake') + # 3 - Create a new user repo = UserRepository.new @@ -100,6 +106,8 @@ encrypted_password = BCrypt::Password.create(new_user.password) new_user.password = encrypted_password # set the encrypted password repo.create(new_user) + + ``` Encode this example as a test. diff --git a/spec/user_repository_spec.rb b/spec/user_repository_spec.rb index b38a66dead..cc65879e7a 100644 --- a/spec/user_repository_spec.rb +++ b/spec/user_repository_spec.rb @@ -17,4 +17,11 @@ def reset_users_table expect(users.length).to eq(3) expect(users.first.username).to eq('sidra_fake') end + + it 'finds a user based on email address' do + repo = UserRepository.new + user = repo.find_by_email('sidra@fake.com') + + expect(user.username).to eq('sidra_fake') + end end From 69b5f556ad69c8e891cc8f96adc53554d74be0a6 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 16:41:08 +0100 Subject: [PATCH 06/56] create new_user method added and tested --- lib/user_repository.rb | 28 +++++++++------------------- spec/user_repository_spec.rb | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 19 deletions(-) diff --git a/lib/user_repository.rb b/lib/user_repository.rb index a7fb7bf8c9..1a3db7e64f 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -1,4 +1,5 @@ require_relative './user' +require 'bcrypt' class UserRepository def all @@ -30,29 +31,18 @@ def find_by_email(email) user.password = user_row['password'] return user - end def create(new_user) - # encrypted_password = BCrypt::Password.create(new_user.password) - - # sql = 'INSERT INTO users (email_address, username, password) - # VALUES($1, $2, $3);' - # sql_params = [ - # new_user.email_address, - # new_user.user_name - # encrypted_password - # ] + encrypted_password = BCrypt::Password.create(new_user.password) - # result_set = DatabaseConnection.exec_params(sql, sql_params) + sql = 'INSERT INTO users (email_address, username, password) + VALUES($1, $2, $3);' + sql_params = [ + new_user.email_address, + new_user.username, + encrypted_password] - # new_user = User.new - # new_user.email_address = email_address - # new_user.user_name = user_name - # new_user.password = password - - # return new_user + return new_user end - - end diff --git a/spec/user_repository_spec.rb b/spec/user_repository_spec.rb index cc65879e7a..b244ff8f40 100644 --- a/spec/user_repository_spec.rb +++ b/spec/user_repository_spec.rb @@ -24,4 +24,18 @@ def reset_users_table expect(user.username).to eq('sidra_fake') end + + it 'creates a new user' do + repo = UserRepository.new + + new_user = User.new + new_user.email_address = 'angel@fake.com' + new_user.username = 'angel_fake' + new_user.password = 'password123' # set the plaintext password + + encrypted_password = BCrypt::Password.create(new_user.password) + new_user.password = encrypted_password # set the encrypted password + + repo.create(new_user) + end end From 861c0ffbb0c060876cc48dd30e4ccacec0c149e0 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 16:49:44 +0100 Subject: [PATCH 07/56] BCRypt on the find_by_email and all methods for password de-encryption --- lib/user_repository.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/user_repository.rb b/lib/user_repository.rb index 1a3db7e64f..77c59881fa 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -13,25 +13,25 @@ def all user.id = row['id'] user.email_address = row['email_address'] user.username = row['username'] - user.password = row['password'] + user.password = BCrypt::Password.new(row['password']) users << user end return users end def find_by_email(email) - sql = 'SELECT email_address, username, password FROM users WHERE users.email_address = $1;' + sql = 'SELECT id, email_address, username, password FROM users WHERE email_address = $1;' result_set = DatabaseConnection.exec_params(sql, [email]) user_row = result_set[0] - + user = User.new user.id = user_row['id'] user.email_address = user_row['email_address'] user.username = user_row['username'] - user.password = user_row['password'] - + user.password = BCrypt::Password.new(user_row['password']) + return user - end + end def create(new_user) encrypted_password = BCrypt::Password.create(new_user.password) From a22c5ff29b6dabc763c6541ce040da392bfddbdd Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 17:00:27 +0100 Subject: [PATCH 08/56] extra test expect for create user --- lib/user_repository.rb | 1 + spec/user_repository_spec.rb | 2 ++ 2 files changed, 3 insertions(+) diff --git a/lib/user_repository.rb b/lib/user_repository.rb index 77c59881fa..4e9bb4983a 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -42,6 +42,7 @@ def create(new_user) new_user.email_address, new_user.username, encrypted_password] + DatabaseConnection.exec_params(sql, sql_params) return new_user end diff --git a/spec/user_repository_spec.rb b/spec/user_repository_spec.rb index b244ff8f40..95aaacb533 100644 --- a/spec/user_repository_spec.rb +++ b/spec/user_repository_spec.rb @@ -37,5 +37,7 @@ def reset_users_table new_user.password = encrypted_password # set the encrypted password repo.create(new_user) + users = repo.all + expect(users.last.username).to eq('angel_fake') end end From b0cd2a961388095398ea062e1300ba462ab6a1b2 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 17:47:18 +0100 Subject: [PATCH 09/56] peep_repo all method --- lib/peep.rb | 3 + lib/peep_repository.rb | 27 +++++ lib/user_repository.rb | 2 +- recipes/peep_model_repo_class_recipe.md | 98 +++++++++++++++++++ ...d => user_model_repo_class_recipe copy.md} | 0 spec/peep_repository_spec.rb | 21 ++++ 6 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 lib/peep.rb create mode 100644 lib/peep_repository.rb create mode 100644 recipes/peep_model_repo_class_recipe.md rename recipes/{model_repo_class_recipe.md => user_model_repo_class_recipe copy.md} (100%) create mode 100644 spec/peep_repository_spec.rb diff --git a/lib/peep.rb b/lib/peep.rb new file mode 100644 index 0000000000..590b343e8f --- /dev/null +++ b/lib/peep.rb @@ -0,0 +1,3 @@ +class Peep + attr_accessor :id, :time, :contents, :user_id +end diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb new file mode 100644 index 0000000000..cd3eb2c3e3 --- /dev/null +++ b/lib/peep_repository.rb @@ -0,0 +1,27 @@ +require_relative './peep' +require 'date' + +class PeepRepository + + def all + sql = 'SELECT id, time, contents, user_id FROM peeps;' + result_set = DatabaseConnection.exec_params(sql, []) + + peeps = [] + + result_set.each do |row| + peep = Peep.new + peep.id = row['id'] + peep.time = row['time'] + peep.contents = row['contents'] + peep.user_id = row['user_id'] + peeps << peep + end + return peeps + end + + def create_peep + # relay the time of the peep + # contents of the peep + end +end diff --git a/lib/user_repository.rb b/lib/user_repository.rb index 4e9bb4983a..e739fefd06 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -42,7 +42,7 @@ def create(new_user) new_user.email_address, new_user.username, encrypted_password] - DatabaseConnection.exec_params(sql, sql_params) + DatabaseConnection.exec_params(sql, sql_params) return new_user end diff --git a/recipes/peep_model_repo_class_recipe.md b/recipes/peep_model_repo_class_recipe.md new file mode 100644 index 0000000000..e33a738058 --- /dev/null +++ b/recipes/peep_model_repo_class_recipe.md @@ -0,0 +1,98 @@ +# {{chitter_database}} Model and Repository Classes Design Recipe + +## 2. Create Test SQL seeds + +```sql +-- (file: spec/seeds_.sql) + +TRUNCATE TABLE peeps, users RESTART IDENTITY; + +-- Encrypt passwords using bcrypt +INSERT INTO users (email_address, username, password) +VALUES ('sidra@fake.com', 'sidra_fake', crypt('12345', gen_salt('bf'))); +INSERT INTO users (email_address, username, password) +VALUES ('bobby@fake.com', 'bobby_fake', crypt('password', gen_salt('bf'))); +INSERT INTO users (email_address, username, password) +VALUES ('tina@fake.com', 'tina_fake', crypt('password123', gen_salt('bf'))); + +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-12-04 12:03:00', 'This is my post, 1'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-13-04 13:03:00', 'Here is my new post, 2'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-14-04 13:03:00', 'Here is my other post, 1'); +INSERT INTO peeps (time, contents, user_id) VALUES ('2023-15-04 13:03:00', 'User 3 newer post, 3'); + +``` +```bash +psql -h 127.0.0.1 your_database_name < seeds_{table_name}.sql +``` + +## 4. Implement the Model class + +```ruby +# Table name: peeps + +# Model class +# (in lib/peep.rb) + +class Peep + attr_accessor :id, :time, :contents, :user_id +end +``` + +## 5. Define the Repository Class interface +```ruby +# Table name: peeps + +# Repository class +# (in lib/peep_repository.rb) + +require 'date' + +class PeepRepository + + def all_peeps + # order by time in SQL + end + + def create_peep + # relay the time of the peep + # contents of the peep + end +end +``` + +## 6. Write Test Examples + +```ruby + +# 1 - Shows all peeps + +repo = PeepRepository.new +peeps = repo.all +expect(peeps.length).to eq(4) +expect(users.last.contents).to eq('User 3 newer post') + +``` + +Encode this example as a test. + +## 7. Reload the SQL seeds before each test run + +```ruby +# file: spec/student_repository_spec.rb + +def reset_students_table + seed_sql = File.read('spec/seeds_students.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'students' }) + connection.exec(seed_sql) +end + +describe StudentRepository do + before(:each) do + reset_students_table + end +end +``` + +## 8. Test-drive and implement the Repository class behaviour + + diff --git a/recipes/model_repo_class_recipe.md b/recipes/user_model_repo_class_recipe copy.md similarity index 100% rename from recipes/model_repo_class_recipe.md rename to recipes/user_model_repo_class_recipe copy.md diff --git a/spec/peep_repository_spec.rb b/spec/peep_repository_spec.rb new file mode 100644 index 0000000000..de66c949fb --- /dev/null +++ b/spec/peep_repository_spec.rb @@ -0,0 +1,21 @@ +require 'peep_repository' + +def reset_users_table + seed_sql = File.read('spec/seeds.sql') + connection = PG.connect({ host: '127.0.0.1', dbname: 'chitter_database_test' }) + connection.exec(seed_sql) +end + +describe PeepRepository do + before(:each) do + reset_users_table + end + + it 'shows a list of all peeps' do + repo = PeepRepository.new + peeps = repo.all + + expect(peeps.length).to eq(4) + expect(peeps.last.contents).to eq('User 3 newer post') + end +end From eaf128f74836cadd961dbf25ec1338cad8350d9c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 17:53:10 +0100 Subject: [PATCH 10/56] create new pip rspec created --- lib/peep_repository.rb | 2 +- recipes/peep_model_repo_class_recipe.md | 1 - spec/peep_repository_spec.rb | 13 +++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index cd3eb2c3e3..38777e46e7 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -20,7 +20,7 @@ def all return peeps end - def create_peep + def create_peep(peep) # relay the time of the peep # contents of the peep end diff --git a/recipes/peep_model_repo_class_recipe.md b/recipes/peep_model_repo_class_recipe.md index e33a738058..4e282b6ad2 100644 --- a/recipes/peep_model_repo_class_recipe.md +++ b/recipes/peep_model_repo_class_recipe.md @@ -65,7 +65,6 @@ end ```ruby # 1 - Shows all peeps - repo = PeepRepository.new peeps = repo.all expect(peeps.length).to eq(4) diff --git a/spec/peep_repository_spec.rb b/spec/peep_repository_spec.rb index de66c949fb..3262783e34 100644 --- a/spec/peep_repository_spec.rb +++ b/spec/peep_repository_spec.rb @@ -18,4 +18,17 @@ def reset_users_table expect(peeps.length).to eq(4) expect(peeps.last.contents).to eq('User 3 newer post') end + + it 'creates a new peep' do + repo = PeepRepository.new + peep = Peep.new + peep.time = '2023-04-16 12:10:00' + peep.contents = 'Hello this is me!' + peep.user_id = '3' + repo.create_peep(peep) + peeps = repo.all + + expect(peeps.length).to eq(5) + expect(peeps.last.contents).to eq('Hello this is me!') + end end From bdcd5a82d83777eef7e5564d1730824151328ac2 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 17:59:19 +0100 Subject: [PATCH 11/56] peep creation --- lib/peep_repository.rb | 8 ++++++-- lib/user_repository.rb | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index 38777e46e7..2429be8a24 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -21,7 +21,11 @@ def all end def create_peep(peep) - # relay the time of the peep - # contents of the peep + sql = 'INSERT INTO peeps (time, contents, user_id) + VALUES ($1, $2, $3);' + sql_params = [peep.time, peep.contents, peep.user_id] + + result_set = DatabaseConnection.exec_params(sql, sql_params) + return nil end end diff --git a/lib/user_repository.rb b/lib/user_repository.rb index e739fefd06..1bddfb2c2f 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -44,6 +44,6 @@ def create(new_user) encrypted_password] DatabaseConnection.exec_params(sql, sql_params) - return new_user + return nil end end From 6095bef05c267143524c8220dc6a225ee29853b7 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 18:03:51 +0100 Subject: [PATCH 12/56] renamed folder for recipe --- {recipes => repo_and_db_recipes}/database_table_recipe.md | 0 {recipes => repo_and_db_recipes}/peep_model_repo_class_recipe.md | 0 .../user_model_repo_class_recipe copy.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename {recipes => repo_and_db_recipes}/database_table_recipe.md (100%) rename {recipes => repo_and_db_recipes}/peep_model_repo_class_recipe.md (100%) rename {recipes => repo_and_db_recipes}/user_model_repo_class_recipe copy.md (100%) diff --git a/recipes/database_table_recipe.md b/repo_and_db_recipes/database_table_recipe.md similarity index 100% rename from recipes/database_table_recipe.md rename to repo_and_db_recipes/database_table_recipe.md diff --git a/recipes/peep_model_repo_class_recipe.md b/repo_and_db_recipes/peep_model_repo_class_recipe.md similarity index 100% rename from recipes/peep_model_repo_class_recipe.md rename to repo_and_db_recipes/peep_model_repo_class_recipe.md diff --git a/recipes/user_model_repo_class_recipe copy.md b/repo_and_db_recipes/user_model_repo_class_recipe copy.md similarity index 100% rename from recipes/user_model_repo_class_recipe copy.md rename to repo_and_db_recipes/user_model_repo_class_recipe copy.md From 8cc1f8523f6de0c163c1caeb5de8049e911ec228 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 18:05:59 +0100 Subject: [PATCH 13/56] add comment for time.now --- lib/peep_repository.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index 2429be8a24..e61767ea61 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -25,6 +25,8 @@ def create_peep(peep) VALUES ($1, $2, $3);' sql_params = [peep.time, peep.contents, peep.user_id] + # need to input the date and time now for the time + result_set = DatabaseConnection.exec_params(sql, sql_params) return nil end From dd334b46b951ffb025b2f28d0708aa84b18f1272 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 20:50:04 +0100 Subject: [PATCH 14/56] added Time.now in create_peep --- lib/peep_repository.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index e61767ea61..87961c20eb 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -23,9 +23,8 @@ def all def create_peep(peep) sql = 'INSERT INTO peeps (time, contents, user_id) VALUES ($1, $2, $3);' - sql_params = [peep.time, peep.contents, peep.user_id] - - # need to input the date and time now for the time + time = Time.now.strftime("%d/%m/%Y %H:%M") + sql_params = [time, peep.contents, peep.user_id] result_set = DatabaseConnection.exec_params(sql, sql_params) return nil From 3c3fce0ba6341bd695eba61b95a3a3a8f2dceb1f Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Thu, 6 Apr 2023 21:01:10 +0100 Subject: [PATCH 15/56] set up Sinatra project --- Gemfile | 5 +++++ Gemfile.lock | 26 ++++++++++++++++++++++++++ app.rb | 28 ++++++++++++++-------------- config.ru | 3 +++ spec/integration/application_spec.rb | 3 +++ 5 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 config.ru create mode 100644 spec/integration/application_spec.rb diff --git a/Gemfile b/Gemfile index ff34d824e1..494eca7c08 100644 --- a/Gemfile +++ b/Gemfile @@ -13,3 +13,8 @@ group :development, :test do end gem "pg", "~> 1.4" + +gem "sinatra", "~> 3.0" +gem "sinatra-contrib", "~> 3.0" +gem "webrick", "~> 1.8" +gem "rack-test", "~> 2.1" diff --git a/Gemfile.lock b/Gemfile.lock index 4e481984bc..ea55ee5077 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -5,10 +5,18 @@ GEM ast (2.4.2) diff-lcs (1.4.4) docile (1.4.0) + multi_json (1.15.0) + mustermann (3.0.0) + ruby2_keywords (~> 0.0.1) parallel (1.20.1) parser (3.0.2.0) ast (~> 2.4.1) pg (1.4.6) + rack (2.2.6.4) + rack-protection (3.0.5) + rack + rack-test (2.1.0) + rack (>= 1.3) rainbow (3.0.0) regexp_parser (2.1.1) rexml (3.2.5) @@ -37,6 +45,7 @@ GEM rubocop-ast (1.11.0) parser (>= 3.0.1.1) ruby-progressbar (1.11.0) + ruby2_keywords (0.0.5) simplecov (0.21.2) docile (~> 1.1) simplecov-html (~> 0.11) @@ -47,19 +56,36 @@ GEM terminal-table simplecov-html (0.12.3) simplecov_json_formatter (0.1.3) + sinatra (3.0.5) + mustermann (~> 3.0) + rack (~> 2.2, >= 2.2.4) + rack-protection (= 3.0.5) + tilt (~> 2.0) + sinatra-contrib (3.0.5) + multi_json + mustermann (~> 3.0) + rack-protection (= 3.0.5) + sinatra (= 3.0.5) + tilt (~> 2.0) terminal-table (3.0.1) unicode-display_width (>= 1.1.1, < 3) + tilt (2.1.0) unicode-display_width (2.0.0) + webrick (1.8.1) PLATFORMS ruby DEPENDENCIES pg (~> 1.4) + rack-test (~> 2.1) rspec rubocop (= 1.20) simplecov simplecov-console + sinatra (~> 3.0) + sinatra-contrib (~> 3.0) + webrick (~> 1.8) RUBY VERSION ruby 3.0.2p107 diff --git a/app.rb b/app.rb index a692a8f529..aaa5c9576a 100644 --- a/app.rb +++ b/app.rb @@ -1,15 +1,15 @@ -# file: app.rb - +require 'sinatra' +require "sinatra/reloader" require_relative 'lib/database_connection' - -# We need to give the database name to the method `connect`. -DatabaseConnection.connect('music_library') - -# Perform a SQL query on the database and get the result set. -sql = 'SELECT id, title FROM albums;' -result = DatabaseConnection.exec_params(sql, []) - -# Print out each record from the result set . -result.each do |record| - p record -end +require_relative 'lib/peep_repository' +require_relative 'lib/user_repository' + +DatabaseConnection.connect('chitter_database') + +class Application < Sinatra::Base + # This allows the app code to refresh + # without having to restart the server. + configure :development do + register Sinatra::Reloader + end +end \ No newline at end of file diff --git a/config.ru b/config.ru new file mode 100644 index 0000000000..18af4f3388 --- /dev/null +++ b/config.ru @@ -0,0 +1,3 @@ +# file: config.ru +require './app' +run Application \ No newline at end of file diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb new file mode 100644 index 0000000000..8235ec4c4c --- /dev/null +++ b/spec/integration/application_spec.rb @@ -0,0 +1,3 @@ +require "spec_helper" +require "rack/test" +require_relative '../../app' \ No newline at end of file From 8e6b3cd698ed1e32e3913c474a0e5a2dd1082a8e Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 13:52:57 +0100 Subject: [PATCH 16/56] get homepage method: --- app.rb | 7 +- config.ru | 2 +- route_recipes/homepage_route_recipe.md | 89 ++++++++++++++++++++++++++ spec/integration/application_spec.rb | 18 +++++- views/homepage.erb | 12 ++++ 5 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 route_recipes/homepage_route_recipe.md create mode 100644 views/homepage.erb diff --git a/app.rb b/app.rb index aaa5c9576a..454a81eddb 100644 --- a/app.rb +++ b/app.rb @@ -12,4 +12,9 @@ class Application < Sinatra::Base configure :development do register Sinatra::Reloader end -end \ No newline at end of file + + get '/' do + return erb(:homepage) + end + +end diff --git a/config.ru b/config.ru index 18af4f3388..c41dba5056 100644 --- a/config.ru +++ b/config.ru @@ -1,3 +1,3 @@ # file: config.ru require './app' -run Application \ No newline at end of file +run Application diff --git a/route_recipes/homepage_route_recipe.md b/route_recipes/homepage_route_recipe.md new file mode 100644 index 0000000000..af10f9d958 --- /dev/null +++ b/route_recipes/homepage_route_recipe.md @@ -0,0 +1,89 @@ +# {{ GET }} {{ / }} Route Design Recipe + +## 1. Design the Route Signature + +You'll need to include: + * the HTTP method - GET + * the path - "/" + * any query parameters (passed in the URL) N/A + * or body parameters (passed in the request body) N/A + +## 2. Design the Response + +The route might return different responses, depending on the result. + +For example, a route for a specific blog post (by its ID) might return `200 OK` if the post exists, but `404 Not Found` if the post is not found in the database. + +Your response might return plain text, JSON, or HTML code. + +_Replace the below with your own design. Think of all the different possible responses your route will return._ + +```html + + + + + + +

Welcome to the homepage!

+
Please see tweets
+ + +``` + +## 3. Write Examples + +``` +# Request: GET / +# Expected response.status: 200 +# Expected response.body + +``` + +``` +# Request: + +GET /posts?id=276278 + +# Expected response: + +Response for 404 Not Found +``` + +## 4. Encode as Tests Examples + +```ruby +# EXAMPLE +# file: spec/integration/application_spec.rb + +require "spec_helper" + +describe Application do + include Rack::Test::Methods + + let(:app) { Application.new } + + context "GET /" do + it 'returns 200 OK' do + # Assuming the post with id 1 exists. + response = get('/posts?id=1') + + expect(response.status).to eq(200) + # expect(response.body).to eq(expected_response) + end + + it 'returns 404 Not Found' do + response = get('/posts?id=276278') + + expect(response.status).to eq(404) + # expect(response.body).to eq(expected_response) + end + end +end +``` + +## 5. Implement the Route + +Write the route and web server code to implement the route behaviour. + + \ No newline at end of file diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 8235ec4c4c..74fc14df7d 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -1,3 +1,19 @@ require "spec_helper" require "rack/test" -require_relative '../../app' \ No newline at end of file +require_relative '../../app' + +describe Application do + include Rack::Test::Methods + + let(:app) { Application.new } + + context "Homepage to site /" do + it "shows the homepage with options" do + response = get('/') + + expect(response.status).to eq(200) + expect(response.body).to include('Welcome to Chitter Chatter!') + expect(response.body).to include('Here are your posts:') + end + end +end diff --git a/views/homepage.erb b/views/homepage.erb new file mode 100644 index 0000000000..32adddaa1c --- /dev/null +++ b/views/homepage.erb @@ -0,0 +1,12 @@ + + + + + + + Welcome to Chitter Chatter! + + + Here are your posts: + + \ No newline at end of file From 60048835ccd5a93ad6763b8346bfcfb4d1aabba5 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 14:08:45 +0100 Subject: [PATCH 17/56] get '/' with peeps done --- app.rb | 6 ++++++ spec/integration/application_spec.rb | 5 +++-- views/homepage.erb | 23 +++++++++++++---------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/app.rb b/app.rb index 454a81eddb..d2e1c0b05b 100644 --- a/app.rb +++ b/app.rb @@ -14,7 +14,13 @@ class Application < Sinatra::Base end get '/' do + # need to show peeps on the homepage + repo = PeepRepository.new + @peeps = repo.all + return erb(:homepage) end + + end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 74fc14df7d..35ae99bcf2 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -8,12 +8,13 @@ let(:app) { Application.new } context "Homepage to site /" do - it "shows the homepage with options" do + it "shows the welcome text on homepage with posts" do response = get('/') expect(response.status).to eq(200) expect(response.body).to include('Welcome to Chitter Chatter!') - expect(response.body).to include('Here are your posts:') + expect(response.body).to include('Here are the recent peeps') + expect(response.body).to include('Here is my other post') end end end diff --git a/views/homepage.erb b/views/homepage.erb index 32adddaa1c..5c3d30c788 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -1,12 +1,15 @@ - - - - - + + Welcome to Chitter Chatter! - - - Here are your posts: - - \ No newline at end of file + + +

Welcome to Chitter Chatter!

+

Here are the recent peeps:

+
    + <% @peeps.each do |peep| %> +
  • <%= peep.contents %>
  • + <% end %> +
+ + From 9b3334e06dc1b875cee161ebe9cf2f8f43d87d41 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 14:36:16 +0100 Subject: [PATCH 18/56] register page --- app.rb | 5 ++++- spec/integration/application_spec.rb | 10 ++++++++++ views/homepage.erb | 7 +++++++ views/register.erb | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 views/register.erb diff --git a/app.rb b/app.rb index d2e1c0b05b..7124c13f62 100644 --- a/app.rb +++ b/app.rb @@ -17,10 +17,13 @@ class Application < Sinatra::Base # need to show peeps on the homepage repo = PeepRepository.new @peeps = repo.all - + return erb(:homepage) end + get '/register' do + return erb(:register) + end end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 35ae99bcf2..f36be4f529 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -17,4 +17,14 @@ expect(response.body).to include('Here is my other post') end end + + context 'GET/register' do + it "takes user to the register page to submit details" do + response = get('/register') + + expect(response.status).to eq(200) + expect(response.body).to include('

Enter a username:

') + expect(response.body).to include('

Enter a password:

') + end + end end diff --git a/views/homepage.erb b/views/homepage.erb index 5c3d30c788..16dd87e5e4 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -11,5 +11,12 @@
  • <%= peep.contents %>
  • <% end %> + +

    Options:

    + + Sign up to Chitter Chatter!
    + Log in
    + Log out
    + Post a peep diff --git a/views/register.erb b/views/register.erb new file mode 100644 index 0000000000..7b9f1bdb83 --- /dev/null +++ b/views/register.erb @@ -0,0 +1,17 @@ + + + + + + + Register Page + + +

    Join Chitter Chatter today!

    + +

    Enter your email:

    +

    Enter a username:

    +

    Enter a password:

    + + + \ No newline at end of file From 246108129419004be37ea98c010ce4296016934c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 14:43:01 +0100 Subject: [PATCH 19/56] register page added --- spec/integration/application_spec.rb | 4 ++-- views/homepage.erb | 2 +- views/register.erb | 10 ++++++---- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index f36be4f529..1a582ec052 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -23,8 +23,8 @@ response = get('/register') expect(response.status).to eq(200) - expect(response.body).to include('

    Enter a username:

    ') - expect(response.body).to include('

    Enter a password:

    ') + expect(response.body).to include('') + expect(response.body).to include('') end end end diff --git a/views/homepage.erb b/views/homepage.erb index 16dd87e5e4..52fb25a5f6 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -17,6 +17,6 @@ Sign up to Chitter Chatter!
    Log in
    Log out
    - Post a peep + Post a peep
    diff --git a/views/register.erb b/views/register.erb index 7b9f1bdb83..e7d59c3717 100644 --- a/views/register.erb +++ b/views/register.erb @@ -9,9 +9,11 @@

    Join Chitter Chatter today!

    -

    Enter your email:

    -

    Enter a username:

    -

    Enter a password:

    - +
    +
    +
    +
    + +
    \ No newline at end of file From 24b1aee4458137acd0f8f53d9db979097b413e2c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 15:19:15 +0100 Subject: [PATCH 20/56] post '/' for user registration added --- app.rb | 15 +++++++++++++++ spec/integration/application_spec.rb | 5 +++++ 2 files changed, 20 insertions(+) diff --git a/app.rb b/app.rb index 7124c13f62..08f1b41564 100644 --- a/app.rb +++ b/app.rb @@ -26,4 +26,19 @@ class Application < Sinatra::Base end + post '/' do # once user has registered + if params[:email_address].nil? || params[:username].nil? || params[:password].nil? + status 400 + return '' + end + + repo = UserRepository.new + user = User.new + user.email_address = params[:email_address] + user.username = params[:username] + user.password = params[:password] + repo.create(user) + + redirect '/' + end end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 1a582ec052..0e025d6904 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -27,4 +27,9 @@ expect(response.body).to include('') end end + + context 'POST /' do + it "redirects the user to homepage once registering" do + end + end end From 0e3c4b911acdd37ff57ceec29441518a4fac094c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 20:33:14 +0100 Subject: [PATCH 21/56] post register --- app.rb | 27 ++++++++++++++++----------- spec/integration/application_spec.rb | 20 ++++++++++++++++++-- views/register.erb | 19 ++++++++----------- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/app.rb b/app.rb index 08f1b41564..553913623f 100644 --- a/app.rb +++ b/app.rb @@ -26,19 +26,24 @@ class Application < Sinatra::Base end - post '/' do # once user has registered + post '/register' do # once user has registered + email_address = params['email_address'] + username = params['username'] + password = params['password'] + if params[:email_address].nil? || params[:username].nil? || params[:password].nil? status 400 - return '' + return '' end - repo = UserRepository.new - user = User.new - user.email_address = params[:email_address] - user.username = params[:username] - user.password = params[:password] - repo.create(user) - - redirect '/' - end + repo = UserRepository.new + user = User.new + user.email_address = email_address + user.username = username + user.password = password + repo.create(user) + + redirect '/' + end end + \ No newline at end of file diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 0e025d6904..3e4f687509 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -24,12 +24,28 @@ expect(response.status).to eq(200) expect(response.body).to include('') - expect(response.body).to include('') + expect(response.body).to include('') end end context 'POST /' do - it "redirects the user to homepage once registering" do + it 'should validate register parameters' do + response = post( + '/register', + email_addres: '', + username: 'tina_fake', + password: 123) + + expect(response.status).to eq(400) end + + it "registers a new user" do + response = post('/register', + email_address: 'ricky@fake.com', + username: 'ricky_fake', + password: 'rickyfake1234') + + expect(response.status).to eq(302) end + end end diff --git a/views/register.erb b/views/register.erb index e7d59c3717..643a76b8a1 100644 --- a/views/register.erb +++ b/views/register.erb @@ -1,19 +1,16 @@ - + - - - Register Page

    Join Chitter Chatter today!

    - -
    -
    -
    -
    - + + +
    +
    +
    +
    - \ No newline at end of file + From 7a3ad977357c8aaa08d52aab0e7d7fe125ce232e Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 22:22:44 +0100 Subject: [PATCH 22/56] reversed the extra validation for email etc --- app.rb | 17 ++++++++--------- lib/user_repository.rb | 2 +- spec/integration/application_spec.rb | 23 +++++++++++------------ views/register.erb | 2 +- 4 files changed, 21 insertions(+), 23 deletions(-) diff --git a/app.rb b/app.rb index 553913623f..cf10745882 100644 --- a/app.rb +++ b/app.rb @@ -3,6 +3,7 @@ require_relative 'lib/database_connection' require_relative 'lib/peep_repository' require_relative 'lib/user_repository' +require 'sinatra/flash' DatabaseConnection.connect('chitter_database') @@ -13,6 +14,8 @@ class Application < Sinatra::Base register Sinatra::Reloader end + register Sinatra::Flash + get '/' do # need to show peeps on the homepage repo = PeepRepository.new @@ -27,22 +30,18 @@ class Application < Sinatra::Base end post '/register' do # once user has registered - email_address = params['email_address'] - username = params['username'] - password = params['password'] - - if params[:email_address].nil? || params[:username].nil? || params[:password].nil? + if params[:email_address].nil? || !params[:email_address].include?('@') || params[:username].nil? || params[:password].nil? status 400 return '' end repo = UserRepository.new user = User.new - user.email_address = email_address - user.username = username - user.password = password + user.email_address = params['email_address'] + user.username = params['username'] + user.password = params['password'] repo.create(user) - + redirect '/' end end diff --git a/lib/user_repository.rb b/lib/user_repository.rb index 1bddfb2c2f..e739fefd06 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -44,6 +44,6 @@ def create(new_user) encrypted_password] DatabaseConnection.exec_params(sql, sql_params) - return nil + return new_user end end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 3e4f687509..0598700704 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -18,26 +18,25 @@ end end - context 'GET/register' do + context 'GET /register' do it "takes user to the register page to submit details" do response = get('/register') expect(response.status).to eq(200) expect(response.body).to include('') - expect(response.body).to include('') + expect(response.body).to include('
    ') end end - context 'POST /' do - it 'should validate register parameters' do - response = post( - '/register', - email_addres: '', - username: 'tina_fake', - password: 123) - - expect(response.status).to eq(400) - end + context 'POST /register' do + it 'validates user inputs' do + response = post( + '/register', + email_address: '', + user_name: 'sks', + password: 12345) + expect(response.status).to eq 400 + end it "registers a new user" do response = post('/register', diff --git a/views/register.erb b/views/register.erb index 643a76b8a1..32300525d7 100644 --- a/views/register.erb +++ b/views/register.erb @@ -9,7 +9,7 @@

    -
    +
    From a8fd8f83bb21d8d3df8aa3141e22341880f32a6e Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 22:25:17 +0100 Subject: [PATCH 23/56] rubocop tidying --- app.rb | 17 ++++++++--------- spec/integration/application_spec.rb | 14 +++++++------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/app.rb b/app.rb index cf10745882..b8087e8142 100644 --- a/app.rb +++ b/app.rb @@ -26,7 +26,6 @@ class Application < Sinatra::Base get '/register' do return erb(:register) - end post '/register' do # once user has registered @@ -35,14 +34,14 @@ class Application < Sinatra::Base return '' end - repo = UserRepository.new - user = User.new - user.email_address = params['email_address'] - user.username = params['username'] - user.password = params['password'] - repo.create(user) + repo = UserRepository.new + user = User.new + user.email_address = params['email_address'] + user.username = params['username'] + user.password = params['password'] + repo.create(user) - redirect '/' - end + redirect '/' + end end \ No newline at end of file diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 0598700704..2c73417757 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -30,13 +30,13 @@ context 'POST /register' do it 'validates user inputs' do - response = post( - '/register', - email_address: '', - user_name: 'sks', - password: 12345) - expect(response.status).to eq 400 - end + response = post( + '/register', + email_address: '', + user_name: 'sks', + password: 12_345) + expect(response.status).to eq 400 + end it "registers a new user" do response = post('/register', From f856d315cc3e9e94c6a379f756d717563e8fbea7 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Fri, 7 Apr 2023 23:09:53 +0100 Subject: [PATCH 24/56] login pending --- app.rb | 22 ++++++++++++++++++++-- spec/integration/application_spec.rb | 22 ++++++++++++++++++++++ views/login.erb | 15 +++++++++++++++ 3 files changed, 57 insertions(+), 2 deletions(-) create mode 100644 views/login.erb diff --git a/app.rb b/app.rb index b8087e8142..a6ce92b110 100644 --- a/app.rb +++ b/app.rb @@ -43,5 +43,23 @@ class Application < Sinatra::Base redirect '/' end -end - \ No newline at end of file + + get '/login' do + return erb(:login) + end + + post '/login' do + email_address = params[:email_address] + username = params[:username] + password = params[:password] + + repo = UserRepository.new + # check if the username, email and decrypt password match the account + user = repo.find_by_email(email_address) + if user.username == username && user.email_address == email_address && user.password == password + return erb(:login) + else + halt 404, "Invalid input" + end + end +end \ No newline at end of file diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 2c73417757..c5d7b68bce 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -47,4 +47,26 @@ expect(response.status).to eq(302) end end + + context "GET /login" do + it 'sends a user to the login page' do + response = get('/login') + + expect(response.status).to eq(200) + expect(response.body).to include('
    ') + expect(response.body).to include('') + end + end + + context "POST /login" do + it 'validated a user is valid/existing' do + response = post('/login', + email_address: 'sidra@fake.com', + username: 'sidra_123', + password: '$2a$06$123') + + expect(response.status).to eq(404) + expect(response.body).to include("Invalid input") + end + end end diff --git a/views/login.erb b/views/login.erb new file mode 100644 index 0000000000..6999283b6e --- /dev/null +++ b/views/login.erb @@ -0,0 +1,15 @@ + + + + Login Page + + +

    Log in to your account!

    + + +
    +
    + +
    + + \ No newline at end of file From 55320345806f54dcafe71bd8e78b28046d0c4418 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Sat, 8 Apr 2023 16:50:55 +0100 Subject: [PATCH 25/56] login post changes --- app.rb | 29 +++++++++++++++++--------- spec/integration/application_spec.rb | 7 +++---- views/homepage.erb | 31 +++++++++++++++++----------- views/login.erb | 8 +++++-- views/register.erb | 2 +- 5 files changed, 48 insertions(+), 29 deletions(-) diff --git a/app.rb b/app.rb index a6ce92b110..414f9a6521 100644 --- a/app.rb +++ b/app.rb @@ -14,15 +14,22 @@ class Application < Sinatra::Base register Sinatra::Reloader end + enable :sessions register Sinatra::Flash get '/' do - # need to show peeps on the homepage repo = PeepRepository.new @peeps = repo.all - - return erb(:homepage) - end + + if session[:user_id] + # user is logged in + @user = UserRepository.new.find(session[:user_id]) + return erb(:homepage, locals: { logged_in: true }) + else + # user is not logged in + return erb(:homepage, locals: { logged_in: false }) + end + end get '/register' do return erb(:register) @@ -50,16 +57,18 @@ class Application < Sinatra::Base post '/login' do email_address = params[:email_address] - username = params[:username] password = params[:password] repo = UserRepository.new - # check if the username, email and decrypt password match the account user = repo.find_by_email(email_address) - if user.username == username && user.email_address == email_address && user.password == password - return erb(:login) + + if user && user.password == password + session[:user_id] = user.id + + redirect '/' else - halt 404, "Invalid input" + @error = true + return erb(:login) end end -end \ No newline at end of file +end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index c5d7b68bce..39beedc66b 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -13,7 +13,7 @@ expect(response.status).to eq(200) expect(response.body).to include('Welcome to Chitter Chatter!') - expect(response.body).to include('Here are the recent peeps') + expect(response.body).to include('Recent Peeps:') expect(response.body).to include('Here is my other post') end end @@ -62,11 +62,10 @@ it 'validated a user is valid/existing' do response = post('/login', email_address: 'sidra@fake.com', - username: 'sidra_123', password: '$2a$06$123') - expect(response.status).to eq(404) - expect(response.body).to include("Invalid input") + expect(response.status).to eq(200) + expect(response.body).to include("Login failed. Please try again") end end end diff --git a/views/homepage.erb b/views/homepage.erb index 52fb25a5f6..7f0493ada5 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -4,19 +4,26 @@ Welcome to Chitter Chatter! -

    Welcome to Chitter Chatter!

    -

    Here are the recent peeps:

    -
      - <% @peeps.each do |peep| %> -
    • <%= peep.contents %>
    • - <% end %> -
    + <% if session[:user_id] %> + +

    Welcome <%= @user.username %>!

    + Logout +

    Recent Peeps:

    + <% @peeps.each do |peep| %> +

    <%= peep.contents %>

    + <% end %> + <% else %> + +

    Welcome to Chitter!

    Options:

    - - Sign up to Chitter Chatter!
    - Log in
    - Log out
    - Post a peep
    + Sign Up
    + Login
    +

    Recent Peeps:

    + <% @peeps.each do |peep| %> +

    <%= peep.contents %>

    + <% end %> + <% end %> + diff --git a/views/login.erb b/views/login.erb index 6999283b6e..06e3cf4b81 100644 --- a/views/login.erb +++ b/views/login.erb @@ -6,9 +6,13 @@

    Log in to your account!

    + <% if @error %> +
    Login failed. Please try again.
    + <% end %> +
    -
    -
    +
    +
    diff --git a/views/register.erb b/views/register.erb index 32300525d7..e76e23315c 100644 --- a/views/register.erb +++ b/views/register.erb @@ -9,7 +9,7 @@


    -
    +
    From 379c4ccea649d9a79bfac3a70a58cdfbf896c205 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Sun, 9 Apr 2023 13:20:20 +0100 Subject: [PATCH 26/56] login and logout done --- app.rb | 22 +++++++++++++---- spec/integration/application_spec.rb | 37 ++++++++++++++++++++++++---- views/homepage.erb | 2 +- 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/app.rb b/app.rb index 414f9a6521..21e57aca8c 100644 --- a/app.rb +++ b/app.rb @@ -21,9 +21,9 @@ class Application < Sinatra::Base repo = PeepRepository.new @peeps = repo.all - if session[:user_id] + if session[:email_address] # user is logged in - @user = UserRepository.new.find(session[:user_id]) + @user = UserRepository.new.find_by_email(session[:email_address]) return erb(:homepage, locals: { logged_in: true }) else # user is not logged in @@ -36,7 +36,9 @@ class Application < Sinatra::Base end post '/register' do # once user has registered - if params[:email_address].nil? || !params[:email_address].include?('@') || params[:username].nil? || params[:password].nil? + if params[:email_address].nil? || + !params[:email_address].include?('@') || + params[:username].nil? || params[:password].nil? status 400 return '' end @@ -63,12 +65,22 @@ class Application < Sinatra::Base user = repo.find_by_email(email_address) if user && user.password == password - session[:user_id] = user.id + session[:email_address] = user.email_address - redirect '/' + peep_repo = PeepRepository.new + @peeps = peep_repo.all + + @user = user + + return erb(:homepage) else @error = true return erb(:login) end end + + get '/logout' do + session.clear + redirect '/' + end end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 39beedc66b..e48836a9ad 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -40,9 +40,9 @@ it "registers a new user" do response = post('/register', - email_address: 'ricky@fake.com', - username: 'ricky_fake', - password: 'rickyfake1234') + email_address: 'ricky@fake.com', + username: 'ricky_fake', + password: 'rickyfake1234') expect(response.status).to eq(302) end @@ -61,11 +61,38 @@ context "POST /login" do it 'validated a user is valid/existing' do response = post('/login', - email_address: 'sidra@fake.com', - password: '$2a$06$123') + email_address: 'sidra@fake.com', + password: '$2a$06$123') expect(response.status).to eq(200) expect(response.body).to include("Login failed. Please try again") end + + it 'logs a user in and redirects to logged in homepage' do + response = post('/login', + email_address: 'sidra@fake.com', + password: '12345') + + expect(response.status).to eq(200) + expect(response.body).to include('

    Welcome sidra_fake!

    ') + expect(response.body).to include('Logout') + end end + + describe 'GET /logout' do + it 'redirects to the homepage and displays the welcome message when the user logs out' do + # Sign in the user before logging them out + post '/login', params = { email_address: 'user@example.com', password: 'password' } + get '/logout' + + # Expect the response to have a 302 status code (redirect) + expect(last_response.status).to eq(302) + # Follow the redirect to the homepage + follow_redirect! + + expect(last_response.status).to eq(200) + expect(last_response.body).to include('

    Welcome to Chitter!

    ') + end + end + end diff --git a/views/homepage.erb b/views/homepage.erb index 7f0493ada5..b7c1518317 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -5,7 +5,7 @@ - <% if session[:user_id] %> + <% if session[:email_address] %>

    Welcome <%= @user.username %>!

    Logout From c19ca13e061fecd07faa94d2552af5109cfed593 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Sun, 9 Apr 2023 14:33:16 +0100 Subject: [PATCH 27/56] new_peep route --- app.rb | 29 ++++++++++++++++++++------ spec/integration/application_spec.rb | 31 +++++++++++++++++++++++----- views/homepage.erb | 1 + views/new_peep.erb | 6 ++++++ 4 files changed, 56 insertions(+), 11 deletions(-) create mode 100644 views/new_peep.erb diff --git a/app.rb b/app.rb index 21e57aca8c..9325fcff95 100644 --- a/app.rb +++ b/app.rb @@ -3,7 +3,7 @@ require_relative 'lib/database_connection' require_relative 'lib/peep_repository' require_relative 'lib/user_repository' -require 'sinatra/flash' +require 'date' DatabaseConnection.connect('chitter_database') @@ -15,18 +15,15 @@ class Application < Sinatra::Base end enable :sessions - register Sinatra::Flash get '/' do repo = PeepRepository.new @peeps = repo.all if session[:email_address] - # user is logged in @user = UserRepository.new.find_by_email(session[:email_address]) return erb(:homepage, locals: { logged_in: true }) else - # user is not logged in return erb(:homepage, locals: { logged_in: false }) end end @@ -69,9 +66,7 @@ class Application < Sinatra::Base peep_repo = PeepRepository.new @peeps = peep_repo.all - @user = user - return erb(:homepage) else @error = true @@ -83,4 +78,26 @@ class Application < Sinatra::Base session.clear redirect '/' end + + get '/new_peep' do + return erb(:new_peep) + end + + post '/new_peep' do + contents = params[:contents] + + if session[:email_address] + @user = UserRepository.new.find_by_email(session[:email_address]) + end + + peep_repo = PeepRepository.new + new_peep = Peep.new + new_peep.contents = contents + new_peep.time = Time.now.strftime("%d/%m/%Y %H:%M") + new_peep.user_id = @user.id + peep_repo.create_peep(new_peep) + @peeps = peep_repo.all + + return erb(:homepage) + end end diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index e48836a9ad..3a80bb8f43 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -7,7 +7,7 @@ let(:app) { Application.new } - context "Homepage to site /" do + describe "Homepage to site /" do it "shows the welcome text on homepage with posts" do response = get('/') @@ -18,7 +18,7 @@ end end - context 'GET /register' do + describe 'GET /register' do it "takes user to the register page to submit details" do response = get('/register') @@ -28,7 +28,7 @@ end end - context 'POST /register' do + describe 'POST /register' do it 'validates user inputs' do response = post( '/register', @@ -48,7 +48,7 @@ end end - context "GET /login" do + describe "GET /login" do it 'sends a user to the login page' do response = get('/login') @@ -58,7 +58,7 @@ end end - context "POST /login" do + describe "POST /login" do it 'validated a user is valid/existing' do response = post('/login', email_address: 'sidra@fake.com', @@ -95,4 +95,25 @@ end end + describe "GET /new_peep" do + it 'sends a user to the new_peep page' do + response = get('/new_peep') + + expect(response.status).to eq(200) + expect(response.body).to include('

    What do you want to say?

    ') + end + end + + describe "POST /new_peep" do + it 'submits a peep of the user and shows it on the homepage' do + post '/login', params = { email_address: 'sidra@fake.com', password: '12345' } + expect(last_response.status).to eq(200) # ensure login successful + + peep_contents = "Hello world!" + post '/new_peep', params = { contents: peep_contents } + expect(last_response.status).to eq(200) + + expect(last_response.body).to include(peep_contents) + end + end end diff --git a/views/homepage.erb b/views/homepage.erb index b7c1518317..133105c101 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -8,6 +8,7 @@ <% if session[:email_address] %>

    Welcome <%= @user.username %>!

    + Post a Peep
    Logout

    Recent Peeps:

    <% @peeps.each do |peep| %> diff --git a/views/new_peep.erb b/views/new_peep.erb new file mode 100644 index 0000000000..643e1c3409 --- /dev/null +++ b/views/new_peep.erb @@ -0,0 +1,6 @@ +

    What do you want to say?

    + +
    +
    + +
    \ No newline at end of file From ef89d183f9f2d269e9e61235353609b546e5554a Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Sun, 9 Apr 2023 14:41:39 +0100 Subject: [PATCH 28/56] fixed the login where incorrect email put in --- app.rb | 5 +++++ lib/user_repository.rb | 21 ++++++++++++--------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/app.rb b/app.rb index 9325fcff95..31f27f53a7 100644 --- a/app.rb +++ b/app.rb @@ -72,6 +72,11 @@ class Application < Sinatra::Base @error = true return erb(:login) end + + if user.nil? + @error = true + return erb(:login) + end end get '/logout' do diff --git a/lib/user_repository.rb b/lib/user_repository.rb index e739fefd06..e0d73b8f2a 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -22,15 +22,18 @@ def all def find_by_email(email) sql = 'SELECT id, email_address, username, password FROM users WHERE email_address = $1;' result_set = DatabaseConnection.exec_params(sql, [email]) - user_row = result_set[0] - - user = User.new - user.id = user_row['id'] - user.email_address = user_row['email_address'] - user.username = user_row['username'] - user.password = BCrypt::Password.new(user_row['password']) - - return user + + if result_set.ntuples > 0 + user_row = result_set[0] + user = User.new + user.id = user_row['id'] + user.email_address = user_row['email_address'] + user.username = user_row['username'] + user.password = BCrypt::Password.new(user_row['password']) + return user + else + nil + end end def create(new_user) From 1ba516d44665e3d1b0762e0abc839fdbf0c8a8f1 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Sun, 9 Apr 2023 16:19:05 +0100 Subject: [PATCH 29/56] sort posts by newest first --- lib/peep_repository.rb | 2 +- spec/peep_repository_spec.rb | 4 ++-- spec/seeds.sql | 1 + views/homepage.erb | 4 ++-- views/new_peep.erb | 2 +- 5 files changed, 7 insertions(+), 6 deletions(-) diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index 87961c20eb..df7a6f7ee3 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -4,7 +4,7 @@ class PeepRepository def all - sql = 'SELECT id, time, contents, user_id FROM peeps;' + sql = 'SELECT id, time, contents, user_id FROM peeps ORDER BY time desc;' result_set = DatabaseConnection.exec_params(sql, []) peeps = [] diff --git a/spec/peep_repository_spec.rb b/spec/peep_repository_spec.rb index 3262783e34..48932e5f12 100644 --- a/spec/peep_repository_spec.rb +++ b/spec/peep_repository_spec.rb @@ -16,7 +16,7 @@ def reset_users_table peeps = repo.all expect(peeps.length).to eq(4) - expect(peeps.last.contents).to eq('User 3 newer post') + expect(peeps.last.contents).to eq('This is my post') end it 'creates a new peep' do @@ -29,6 +29,6 @@ def reset_users_table peeps = repo.all expect(peeps.length).to eq(5) - expect(peeps.last.contents).to eq('Hello this is me!') + expect(peeps.first.contents).to eq('Hello this is me!') end end diff --git a/spec/seeds.sql b/spec/seeds.sql index 6f55387ba1..b7b001b878 100644 --- a/spec/seeds.sql +++ b/spec/seeds.sql @@ -13,3 +13,4 @@ INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-13 12:16:00', 'Here INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-14 12:19:00', 'Here is my other post', '1'); INSERT INTO peeps (time, contents, user_id) VALUES ('2023-04-15 12:10:00', 'User 3 newer post', '3'); + diff --git a/views/homepage.erb b/views/homepage.erb index 133105c101..8fb07b7079 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -12,7 +12,7 @@ Logout

    Recent Peeps:

    <% @peeps.each do |peep| %> -

    <%= peep.contents %>

    +

    <%= peep.contents %> - <%= peep.time %>

    <% end %> <% else %> @@ -22,7 +22,7 @@ Login

    Recent Peeps:

    <% @peeps.each do |peep| %> -

    <%= peep.contents %>

    +

    <%= peep.contents %> - <%= peep.time %>

    <% end %> <% end %> diff --git a/views/new_peep.erb b/views/new_peep.erb index 643e1c3409..ddb0c480c9 100644 --- a/views/new_peep.erb +++ b/views/new_peep.erb @@ -1,6 +1,6 @@

    What do you want to say?

    -
    +
    \ No newline at end of file From 7b35be68889d5f914d32100a5e62875b04191489 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Sun, 9 Apr 2023 16:29:47 +0100 Subject: [PATCH 30/56] refactor login post --- app.rb | 20 +++++++------------- lib/user_repository.rb | 2 +- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app.rb b/app.rb index 31f27f53a7..99334225c9 100644 --- a/app.rb +++ b/app.rb @@ -57,27 +57,21 @@ class Application < Sinatra::Base post '/login' do email_address = params[:email_address] password = params[:password] - - repo = UserRepository.new - user = repo.find_by_email(email_address) - + + user = UserRepository.new.find_by_email(email_address) + if user && user.password == password session[:email_address] = user.email_address - + peep_repo = PeepRepository.new @peeps = peep_repo.all @user = user - return erb(:homepage) + erb(:homepage) else @error = true - return erb(:login) - end - - if user.nil? - @error = true - return erb(:login) + erb(:login) end - end + end get '/logout' do session.clear diff --git a/lib/user_repository.rb b/lib/user_repository.rb index e0d73b8f2a..61d815ddf2 100644 --- a/lib/user_repository.rb +++ b/lib/user_repository.rb @@ -23,7 +23,7 @@ def find_by_email(email) sql = 'SELECT id, email_address, username, password FROM users WHERE email_address = $1;' result_set = DatabaseConnection.exec_params(sql, [email]) - if result_set.ntuples > 0 + if result_set.ntuples.positive? user_row = result_set[0] user = User.new user.id = user_row['id'] From c65f134e0338e0e22e777161b8abbc9b8b29d076 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 12:17:28 +0100 Subject: [PATCH 31/56] add css --- app.rb | 8 +- lib/ignore.rb | 121 +++++++++++++++++++++++++ public/style.css | 106 ++++++++++++++++++++++ route_recipes/homepage_route_recipe.md | 87 +++++++++++++++++- spec/integration/application_spec.rb | 4 +- views/homepage.erb | 27 ++++-- views/login.erb | 10 +- views/new_peep.erb | 5 +- views/register.erb | 13 ++- 9 files changed, 357 insertions(+), 24 deletions(-) create mode 100644 lib/ignore.rb create mode 100644 public/style.css diff --git a/app.rb b/app.rb index 99334225c9..e6407445c1 100644 --- a/app.rb +++ b/app.rb @@ -22,9 +22,9 @@ class Application < Sinatra::Base if session[:email_address] @user = UserRepository.new.find_by_email(session[:email_address]) - return erb(:homepage, locals: { logged_in: true }) + return erb(:homepage) else - return erb(:homepage, locals: { logged_in: false }) + return erb(:homepage) end end @@ -33,9 +33,7 @@ class Application < Sinatra::Base end post '/register' do # once user has registered - if params[:email_address].nil? || - !params[:email_address].include?('@') || - params[:username].nil? || params[:password].nil? + if !params[:email_address].include?('@') status 400 return '' end diff --git a/lib/ignore.rb b/lib/ignore.rb new file mode 100644 index 0000000000..80c563906a --- /dev/null +++ b/lib/ignore.rb @@ -0,0 +1,121 @@ +# repeating app.rb so I understand it all + +require 'sinatra' +require 'sinatra/reloader' +# automatically reload app when change detected +require_relative 'lib/database_connection' +require_relative 'lib/peep_repository' +require_relative 'lib/user_repository' +require 'date' + +DatabaseConnection.connect('chitter_database') + +class Application < Sinatra::Base +# ^ makes a new class 'Application' that inherits from the Sinatra::Base +# Base is main class for web application building with the Sinatra web framework +# Allows us to define routes, configure settings, and add extensions + configue :development do + # sets Sinatra configuration to development environment + register Sinatra::Reloader + end + + enable: sessions + # Store user data for a specific session + + get '/' do + repo = PeepRepository.new + @peeps = repo.all + # Above need to make a new peep repository to show all peeps to users + # Instance variable for the erb file to access + + if session[:email_address] + # above checks if user prev logged in, if they were, the email is stored + # on the session, if not then the email is not stored on the session + # @user instance variable pulls our the user based on finding by email address + # This allows us to access all the elements of the user + @user = UserRepository.new.find_by_email(session[:email_address]) + return erb(:homepage) + else + return erb(:homepage) + end + end + + get '/register' do + return erb(:register) + end + + post '/register' do + if !params[:email_address].include?('@') || + status 400 + return '' + end # In view we have a minlength reference, so dont need to worry about nil + + repo = UserRepository.new + user = User.new + user.email_address = params['email_address'] + user.username = params['username'] + user.password = params['password'] + repo.create(user) + + redirect '/' + end + + get '/login' do + return erb(:login) + end + + post '/login' do + email_address = params[email_address] + password = params[password] + + user = UserRepository.new(find_by_email(email_address)) + # Above assigns a user variable to a new user repo with + # find_by_email, and this finds the user based on email_address + + if user && user.password == password + # if user means if the user is true from line 71 (it exists) + # user.password == password checks the password with decrypt matches + # session[email_address] is created based on user.email_address + session[:email_address] = user.email_address + + peep_repo = PeepRepository.new + @peeps = peep_repo.all + # peep repo needs to be done for every route as it doesn't save per route + @user = user # create this as an instance variable + erb(:homepage) + else + @error = true # error message defined in login page + erb(:login) + end + + get 'logout' do + session.clear # clears the user session + redirect '/' + end + + get '/new_peep' do + return erb(:new_peep) + end + + post '/new_peep' do + contents = params[:contents] + + if session[:email_address] + @user = UserRepository.new.find_by_email(session[:email_address]) + end + + peep_repo = PeepRepository.new + + new_peep = Peep.new + new_peep.contents = contents + new_peep.time = Time.now.strftime("%d/%m/%Y %H:%M") + new_peep.user_id = @user.id + + peep_repo.create_peep(new_peep) + @peeps = peep_repo.all + # Above first is making a new peep based on contents submitted on + # new_peep erb, then relaying all the peeps, maybe i dont have to do this + + return erb(:homepage) + end +end \ No newline at end of file diff --git a/public/style.css b/public/style.css new file mode 100644 index 0000000000..cde1c13226 --- /dev/null +++ b/public/style.css @@ -0,0 +1,106 @@ +body { + font-family: Arial, Helvetica, sans-serif; + margin: 20; + padding: 20; +} + +h1 { + font-size: 32px; + font-weight: bold; +} + +h2 { + font-size: 24px; + font-weight: bold; +} + +p { + font-size: 16px; +} + +a { + color: #0077cc; + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + +/* Homepage specific */ + +.options-box { + border: 1px; + background-color: lightblue; + padding: 5px; +} + +.welcome-box { + border: 1px; + background-color: mediumturquoise; + padding: 5px; +} + +.peeps-box { + width: 80%; + margin: auto; + max-height: 300px; + overflow: scroll; +} + + .scrollable-peeps { + padding: 10px; +} + + +/* Register specific */ + +input[type="submit"] { + background-color: lightblue; + color: black; + padding: 10px 20px; + font-weight: bold; + border: grey; + border-radius: 5px; + cursor: pointer; + margin: auto; + width: 50%; +} + +form { + margin: auto; + margin-top: 50px; + width: 50%; +} + +input[type=text] { + margin-bottom: 10px; + padding: 5px; +} + +.join-box { + border: 1px; + background-color: mediumturquoise; + padding: 5px; + margin-bottom: 10px; +} + + +/* Login specific */ + +.login-box { + border: 1px; + background-color: mediumturquoise; + padding: 5px; + margin-bottom: 10px; +} + +/* New Peep specific */ + +.question-peep { + font-family: Arial, Helvetica, sans-serif; + border: 1px; + background-color: mediumturquoise; + padding: 5px; + margin-bottom: 10px; +} \ No newline at end of file diff --git a/route_recipes/homepage_route_recipe.md b/route_recipes/homepage_route_recipe.md index af10f9d958..17fbdb41d9 100644 --- a/route_recipes/homepage_route_recipe.md +++ b/route_recipes/homepage_route_recipe.md @@ -22,15 +22,98 @@ _Replace the below with your own design. Think of all the different possible res + -

    Welcome to the homepage!

    -
    Please see tweets
    +

    Sign up to Chitter Chatter!

    +
    +
    +
    +
    + +
    + + + + + + +

    Enter your details

    + <% if @error %> +
    Login failed. Please try again
    + <% end %> +
    +
    +
    + +
    + + + + + + + + +

    What do you want to say?

    +
    +
    + +
    + + + + + + + + + + + <% if session[:email_address] %> + +

    Welcome <%= @user.username %>!

    +

    Options

    + Log out
    + Send peep + +

    Recent Peeps

    + <% @peeps.each do |peep| %> +
    <%= peep.contents %> - <%= peep.time %>
    + <% end %> + + <% else %> + +

    Welcome to Chitter Chatter!

    +

    Options

    + Log in + Log in + +

    Recent Peeps

    + <% @peeps.each do |peep| %> +
    <%= peep.contents %> - <%= peep.time %>
    + <% end %> + <% end %> + + + + + + + + + + + + + + ``` + ## 3. Write Examples ``` diff --git a/spec/integration/application_spec.rb b/spec/integration/application_spec.rb index 3a80bb8f43..6d6453cd51 100644 --- a/spec/integration/application_spec.rb +++ b/spec/integration/application_spec.rb @@ -23,7 +23,7 @@ response = get('/register') expect(response.status).to eq(200) - expect(response.body).to include('') + expect(response.body).to include('') expect(response.body).to include('
    ') end end @@ -54,7 +54,7 @@ expect(response.status).to eq(200) expect(response.body).to include('') - expect(response.body).to include('') + expect(response.body).to include('') end end diff --git a/views/homepage.erb b/views/homepage.erb index 8fb07b7079..5e05f04c80 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -2,29 +2,44 @@ Welcome to Chitter Chatter! + <% if session[:email_address] %> +

    Welcome <%= @user.username %>!

    +
    + +

    Recent Peeps:

    +
    <% @peeps.each do |peep| %>

    <%= peep.contents %> - <%= peep.time %>

    <% end %> +
    +
    <% else %> +

    Welcome to Chitter!

    -

    Options:

    +
    +
    Sign Up
    Login
    -

    Recent Peeps:

    - <% @peeps.each do |peep| %> -

    <%= peep.contents %> - <%= peep.time %>

    - <% end %> +
    +
    +

    Recent Peeps:

    +
    + <% @peeps.each do |peep| %> +

    <%= peep.contents %> - <%= peep.time %>

    + <% end %> +
    +
    <% end %> - diff --git a/views/login.erb b/views/login.erb index 06e3cf4b81..ba6f22f306 100644 --- a/views/login.erb +++ b/views/login.erb @@ -2,18 +2,20 @@ Login Page + + <% if @error %>
    Login failed. Please try again.
    <% end %> -
    -
    - +
    +
    +
    \ No newline at end of file diff --git a/views/new_peep.erb b/views/new_peep.erb index ddb0c480c9..9de5e0314b 100644 --- a/views/new_peep.erb +++ b/views/new_peep.erb @@ -1,6 +1,9 @@ + +

    What do you want to say?

    +

    - +
    \ No newline at end of file diff --git a/views/register.erb b/views/register.erb index e76e23315c..80eff7278a 100644 --- a/views/register.erb +++ b/views/register.erb @@ -2,15 +2,20 @@ Register Page + +

    Join Chitter Chatter today!

    +
    -
    -
    -
    - +
    +
    +
    +
    + +
    From 543a25423752ead5868f3bdca1ba2fcedfc50377 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 13:26:51 +0100 Subject: [PATCH 32/56] trying to add username to no avail --- app.rb | 15 +++++---- lib/peep.rb | 2 +- lib/peep_repository.rb | 8 +++-- views/homepage.erb | 69 +++++++++++++++++++++--------------------- 4 files changed, 48 insertions(+), 46 deletions(-) diff --git a/app.rb b/app.rb index e6407445c1..377bce447c 100644 --- a/app.rb +++ b/app.rb @@ -8,8 +8,6 @@ DatabaseConnection.connect('chitter_database') class Application < Sinatra::Base - # This allows the app code to refresh - # without having to restart the server. configure :development do register Sinatra::Reloader end @@ -19,13 +17,13 @@ class Application < Sinatra::Base get '/' do repo = PeepRepository.new @peeps = repo.all - + if session[:email_address] - @user = UserRepository.new.find_by_email(session[:email_address]) - return erb(:homepage) - else - return erb(:homepage) + user_repo = UserRepository.new + @user = user_repo.find_by_email(session[:email_address]) end + + return erb(:homepage) end get '/register' do @@ -33,7 +31,7 @@ class Application < Sinatra::Base end post '/register' do # once user has registered - if !params[:email_address].include?('@') + unless params[:email_address].include?('@') status 400 return '' end @@ -92,6 +90,7 @@ class Application < Sinatra::Base new_peep.contents = contents new_peep.time = Time.now.strftime("%d/%m/%Y %H:%M") new_peep.user_id = @user.id + # new_peep.username = @user.username peep_repo.create_peep(new_peep) @peeps = peep_repo.all diff --git a/lib/peep.rb b/lib/peep.rb index 590b343e8f..da1e0c5ba4 100644 --- a/lib/peep.rb +++ b/lib/peep.rb @@ -1,3 +1,3 @@ class Peep - attr_accessor :id, :time, :contents, :user_id + attr_accessor :id, :time, :contents, :user_id, :username end diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index df7a6f7ee3..94fb2ca15d 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -4,17 +4,21 @@ class PeepRepository def all - sql = 'SELECT id, time, contents, user_id FROM peeps ORDER BY time desc;' + sql = 'SELECT peeps.id AS "peeps_id", users.username AS "username", + users.id AS "user_id", peeps.contents AS "contents", peeps.time AS "time" + FROM peeps + INNER JOIN users ON peeps.user_id=users.id ORDER BY time desc;' result_set = DatabaseConnection.exec_params(sql, []) peeps = [] result_set.each do |row| peep = Peep.new - peep.id = row['id'] + peep.id = row['peeps_id'] peep.time = row['time'] peep.contents = row['contents'] peep.user_id = row['user_id'] + peep.username = row['username'] peeps << peep end return peeps diff --git a/views/homepage.erb b/views/homepage.erb index 5e05f04c80..a1c14482cc 100644 --- a/views/homepage.erb +++ b/views/homepage.erb @@ -5,41 +5,40 @@ - - <% if session[:email_address] %> - -
    -

    Welcome <%= @user.username %>!

    -
    - -
    -

    Recent Peeps:

    -
    - <% @peeps.each do |peep| %> -

    <%= peep.contents %> - <%= peep.time %>

    - <% end %> -
    -
    - <% else %> - -
    -

    Welcome to Chitter!

    -
    -
    - Sign Up
    - Login
    -
    -
    -

    Recent Peeps:

    -
    - <% @peeps.each do |peep| %> -

    <%= peep.contents %> - <%= peep.time %>

    - <% end %> + <% if session[:email_address] %> + +
    +

    Welcome <%= @user.username %>!

    +
    + +
    +

    Recent Peeps:

    +
    + <% @peeps.each do |peep| %> +

    <%= peep.contents %> - <%= peep.time %>

    + <% end %> +
    +
    + <% else %> + +
    +

    Welcome to Chitter!

    -
    - <% end %> +
    + Sign Up
    + Login
    +
    +
    +

    Recent Peeps:

    +
    + <% @peeps.each do |peep| %> +

    <%= peep.contents %> - <%= peep.time %>

    + <% end %> +
    +
    + <% end %> From e7ca13d7fda9feab59bfb810cd0d4f7c20f5009c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 15:16:59 +0100 Subject: [PATCH 33/56] Failed to add username --- app.rb | 2 +- lib/peep_repository.rb | 3 ++- views/new_peep.erb | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app.rb b/app.rb index 377bce447c..053b8d107b 100644 --- a/app.rb +++ b/app.rb @@ -90,7 +90,7 @@ class Application < Sinatra::Base new_peep.contents = contents new_peep.time = Time.now.strftime("%d/%m/%Y %H:%M") new_peep.user_id = @user.id - # new_peep.username = @user.username + new_peep.username = @user.username peep_repo.create_peep(new_peep) @peeps = peep_repo.all diff --git a/lib/peep_repository.rb b/lib/peep_repository.rb index 94fb2ca15d..5d5697ddf0 100644 --- a/lib/peep_repository.rb +++ b/lib/peep_repository.rb @@ -25,8 +25,9 @@ def all end def create_peep(peep) - sql = 'INSERT INTO peeps (time, contents, user_id) + sql = 'INSERT INTO peeps (time, contents, user_id) VALUES ($1, $2, $3);' + time = Time.now.strftime("%d/%m/%Y %H:%M") sql_params = [time, peep.contents, peep.user_id] diff --git a/views/new_peep.erb b/views/new_peep.erb index 9de5e0314b..fc82d98a7b 100644 --- a/views/new_peep.erb +++ b/views/new_peep.erb @@ -4,6 +4,6 @@
    -
    +
    \ No newline at end of file From bb3ca20dd6ff4d1185b3fdebb7c106153da3db45 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 15:20:01 +0100 Subject: [PATCH 34/56] Setup for deploy --- Gemfile.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile.lock b/Gemfile.lock index ea55ee5077..40b494142b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -75,6 +75,7 @@ GEM PLATFORMS ruby + x86_64-linux DEPENDENCIES pg (~> 1.4) From 9c73d9335f99f4032e00e9e754e81a999ab928a6 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 17:23:43 +0100 Subject: [PATCH 35/56] ENV in database connection --- lib/database_connection.rb | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/database_connection.rb b/lib/database_connection.rb index f4bde0ff72..6821b85459 100644 --- a/lib/database_connection.rb +++ b/lib/database_connection.rb @@ -10,7 +10,20 @@ class DatabaseConnection # This method connects to PostgreSQL using the # PG gem. We connect to 127.0.0.1, and select # the database name given in argument. - def self.connect(database_name) +# file: lib/database_connection.rb + def self.connect + # If the environment variable (set by Render) + # is present, use this to open the connection. + if ENV['DATABASE_URL'] != nil + @connection = PG.connect(ENV['DATABASE_URL']) + return + end + + if ENV['ENV'] == 'test' + database_name = 'chitter_database_test' + else + database_name = 'chitter_database' + end @connection = PG.connect({ host: '127.0.0.1', dbname: database_name }) end From 4f1f4dc920028c69c6119b63332008a7865dd5d6 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 17:38:51 +0100 Subject: [PATCH 36/56] update to add bcrypt --- Gemfile | 2 ++ Gemfile.lock | 48 +++++++++++++++++++++++++----------------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/Gemfile b/Gemfile index 494eca7c08..ea268b2e19 100644 --- a/Gemfile +++ b/Gemfile @@ -18,3 +18,5 @@ gem "sinatra", "~> 3.0" gem "sinatra-contrib", "~> 3.0" gem "webrick", "~> 1.8" gem "rack-test", "~> 2.1" +gem 'bcrypt', '~> 3.1.7' + diff --git a/Gemfile.lock b/Gemfile.lock index 40b494142b..0a0ac1a486 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,13 +3,14 @@ GEM specs: ansi (1.5.0) ast (2.4.2) - diff-lcs (1.4.4) + bcrypt (3.1.18) + diff-lcs (1.5.0) docile (1.4.0) multi_json (1.15.0) mustermann (3.0.0) ruby2_keywords (~> 0.0.1) - parallel (1.20.1) - parser (3.0.2.0) + parallel (1.22.1) + parser (3.2.2.0) ast (~> 2.4.1) pg (1.4.6) rack (2.2.6.4) @@ -17,22 +18,22 @@ GEM rack rack-test (2.1.0) rack (>= 1.3) - rainbow (3.0.0) - regexp_parser (2.1.1) + rainbow (3.1.1) + regexp_parser (2.7.0) rexml (3.2.5) - rspec (3.10.0) - rspec-core (~> 3.10.0) - rspec-expectations (~> 3.10.0) - rspec-mocks (~> 3.10.0) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.1) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.2) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.2) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-support (3.10.2) + rspec-support (~> 3.12.0) + rspec-support (3.12.0) rubocop (1.20.0) parallel (~> 1.10) parser (>= 3.0.0.0) @@ -42,11 +43,11 @@ GEM rubocop-ast (>= 1.9.1, < 2.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.11.0) - parser (>= 3.0.1.1) - ruby-progressbar (1.11.0) + rubocop-ast (1.28.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) - simplecov (0.21.2) + simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) @@ -55,7 +56,7 @@ GEM simplecov terminal-table simplecov-html (0.12.3) - simplecov_json_formatter (0.1.3) + simplecov_json_formatter (0.1.4) sinatra (3.0.5) mustermann (~> 3.0) rack (~> 2.2, >= 2.2.4) @@ -67,10 +68,10 @@ GEM rack-protection (= 3.0.5) sinatra (= 3.0.5) tilt (~> 2.0) - terminal-table (3.0.1) + terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) tilt (2.1.0) - unicode-display_width (2.0.0) + unicode-display_width (2.4.2) webrick (1.8.1) PLATFORMS @@ -78,6 +79,7 @@ PLATFORMS x86_64-linux DEPENDENCIES + bcrypt (~> 3.1.7) pg (~> 1.4) rack-test (~> 2.1) rspec From a3d2c9400ca7d0416126162aa344ae70347b878c Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 17:55:15 +0100 Subject: [PATCH 37/56] removed comments from database connection : --- lib/database_connection.rb | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/lib/database_connection.rb b/lib/database_connection.rb index 6821b85459..d168a54e55 100644 --- a/lib/database_connection.rb +++ b/lib/database_connection.rb @@ -2,18 +2,10 @@ require 'pg' -# This class is a thin "wrapper" around the -# PG library. We'll use it in our project to interact -# with the database using SQL. - class DatabaseConnection - # This method connects to PostgreSQL using the - # PG gem. We connect to 127.0.0.1, and select - # the database name given in argument. -# file: lib/database_connection.rb + def self.connect - # If the environment variable (set by Render) - # is present, use this to open the connection. + if ENV['DATABASE_URL'] != nil @connection = PG.connect(ENV['DATABASE_URL']) return @@ -27,9 +19,6 @@ def self.connect @connection = PG.connect({ host: '127.0.0.1', dbname: database_name }) end - # This method executes an SQL query - # on the database, providing some optional parameters - # (you will learn a bit later about when to provide these parameters). def self.exec_params(query, params) if @connection.nil? raise 'DatabaseConnection.exec_params: Cannot run a SQL query as the connection to'\ From 94fb6252c70eb0553fae79a24aa6e40127cff34a Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Mon, 10 Apr 2023 18:42:51 +0100 Subject: [PATCH 38/56] add an argument --- lib/database_connection.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/database_connection.rb b/lib/database_connection.rb index d168a54e55..bb3c976a45 100644 --- a/lib/database_connection.rb +++ b/lib/database_connection.rb @@ -4,8 +4,7 @@ class DatabaseConnection - def self.connect - + def self.connect(database_name) if ENV['DATABASE_URL'] != nil @connection = PG.connect(ENV['DATABASE_URL']) return From ba54fd746b1d4d708f87d57c53161d9cd81d8100 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 17:28:42 +0100 Subject: [PATCH 39/56] Updating README.md --- README.md | 46 ++++++++-------------------------------------- 1 file changed, 8 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 465eda879b..03752d075d 100644 --- a/README.md +++ b/README.md @@ -6,51 +6,21 @@ Chitter Challenge * If you have a partial solution, **still check in a partial solution** * You must submit a pull request to this repo with your code by 10am Monday morning -Challenge: +Description: ------- -As usual please start by forking this repo. +This project is designed to mimic the popular 'Twitter' app for Makers student use. Chitter will have basic functionality like: creating peeps, viewing peeps (including the time of peep in chronological order), as well as login, sign-up and logout capabilities. -We are going to write a small Twitter clone that will allow the users to post messages to a public stream. +The user should have visibility to the login and register links when they are not logged in and similarly only have visibility to the sign-out link when they are logged in, to give a positive user experience. Features: ------- -``` -STRAIGHT UP - -As a Maker -So that I can let people know what I am doing -I want to post a message (peep) to chitter - -As a maker -So that I can see what others are saying -I want to see all peeps in reverse chronological order - -As a Maker -So that I can better appreciate the context of a peep -I want to see the time at which it was made - -As a Maker -So that I can post messages on Chitter as me -I want to sign up for Chitter - -HARDER - -As a Maker -So that only I can post messages on Chitter as me -I want to log in to Chitter - -As a Maker -So that I can avoid others posting messages on Chitter as me -I want to log out of Chitter - -ADVANCED - -As a Maker -So that I can stay constantly tapped in to the shouty box of Chitter -I want to receive an email if I am tagged in a Peep -``` +* Register: User can register to Chitter with their email and create an account with a username and password. +* Login: User can login to their account from the homepage by entering their email address and password. +* Logout: User can logout from the homepage by clicking on the logout link. +* New Peep: Logged in user can have the option to create a new peep by clicking the new peep link on the homepage, where they are directed to the /new_peep page and can submit a peep +* View Peeps: Irrespective of logged in status, peeps will be shown on the homepage in order of the most recent peep first. The peep contents and time are shown on the homepage. Technical Approach: ----- From 0141dd45d027c7b47fa6f604b56d5618ce8770ae Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 17:29:31 +0100 Subject: [PATCH 40/56] update Readme --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index 03752d075d..41e105d4b3 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,6 @@ Chitter Challenge ================= -* Feel free to use Google, your notes, books, etc. but work on your own -* If you refer to the solution of another coach or student, please put a link to that in your README -* If you have a partial solution, **still check in a partial solution** -* You must submit a pull request to this repo with your code by 10am Monday morning - Description: ------- From 8b3938ebbd9bcfaeb7b41f7f0238a401d8503ce0 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:04:21 +0100 Subject: [PATCH 41/56] readme --- README.md | 74 +++++++++---------------------------------------------- 1 file changed, 12 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 41e105d4b3..1dc6b93355 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ -Chitter Challenge -================= +# _Chitter Challenge_ + +#### By _**{Sidra Iqbal, adapted from Makers Academy}**_ + +Technologies Used +----- + +* Ruby +* CSS +* HTML +* Postgresql +* Sinatra Description: ------- @@ -17,22 +27,6 @@ Features: * New Peep: Logged in user can have the option to create a new peep by clicking the new peep link on the homepage, where they are directed to the /new_peep page and can submit a peep * View Peeps: Irrespective of logged in status, peeps will be shown on the homepage in order of the most recent peep first. The peep contents and time are shown on the homepage. -Technical Approach: ------ - -In the last two weeks, you integrated a database using the `pg` gem and Repository classes. You also implemented small web applications using Sinatra, RSpec, HTML and ERB views to make dynamic webpages. You can continue to use this approach when building Chitter Challenge. - -You can refer to the [guidance on Modelling and Planning a web application](https://github.com/makersacademy/web-applications/blob/main/pills/modelling_and_planning_web_application.md), to help you in planning the different web pages you will need to implement this challenge. If you'd like to deploy your app to Heroku so other people can use it, [you can follow this guidance](https://github.com/makersacademy/web-applications/blob/main/html_challenges/07_deploying.md). - -If you'd like more technical challenge now, try using an [Object Relational Mapper](https://en.wikipedia.org/wiki/Object-relational_mapping) as the database interface, instead of implementing your own Repository classes. - -Some useful resources: -**Ruby Object Mapper** -- [ROM](https://rom-rb.org/) - -**ActiveRecord** -- [ActiveRecord ORM](https://guides.rubyonrails.org/active_record_basics.html) -- [Sinatra & ActiveRecord setup](https://learn.co/lessons/sinatra-activerecord-setup) Notes on functionality: ------ @@ -42,47 +36,3 @@ Notes on functionality: * The username and email are unique. * Peeps (posts to chitter) have the name of the maker and their user handle. * Your README should indicate the technologies used, and give instructions on how to install and run the tests. - -Bonus: ------ - -If you have time you can implement the following: - -* In order to start a conversation as a maker I want to reply to a peep from another maker. - -And/Or: - -* Work on the CSS to make it look good. - -Good luck and let the chitter begin! - -Code Review ------------ - -In code review we'll be hoping to see: - -* All tests passing -* High [Test coverage](https://github.com/makersacademy/course/blob/main/pills/test_coverage.md) (>95% is good) -* The code is elegant: every class has a clear responsibility, methods are short etc. - -Reviewers will potentially be using this [code review rubric](docs/review.md). Referring to this rubric in advance may make the challenge somewhat easier. You should be the judge of how much challenge you want at this moment. - -Notes on test coverage ----------------------- - -Please ensure you have the following **AT THE TOP** of your spec_helper.rb in order to have test coverage stats generated -on your pull request: - -```ruby -require 'simplecov' -require 'simplecov-console' - -SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new([ - SimpleCov::Formatter::Console, - # Want a nice code coverage website? Uncomment this next line! - # SimpleCov::Formatter::HTMLFormatter -]) -SimpleCov.start -``` - -You can see your test coverage when you run your tests. If you want this in a graphical form, uncomment the `HTMLFormatter` line and see what happens! From ce97f530503f925aa4b80aaddd0ff786bd1a7da6 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:20:08 +0100 Subject: [PATCH 42/56] readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1dc6b93355..c4383952ad 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # _Chitter Challenge_ -#### By _**{Sidra Iqbal, adapted from Makers Academy}**_ +#### By _**Sidra Iqbal, adapted from Makers Academy**_ Technologies Used ----- From 52cd43921e2e75ee7c474803dcf5fec791ffd2af Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:34:12 +0100 Subject: [PATCH 43/56] readme --- README.md | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c4383952ad..9d569a3680 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,6 @@ Features: * New Peep: Logged in user can have the option to create a new peep by clicking the new peep link on the homepage, where they are directed to the /new_peep page and can submit a peep * View Peeps: Irrespective of logged in status, peeps will be shown on the homepage in order of the most recent peep first. The peep contents and time are shown on the homepage. - Notes on functionality: ------ @@ -36,3 +35,16 @@ Notes on functionality: * The username and email are unique. * Peeps (posts to chitter) have the name of the maker and their user handle. * Your README should indicate the technologies used, and give instructions on how to install and run the tests. + +Dependencies +------ + +Ruby Gems: +```ruby +gem "sinatra", "~> 3.0" +gem "sinatra-contrib", "~> 3.0" +gem "webrick", "~> 1.8" +gem "rack-test", "~> 2.1" +gem 'bcrypt', '~> 3.1.7' +gem "pg", "~> 1.4" +``` \ No newline at end of file From d528711aece16c337dd26ba66e7e755f73c65014 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:35:05 +0100 Subject: [PATCH 44/56] readme --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 9d569a3680..d0f06292d0 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,6 @@ Notes on functionality: * Makers sign up to chitter with their email, password, name and a username (e.g. samm@makersacademy.com, password123, Sam Morgan, sjmog). * The username and email are unique. * Peeps (posts to chitter) have the name of the maker and their user handle. -* Your README should indicate the technologies used, and give instructions on how to install and run the tests. Dependencies ------ From 944ff847e54df5d1fce451e4eee166d581095c19 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:36:30 +0100 Subject: [PATCH 45/56] README --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index d0f06292d0..87e5811337 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,10 @@ gem "webrick", "~> 1.8" gem "rack-test", "~> 2.1" gem 'bcrypt', '~> 3.1.7' gem "pg", "~> 1.4" +``` +Testing: +```ruby +gem 'rspec' +gem 'simplecov', require: false +gem 'simplecov-console', require: false ``` \ No newline at end of file From 859e3791f46e759a438f566f46fc60be10c602b2 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:44:14 +0100 Subject: [PATCH 46/56] README --- README.md | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 87e5811337..5ff9e9a1a1 100644 --- a/README.md +++ b/README.md @@ -35,21 +35,22 @@ Notes on functionality: * The username and email are unique. * Peeps (posts to chitter) have the name of the maker and their user handle. -Dependencies +Installation & Requirements ------ -Ruby Gems: -```ruby -gem "sinatra", "~> 3.0" -gem "sinatra-contrib", "~> 3.0" -gem "webrick", "~> 1.8" -gem "rack-test", "~> 2.1" -gem 'bcrypt', '~> 3.1.7' -gem "pg", "~> 1.4" -``` +Clone the repo and add $ gems: + +$ git clone https://github.com/siqbal181/chitter-challenge.git +$ gem "sinatra", "~> 3.0" +$ gem "sinatra-contrib", "~> 3.0" +$ gem "webrick", "~> 1.8" +$ gem "rack-test", "~> 2.1" +$ gem 'bcrypt', '~> 3.1.7' +$ gem "pg", "~> 1.4" + Testing: ```ruby -gem 'rspec' -gem 'simplecov', require: false -gem 'simplecov-console', require: false +$ gem 'rspec' +$ gem 'simplecov', require: false +$ gem 'simplecov-console', require: false ``` \ No newline at end of file From dc63846aae79b274f4976de8e507ffb88204efdf Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:47:11 +0100 Subject: [PATCH 47/56] README --- README.md | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5ff9e9a1a1..b9d0b91c64 100644 --- a/README.md +++ b/README.md @@ -41,16 +41,18 @@ Installation & Requirements Clone the repo and add $ gems: $ git clone https://github.com/siqbal181/chitter-challenge.git -$ gem "sinatra", "~> 3.0" -$ gem "sinatra-contrib", "~> 3.0" -$ gem "webrick", "~> 1.8" -$ gem "rack-test", "~> 2.1" -$ gem 'bcrypt', '~> 3.1.7' -$ gem "pg", "~> 1.4" +$ gem install sinatra -v '~> 3.0' +$ gem install sinatra-contrib -v '~> 3.0' +$ gem install webrick -v '~> 1.8' +$ gem install rack-test -v '~> 2.1' +$ gem install bcrypt -v '~> 3.1.7' +$ gem install pg -v '~> 1.4' Testing: ```ruby $ gem 'rspec' $ gem 'simplecov', require: false $ gem 'simplecov-console', require: false -``` \ No newline at end of file +``` + + From f4ad071c4d5ac98a4bc07a4fa58367eb0dde4a1f Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:48:24 +0100 Subject: [PATCH 48/56] README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b9d0b91c64..31fce13bca 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Installation & Requirements Clone the repo and add $ gems: +``` $ git clone https://github.com/siqbal181/chitter-challenge.git $ gem install sinatra -v '~> 3.0' $ gem install sinatra-contrib -v '~> 3.0' @@ -47,6 +48,7 @@ $ gem install webrick -v '~> 1.8' $ gem install rack-test -v '~> 2.1' $ gem install bcrypt -v '~> 3.1.7' $ gem install pg -v '~> 1.4' +``` Testing: ```ruby From 5d7f9697e62ff6af14b9efc2a3da6d16cfb31980 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:55:36 +0100 Subject: [PATCH 49/56] README --- README.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 31fce13bca..c259130384 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Notes on functionality: Installation & Requirements ------ -Clone the repo and add $ gems: +Clone the repo and add the relevant gems: ``` $ git clone https://github.com/siqbal181/chitter-challenge.git @@ -57,4 +57,10 @@ $ gem 'simplecov', require: false $ gem 'simplecov-console', require: false ``` +## Contact +Sidra Iqbal + +Project Link: [https://github.com/siqbal181/chitter-challenge](https://github.com/siqbal181/chitter-challenge) + +

    (back to top)

    From 77ed7ea297985909d90a3adf8e3797d3dd6c6b1f Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 18:57:34 +0100 Subject: [PATCH 50/56] README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c259130384..6b619b17ef 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,8 @@ This project is designed to mimic the popular 'Twitter' app for Makers student u The user should have visibility to the login and register links when they are not logged in and similarly only have visibility to the sign-out link when they are logged in, to give a positive user experience. +[Link to My Deployed App](https://chitter-app-59gf.onrender.com/) + Features: ------- From 88ebaa226b57f1e07d92b8a14404d929fb6564ac Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 22:51:41 +0100 Subject: [PATCH 51/56] README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 6b619b17ef..9aad520de4 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ + + # _Chitter Challenge_ #### By _**Sidra Iqbal, adapted from Makers Academy**_ From 6701c63c438667e75b2d5400f4f382b2bcc59bd5 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 22:59:49 +0100 Subject: [PATCH 52/56] Add image --- README.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9aad520de4..3624c53a3a 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,9 @@ The user should have visibility to the login and register links when they are no [Link to My Deployed App](https://chitter-app-59gf.onrender.com/) +![Screenshot of main page](https://imgur.com/a/EFue0NV) + + Features: ------- @@ -45,20 +48,20 @@ Installation & Requirements Clone the repo and add the relevant gems: ``` -$ git clone https://github.com/siqbal181/chitter-challenge.git -$ gem install sinatra -v '~> 3.0' -$ gem install sinatra-contrib -v '~> 3.0' -$ gem install webrick -v '~> 1.8' -$ gem install rack-test -v '~> 2.1' -$ gem install bcrypt -v '~> 3.1.7' -$ gem install pg -v '~> 1.4' +git clone https://github.com/siqbal181/chitter-challenge.git +gem install sinatra -v '~> 3.0' +gem install sinatra-contrib -v '~> 3.0' +gem install webrick -v '~> 1.8' +gem install rack-test -v '~> 2.1' +gem install bcrypt -v '~> 3.1.7' +gem install pg -v '~> 1.4' ``` Testing: ```ruby -$ gem 'rspec' -$ gem 'simplecov', require: false -$ gem 'simplecov-console', require: false +gem 'rspec' +gem 'simplecov', require: false +gem 'simplecov-console', require: false ``` ## Contact From ac6ffebbfa4838ba30eb13d47d890cf2eec71065 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 23:02:45 +0100 Subject: [PATCH 53/56] Add image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3624c53a3a..3561ce9723 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ The user should have visibility to the login and register links when they are no [Link to My Deployed App](https://chitter-app-59gf.onrender.com/) -![Screenshot of main page](https://imgur.com/a/EFue0NV) +![Screenshot of main page](https://i.imgur.com/g3bzkKR.png) Features: From c37b463a6fe8089f7d044a46a60049aaffd42269 Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 23:04:45 +0100 Subject: [PATCH 54/56] Add image --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 3561ce9723..65fa756631 100644 --- a/README.md +++ b/README.md @@ -20,9 +20,7 @@ This project is designed to mimic the popular 'Twitter' app for Makers student u The user should have visibility to the login and register links when they are not logged in and similarly only have visibility to the sign-out link when they are logged in, to give a positive user experience. -[Link to My Deployed App](https://chitter-app-59gf.onrender.com/) - -![Screenshot of main page](https://i.imgur.com/g3bzkKR.png) +[![Screenshot of main page](https://i.imgur.com/g3bzkKR.png)](https://chitter-app-59gf.onrender.com/) Features: From d6afa48aa9409928aa33d76e1881c8b595eb6d9a Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 23:05:35 +0100 Subject: [PATCH 55/56] Add image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 65fa756631..1ad98b6cf3 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This project is designed to mimic the popular 'Twitter' app for Makers student u The user should have visibility to the login and register links when they are not logged in and similarly only have visibility to the sign-out link when they are logged in, to give a positive user experience. -[![Screenshot of main page](https://i.imgur.com/g3bzkKR.png)](https://chitter-app-59gf.onrender.com/) +[![Screenshot of main page](https://i.imgur.com/g3bzkKR.png)](https://chitter-app-59gf.onrender.com/){:target="_blank"} Features: From 627b4d12ec7f8ba556994132c78505669216b7aa Mon Sep 17 00:00:00 2001 From: Sidra Iqbal Date: Tue, 11 Apr 2023 23:06:39 +0100 Subject: [PATCH 56/56] Add image --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1ad98b6cf3..65fa756631 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ This project is designed to mimic the popular 'Twitter' app for Makers student u The user should have visibility to the login and register links when they are not logged in and similarly only have visibility to the sign-out link when they are logged in, to give a positive user experience. -[![Screenshot of main page](https://i.imgur.com/g3bzkKR.png)](https://chitter-app-59gf.onrender.com/){:target="_blank"} +[![Screenshot of main page](https://i.imgur.com/g3bzkKR.png)](https://chitter-app-59gf.onrender.com/) Features: