Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial Solution to Chitter Challenge #1230

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ source 'https://rubygems.org'

ruby '2.5.0'

gem 'sinatra'
gem 'capybara'
gem 'rake'
gem 'pg'
gem 'rubocop', '0.56.0'

group :test do
Expand Down
36 changes: 35 additions & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
GEM
remote: https://rubygems.org/
specs:
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
ansi (1.5.0)
ast (2.4.0)
capybara (3.20.2)
addressable
mini_mime (>= 0.1.3)
nokogiri (~> 1.8)
rack (>= 1.6.0)
rack-test (>= 0.6.3)
regexp_parser (~> 1.2)
xpath (~> 3.2)
diff-lcs (1.3)
docile (1.1.5)
hirb (0.7.3)
json (2.1.0)
mini_mime (1.0.1)
mini_portile2 (2.4.0)
mustermann (1.0.3)
nokogiri (1.10.3)
mini_portile2 (~> 2.4.0)
parallel (1.12.1)
parser (2.5.1.0)
ast (~> 2.4.0)
pg (1.1.4)
powerpack (0.1.1)
public_suffix (3.0.3)
rack (2.0.7)
rack-protection (2.0.5)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rainbow (3.0.0)
rake (12.3.0)
regexp_parser (1.5.1)
rspec (3.7.0)
rspec-core (~> 3.7.0)
rspec-expectations (~> 3.7.0)
Expand Down Expand Up @@ -43,20 +66,31 @@ GEM
hirb
simplecov
simplecov-html (0.10.2)
sinatra (2.0.5)
mustermann (~> 1.0)
rack (~> 2.0)
rack-protection (= 2.0.5)
tilt (~> 2.0)
tilt (2.0.9)
unicode-display_width (1.3.2)
xpath (3.2.0)
nokogiri (~> 1.8)

PLATFORMS
ruby

DEPENDENCIES
capybara
pg
rake
rspec
rubocop (= 0.56.0)
simplecov
simplecov-console
sinatra

RUBY VERSION
ruby 2.5.0p0

BUNDLED WITH
1.16.1
1.16.6
39 changes: 39 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,42 @@
# My Approach

I have began this challenge by mapping out in an MVC diagram how the app will work, and how the app will flow for the user when logging in, signing up, posting messages and viewing their feed. I have also tried to map out how each method within the classes will work. This diagram is below:

INSERT DIAGRAM HERE

Sadly I ran out of time and only managed to get through the first four user stories:

```
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
```

Following on from the diagram I did to map out how the app will work, I then wrote a feature test for the first user story above. I did the simplest thing to make this pass, then I worked on adding classes to make the functionality correct, implementing unit tests first and then writing the code to make these tests pass.

If I had more time next I would have implemented a log in/log out feature on the homepage using the user class.

## Instructions for Use
* Clone this repo from github
* Run 'bundle install' in the command line
* Open 'psql postgres' in the command line
* Run the two commands saved in 'db/migrations' to create the tables
* Run 'rackup' in the command line
* Go to 'localhost:9292' and follow the instructions to sign up and create peeps.


Chitter Challenge
=================

Expand Down
29 changes: 29 additions & 0 deletions app.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
require 'sinatra/base'
require './lib/user'
require './lib/peep'

class ChitterChallenge < Sinatra::Base
enable :sessions

get '/' do
erb :index
end

post '/chitter' do
user = User.create(name: params[:name], username: params[:username], email: params[:email], password: params[:password])
@user = user.username
redirect '/chitter'
end

get '/chitter' do
@peeps = Peep.all
erb :chitter
end

post '/chitter/new' do
Peep.create(message: params[:message])
redirect '/chitter'
end

run! if app_file == $0
end
3 changes: 3 additions & 0 deletions config.ru
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
require_relative "./app"

run ChitterChallenge
1 change: 1 addition & 0 deletions db/migrations/01_create_users_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE TABLE users(id SERIAL PRIMARY KEY, name, username, email, password VARCHAR(60));
1 change: 1 addition & 0 deletions db/migrations/02_create_peeps_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE TABLE peeps(id SERIAL PRIMARY KEY, message, sent_time VARCHAR(200) NOT NULL);
37 changes: 37 additions & 0 deletions lib/peep.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
class Peep
attr_reader :id, :message, :sent_time

def initialize(id:, message:, sent_time:)
@id = id
@message = message
@sent_time = sent_time
end

def self.all
if ENV['ENVIRONMENT'] == 'test'
connection = PG.connect(dbname: 'chitter_test')
else
connection = PG.connect(dbname: 'chitter')
end
peeps = connection.exec("SELECT * FROM peeps ORDER BY sent_time DESC;")
peeps.map { |peep| to_peep(peep) }
end

def self.create(message:)
if ENV['ENVIRONMENT'] == 'test'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can refactor these into separate files so you DRY out the connections.

connection = PG.connect(dbname: 'chitter_test')
else
connection = PG.connect(dbname: 'chitter')
end

peep = connection.exec("INSERT INTO peeps (message, sent_time) VALUES('#{message}', '#{Time.now}') RETURNING id, message, sent_time;").first

to_peep(peep)
end

def self.to_peep(peep_record)
Peep.new(id: peep_record["id"], \
message: peep_record["message"], \
sent_time: Time.parse(peep_record["sent_time"]))
end
end
24 changes: 24 additions & 0 deletions lib/user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
require 'pg'

class User
attr_reader :id, :name, :username, :email, :password

def initialize(id:, name:, username:, email:, password:)
@id = id
@name = name
@username = username
@email = email
@password = password
end


def self.create(name:, username:, email:, password:)
if ENV['ENVIRONMENT'] == 'test'
connection = PG.connect(dbname: 'chitter_test')
else
connection = PG.connect(dbname: 'chitter')
end
result = connection.exec("INSERT INTO users (name, username, email, password) VALUES('#{name}', '#{username}', '#{email}', '#{password}')RETURNING id, name, username, email, password")
User.new(id: result[0]['id'], name: result[0]['name'], username: result[0]['username'], email: result[0]['email'], password: result[0]['password'])
end
end
8 changes: 8 additions & 0 deletions spec/features/posting_peeps_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
feature "posting a peep" do
scenario "it allows the user to post a peep" do
visit '/chitter'
fill_in 'peep', with: 'First peep'
click_button 'Peep!'
expect(page).to have_content("First peep")
end
end
11 changes: 11 additions & 0 deletions spec/features/signup_feature_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
feature "signing up" do
scenario "the homepage has a sign up feature" do
visit '/'
fill_in('name', with: "Mo Salah")
fill_in('username', with: "champsleagueisours2k19")
fill_in('email', with: "[email protected]")
fill_in('password', with: "ilovelfc")
click_button('Sign up!')
expect(page).to have_content "You are now signed in to Chitter"
end
end
16 changes: 16 additions & 0 deletions spec/features/viewing_peeps_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
feature "viewing peeps" do
scenario "it allows you to view a list of peeps" do
peep_1 = Peep.create(message: "First peep")
peep_2 = Peep.create(message: "Second peep")
peep_3 = Peep.create(message: "Third peep")

visit '/chitter'

expect(page).to have_content("Third peep")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There might be a way to test if this is the first element on the web page. This would test if the peeps are in reverse order with most recent first. Something like, expect(first('.box')).to have_content("Third peep)

expect(page).to have_content("#{peep_3.sent_time}")
expect(page).to have_content("Second peep")
expect(page).to have_content("#{peep_2.sent_time}")
expect(page).to have_content("First peep")
expect(page).to have_content("#{peep_1.sent_time}")
end
end
15 changes: 15 additions & 0 deletions spec/peep_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
require 'peep'

describe Peep do
let(:time_now) { Time.parse(Time.now.strftime("%Y-%m-%d %H:%M:%S :z")) }

describe '#new' do
it 'creates a peep with id, message and time' do
peep = Peep.new(id: 1, message: "New peep", sent_time: time_now)

expect(peep.id).to eq(1)
expect(peep.message).to eq("New peep")
expect(peep.sent_time).to eq(time_now)
end
end
end
11 changes: 11 additions & 0 deletions spec/setup_test_database.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
require 'pg'

def setup_test_database
p "Setting up test database..."

connection = PG.connect(dbname: 'chitter_test')

# Clear the bookmarks table
connection.exec("TRUNCATE users;")
connection.exec("TRUNCATE peeps;")
end
21 changes: 21 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
require_relative './setup_test_database'

ENV['ENVIRONMENT'] = 'test'

RSpec.configure do |config|
config.before(:each) do
setup_test_database
end
end

# Bring in the contents of the `app.rb` file
require File.join(File.dirname(__FILE__), '..', 'app.rb')

# Require all the testing gems
require 'capybara'
require 'capybara/rspec'
require 'rspec'

# Tell Capybara to talk to BookmarkManager
Capybara.app = ChitterChallenge

require 'simplecov'
require 'simplecov-console'

Expand Down
13 changes: 13 additions & 0 deletions spec/user_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'user'

describe User do
describe '.create' do
it "creates a new user" do
user = User.create(name: 'Sam', username: 'samk94', email: '[email protected]', password: 'pass')
expect(user.name).to eq('Sam')
expect(user.username).to eq('samk94')
expect(user.email).to eq('[email protected]')
expect(user.password).to eq('pass')
end
end
end
24 changes: 24 additions & 0 deletions views/chitter.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<h1> Welcome to Chitter! </h1>
<br>
<h2> You are now signed in to Chitter </h2>
<br>
<form action="chitter/new" method="post" >
<input type="text" name="message" placeholder="peep" />
<input type="submit" value="Peep!" />
</form>
<div class='feed'>
<table>
<% @peeps.each do |peep| %>
<tr class='peep-details'>
<td>
<%= peep.sent_time %>
</td>
</tr>
<tr class='peep-message'>
<td>
<%= peep.message %>
</td>
</tr>
<% end %>
</table>
</div>
23 changes: 23 additions & 0 deletions views/index.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<h1> Welcome to Chitter! </h1>
<br>
<h2> Please sign up using the form below: </h2>
<br>
<form method="post" action="/chitter">
Enter your name:
<input type="text" name="name" placeholder="Name" />
<br>
<br>
Enter your username:
<input type="text" name="username" placeholder="Username" />
<br>
<br>
Enter your email address:
<input type="text" name="email" placeholder="Email" />
<br>
<br>
Finally, enter your password and hit sign up:
<input type="text" name="password" placeholder="Password" />
<br>
<br>
<input type="submit" value="Sign up!" />
</form>