diff --git a/Gemfile.lock b/Gemfile.lock index 7d4eb449..21826b1e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -18,6 +18,8 @@ GEM mini_mime (1.1.1) mustermann (1.1.1) ruby2_keywords (~> 0.0.1) + nokogiri (1.12.3-arm64-darwin) + racc (~> 1.4) nokogiri (1.12.3-x86_64-darwin) racc (~> 1.4) parallel (1.20.1) @@ -83,6 +85,7 @@ GEM nokogiri (~> 1.8) PLATFORMS + arm64-darwin-21 x86_64-darwin-20 DEPENDENCIES diff --git a/README.md b/README.md index f9638b66..8c3b7a1c 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ ## Chitter Challenge -* Challenge time: until the end of the day -* Feel free to use google, your notes, books etc but please work on your own -* Please raise a pull request when you start this challenge, and keep pushing updates as and when you make commits throughout the day -* There is _no expectation_ to finish all or any of the user stories, please use this time to reflect on where you feel you are with the skill and what may support your learning. -* If you get blocked, please reflect on what blocked you and any strategies you adopted that helped you make progress. +- Challenge time: until the end of the day +- Feel free to use google, your notes, books etc but please work on your own +- Please raise a pull request when you start this challenge, and keep pushing updates as and when you make commits throughout the day +- There is _no expectation_ to finish all or any of the user stories, please use this time to reflect on where you feel you are with the skill and what may support your learning. +- If you get blocked, please reflect on what blocked you and any strategies you adopted that helped you make progress. We are going to write a small Twitter clone that will allow the users to post messages to a public stream. @@ -12,23 +12,24 @@ We are going to write a small Twitter clone that will allow the users to post me To setup the database: -* Connect to psql -* Create the database using the psql command `CREATE DATABASE chitter;` -* Connect to the database using the psql command `\c chitter`; -* Run the query we have saved in the file 01_create_chitter_table.sql -* Populate your table with a row by running `INSERT INTO peeps (message) values ('This is a peep!');` +- Connect to psql +- Create the database using the psql command `CREATE DATABASE chitter;` +- Connect to the database using the psql command `\c chitter`; +- Run the query we have saved in the file 01_create_chitter_table.sql +- Populate your table with a row by running `INSERT INTO peeps (message) values ('This is a peep!');` -To check you have everything set up ok, please take a look at the peeps table inside the chitter database. You should see one row in there. +To check you have everything set up ok, please take a look at the peeps table inside the chitter database. You should see one row in there. To setup the test database: -* Connect to psql -* Create the database using the psql -command `CREATE DATABASE chitter_test;`; -* Connect to the database using the psql command `\c chitter_test` -* Run the query we have saved in the file 01_create_chitter_table.sql -* `bundle install` -* `rspec` +- Connect to psql +- Create the database using the psql + command `CREATE DATABASE chitter_test;`; +- Connect to the database using the psql command `\c chitter_test` +- Run the query we have saved in the file 01_create_chitter_table.sql + +- `bundle install` +- `rspec` You should see 1 passing test. @@ -39,12 +40,25 @@ As a Maker So that I can see what people are doing I want to see all the messages (peeps) in a browser + + +| Component | Responsibility | Refactor | +| ---------- | ------------------------------------------- | --------------------------------- | +| Model | Encapsulate logic with relevant data | Encapsulate peep data in a class | +| View | Display the result to a user | Show the peep data in a list | +| Controller | Get data from the model and put in the view | Render peep data into to the view | ``` ``` As a Maker -So that I can let people know what I am doing +So that I can let people know what I am doing I want to post a message (peep) to chitter + +- Adding a new message - /peeps/new +- Typing a message into a form on that page +- Submitting that form +- Seeing the message just submitted + ``` ``` @@ -52,6 +66,7 @@ As a Maker So that I can see when people are doing things I want to see the date the message was posted ``` + (Hint the database table will need to change to store the date too) ``` @@ -59,8 +74,73 @@ As a Maker So that I can easily see the latest peeps I want to see a list of peeps in reverse chronological order ``` + ``` As a Maker So that I can find relevant peeps I want to filter on a specific keyword ``` + +# Hannah's Chitter Challenge + +Brief description of what the project is + +## Getting started + +`git clone path-to-your-repo` + +- list gems in the Gemfile: + source 'https://rubygems.org' + +ruby '3.0.2' + +gem 'pg' +gem 'sinatra' + +group :test do +gem 'capybara' +gem 'rspec' +gem 'simplecov', require: false +gem 'simplecov-console', require: false +end + +group :development, :test do +gem 'rubocop', '1.20' +end + +- bundle install +- rspec --init +- setup basic Sinatra app in app.rb (Root directory) + +# in app.rb + +require 'sinatra/base' +require 'sinatra/reloader' + +class Chitter < Sinatra::Base +configure :development do +register Sinatra::Reloader +end + +get '/' do +'Hello World' +end + +run! if app_file == $0 +end + +- configure 'rackup' command to run the app in app.rb via config.ru file + +# in config.ru + +require_relative "./app" + +run Chitter + +## Usage + +- ruby app.rb => Navigate to `http://localhost:4567/` + +## Running tests + +- rspec diff --git a/app.rb b/app.rb index 2450fb92..349d792a 100644 --- a/app.rb +++ b/app.rb @@ -1,8 +1,34 @@ require 'sinatra/base' +# require 'sinatra/reloader' +require './lib/peep' class Chitter < Sinatra::Base - get '/test' do - 'Test page' + # configure :development do + # register Sinatra::Reloader + # end + + # get '/' do + # 'Hello World' + # end + + get '/peeps' do + # p ENV + p @peeps = Peep.all + erb :index + end + + get '/peeps/new' do + erb :new + end + + post '/peeps' do + # p params + # p "Form data submitted to the /peeps route!" + # message = params['message'] + # connection = PG.connect(dbname: 'chitter_test') + # connection.exec("INSERT INTO peeps (message) VALUES('#{message}')") + Peep.create(message: params[:message], username: params[:username]) + redirect '/peeps' end run! if app_file == $0 diff --git a/db/migrations/02_add_username_to_peeps.sql b/db/migrations/02_add_username_to_peeps.sql new file mode 100644 index 00000000..5e2cce0f --- /dev/null +++ b/db/migrations/02_add_username_to_peeps.sql @@ -0,0 +1 @@ +ALTER TABLE peeps ADD COLUMN username VARCHAR(60); \ No newline at end of file diff --git a/lib/peep.rb b/lib/peep.rb new file mode 100644 index 00000000..bc16b601 --- /dev/null +++ b/lib/peep.rb @@ -0,0 +1,42 @@ +require 'pg' + +class Peep + attr_reader :id, :username, :message + + def initialize(id:, username:, message:) + @id = id + @username = username + @message = message + end + + def self.all + if ENV['ENVIRONMENT'] == 'test' + connection = PG.connect(dbname: 'chitter_test') + else + connection = PG.connect(dbname: 'chitter') + end + + result = connection.exec("SELECT * FROM peeps;") + result.map do + Peep.new(id: result[0]['id'], username: result[0]['username'], message: result[0]['message']) + end + end + + def self.create(username:, message:) + if ENV['ENVIRONMENT'] == 'test' + connection = PG.connect(dbname: 'chitter_test') + else + connection = PG.connect(dbname: 'chitter') + end + + # I've broken it on to two lines to make it a bit more readable + result = connection.exec_params( + # The first argument is our SQL query template + # The second argument is the 'params' referred to in exec_params + # $1 refers to the first item in the params array + # $2 refers to the second item in the params array + "INSERT INTO peeps (username, message) VALUES($1, $2) RETURNING id, username, message;", [username, message] + ) + Peep.new(id: result[0]['id'], username: result[0]['username'], message: result[0]['message']) + end +end diff --git a/spec/database_helpers.rb b/spec/database_helpers.rb new file mode 100644 index 00000000..a14472a3 --- /dev/null +++ b/spec/database_helpers.rb @@ -0,0 +1,8 @@ +# in spec/database_helpers.rb +require 'pg' + +def persisted_data(id:) + connection = PG.connect(dbname: 'chitter_test') + result = connection.query("SELECT * FROM peeps WHERE id = #{id};") + result.first +end diff --git a/spec/features/creating_peeps_spec.rb b/spec/features/creating_peeps_spec.rb new file mode 100644 index 00000000..a62b7cdd --- /dev/null +++ b/spec/features/creating_peeps_spec.rb @@ -0,0 +1,12 @@ +# in spec/features/creating_peeps_spec.rb + +feature 'Adding a new peep' do + scenario 'A user can add a peep to Chitter' do + visit('/peeps/new') + fill_in('username', with: 'Username') + fill_in('message', with: 'An example of a peep') + click_button('Submit') + + expect(page).to have_content 'Username, An example of a peep' + end +end diff --git a/spec/features/test_page_spec.rb b/spec/features/test_page_spec.rb index b65ac196..a90d7a81 100644 --- a/spec/features/test_page_spec.rb +++ b/spec/features/test_page_spec.rb @@ -1,6 +1,6 @@ -feature 'Viewing test page' do - scenario 'visiting the test page' do - visit('/test') - expect(page).to have_content "Test page" - end -end +# feature 'Viewing test page' do +# scenario 'visiting the test page' do +# visit('/') +# expect(page).to have_content "Hello World" +# end +# end diff --git a/spec/features/viewing_peeps_spec.rb b/spec/features/viewing_peeps_spec.rb new file mode 100644 index 00000000..7bef4610 --- /dev/null +++ b/spec/features/viewing_peeps_spec.rb @@ -0,0 +1,18 @@ +feature 'Viewing peeps' do + scenario 'A user can see peeps' do + # connection = PG.connect(dbname: 'chitter_test') + + # # Add the test data + # connection.exec("INSERT INTO peeps VALUES(1, 'This is a peep!');") + + # Peep.create(username: 'User1', message: 'This is a peep!') + # Peep.create(username: 'User2', message: 'Here is another peep!') + Peep.create(username: 'User3', message: 'One more peep!') + + visit('/peeps') + + # expect(page).to have_content("User1, This is a peep!") + # expect(page).to have_content("User2, Here is another peep!") + expect(page).to have_content("User3, One more peep!") + end +end diff --git a/spec/peep_spec.rb b/spec/peep_spec.rb new file mode 100644 index 00000000..4a0a8eb1 --- /dev/null +++ b/spec/peep_spec.rb @@ -0,0 +1,44 @@ +require 'peep' +require 'database_helpers' + +# describe Peep do +# describe '.all' do +# it 'returns all peeps' do +# peep = Peep.all + +# expect(peep).to include("This is a peep!") +# end +# end +# end + +describe '.all' do + it 'returns a list of peeps' do + connection = PG.connect(dbname: 'chitter_test') + + # Add the test data + peep = Peep.create(username: "User1", message: "This is a peep!") + Peep.create(username: "User2", message: "Here is another peep!") + Peep.create(username: "User3", message: "One more peep!") + + peeps = Peep.all + + expect(peeps.length).to eq 3 + expect(peeps.first).to be_a Peep + expect(peeps.first.id).to eq peep.id + expect(peeps.first.username).to eq 'User1' + expect(peeps.first.message).to eq 'This is a peep!' + end +end + +describe '.create' do + it 'creates a new peep message' do + peep = Peep.create(username: 'Username', message: 'An example of a peep') + + persisted_data = persisted_data(id: peep.id) + + expect(peep).to be_a Peep + expect(peep.id).to eq persisted_data['id'] + expect(peep.username).to eq 'Username' + expect(peep.message).to eq 'An example of a peep' + end +end diff --git a/spec/setup_test_database.rb b/spec/setup_test_database.rb index af832f7d..55fbee96 100644 --- a/spec/setup_test_database.rb +++ b/spec/setup_test_database.rb @@ -1,7 +1,9 @@ require 'pg' def setup_test_database + p "Setting up test database..." connection = PG.connect(dbname: 'chitter_test') + # Clear the peeps table connection.exec("TRUNCATE peeps;") end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 74046cad..ccd83686 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -29,9 +29,10 @@ ]) SimpleCov.start -ENV['RACK_ENV'] = 'test' +# ENV['RACK_ENV'] = 'test' ENV['ENVIRONMENT'] = 'test' + # Bring in the contents of the `app.rb` file. The below is equivalent to: require_relative '../app.rb' require File.join(File.dirname(__FILE__), '..', 'app.rb') diff --git a/views/index.erb b/views/index.erb new file mode 100644 index 00000000..638a2c57 --- /dev/null +++ b/views/index.erb @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/views/new.erb b/views/new.erb new file mode 100644 index 00000000..47242837 --- /dev/null +++ b/views/new.erb @@ -0,0 +1,5 @@ +
+ + + +
\ No newline at end of file