Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added reply to feature to example app

  • Loading branch information...
commit 85c0ac515d6ffcb44bb93670384dab053f65ca7c 1 parent 5ce1041
Jonas Nicklas authored
2  Gemfile
View
@@ -2,7 +2,7 @@ source 'http://rubygems.org'
gem 'rails', '3.0.5'
gem 'devise'
-gem 'mysql2'
+gem 'pg'
group :talk do
gem 'showoff'
4 Gemfile.lock
View
@@ -75,8 +75,8 @@ GEM
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.16)
- mysql2 (0.2.6)
nokogiri (1.4.4)
+ pg (0.10.1)
polyglot (0.3.1)
rack (1.2.2)
rack-mount (0.6.13)
@@ -144,7 +144,7 @@ DEPENDENCIES
cucumber-rails
database_cleaner
devise
- mysql2
+ pg
rails (= 3.0.5)
rspec-rails
showoff
9 app/controllers/messages_controller.rb
View
@@ -7,6 +7,15 @@ def index
end
end
+ def new
+ @reply_to = Message.find(params[:reply_to]) if params[:reply_to]
+ @message = current_user.messages.build
+ respond_to do |format|
+ format.js { render :partial => 'form.html.erb' }
+ format.html { render 'new_reply' }
+ end
+ end
+
def create
@message = current_user.messages.build(params[:message])
1  app/models/message.rb
View
@@ -1,5 +1,6 @@
class Message < ActiveRecord::Base
belongs_to :user
+ belongs_to :reply_to_message, :class_name => 'Message'
validates_presence_of :message, :user_id
scope :recent, order('created_at DESC').limit(10)
8 app/views/messages/_form.html.erb
View
@@ -0,0 +1,8 @@
+<%= form_for @message do |f| %>
+ <p><%= f.label :message, 'New message' %></p>
+ <p><%= f.text_area :message, :rows => 4 %></p>
+ <p>
+ <%= f.hidden_field :reply_to_message_id, :value => @reply_to.id if @reply_to %>
+ <%= f.submit "Send" %>
+ </p>
+<% end %>
6 app/views/messages/_message.html.erb
View
@@ -0,0 +1,6 @@
+<h3><%= message.message %></h3>
+<p>by <%= message.user.username %></p>
+<% if message.reply_to_message %>
+ <p><%= link_to "In reply to", "#" + dom_id(message.reply_to_message), :class => 'in-reply-to' %></p>
+<% end %>
+<p><%= link_to 'Reply', new_message_path(:reply_to => message), :class => 'reply' %></p>
13 app/views/messages/_messages.html.erb
View
@@ -1,6 +1,7 @@
-<% Message.recent.each do |message| %>
- <li>
- <h3><%= message.message %></h3>
- <p>by <%= message.user.email %></p>
- </li>
-<% end %>
+<ul id="messages">
+ <% Message.recent.each do |message| %>
+ <%= content_tag_for(:li, message) do %>
+ <%= render message %>
+ <% end %>
+ <% end %>
+</ul>
10 app/views/messages/index.html.erb
View
@@ -1,13 +1,7 @@
<h1>Listing messages</h1>
-<%= form_for @message do |f| %>
- <p><%= f.label :message, 'New message' %></p>
- <p><%= f.text_area :message, :rows => 4 %></p>
- <p><%= f.submit "Send" %></p>
-<% end %>
+<p><%= link_to 'New message', new_message_path, :class => 'new' %></p>
-<ul id="messages">
- <%= render :partial => 'messages' %>
-</ul>
+<%= render :partial => 'messages' %>
<%= javascript_include_tag 'messages' %>
3  app/views/messages/new_reply.html.erb
View
@@ -0,0 +1,3 @@
+<h1>Reply to message<h1>
+
+<%= render 'form' %>
8 config/database.yml
View
@@ -1,12 +1,12 @@
development: &DEFAULT
- adapter: mysql2
+ adapter: postgresql
encoding: utf8
reconnect: false
+ database: advanced_capybara_dev
pool: 5
- username: root
+ username: elabs
password:
- host: 127.0.0.1
- database: advanced_capybara_dev
+ min_messages: warning
test:
<<: *DEFAULT
4 features/reply.feature
View
@@ -3,12 +3,14 @@ Feature: Replying to a message
As a user
I want to reply to someones message
- Scenario: Add a post
+ @javascript
+ Scenario: reply to a posAdd a post
Given the user "jonas" has posted the message "Hello CukeUp"
And I am signed in as "peter"
When I reply to the message "Hello CukeUp" with "Hello Jonas"
Then I should see the message "Hello Jonas"
+ @javascript
Scenario: click the "in reply to" link to see the original message highlighted
Given the user "jonas" has posted the message "Hello CukeUp"
And I am signed in as "peter"
2  features/step_definitions/common_steps.rb
View
@@ -2,7 +2,7 @@
visit("/")
end
-Given /^I click on "([^"]*)"$/ do |link|
+Given /^I click "([^"]*)"$/ do |link|
click_on(link)
end
14 features/step_definitions/message_steps.rb
View
@@ -1,4 +1,5 @@
When /^I send the message "([^"]*)"$/ do |message|
+ click_on 'New message'
fill_in 'New message', :with => message
click_on 'Send'
end
@@ -8,14 +9,19 @@
end
Given /^the user "([^"]*)" has posted the message "([^"]*)"$/ do |username, message|
- user = User.find_by_username!(username)
+ user = User.find_by_username(username)
+ user ||= User.create!(
+ :username => username,
+ :email => "#{username}@elabs.se",
+ :password => "capybara"
+ )
Message.create!(:user => user, :message => message)
end
When /^I reply to the message "([^"]*)" with "([^"]*)"$/ do |message, reply|
within "#messages li", :text => message do
click_on "Reply"
- fill_in "New Reply", :with => reply
+ fill_in "New message", :with => reply
click_on "Send"
end
end
@@ -26,7 +32,7 @@
end
end
-Then /^I should see that the message "([^"]*)" is highlighted$/ do |arg1|
- find("#messages li", :text => message)[:class].should include('highlighed')
+Then /^I should see that the message "([^"]*)" is highlighted$/ do |message|
+ find("#messages li", :text => message)[:class].should include('highlighted')
end
13 features/support/env.rb
View
@@ -1,6 +1,6 @@
# IMPORTANT: This file is generated by cucumber-rails - edit at your own peril.
-# It is recommended to regenerate this file in the future when you upgrade to a
-# newer version of cucumber-rails. Consider adding your own code to a new file
+# It is recommended to regenerate this file in the future when you upgrade to a
+# newer version of cucumber-rails. Consider adding your own code to a new file
# instead of editing this one. Cucumber will automatically load all features/**/*.rb
# files.
@@ -15,14 +15,13 @@
require 'capybara/rails'
require 'capybara/cucumber'
require 'capybara/session'
-require 'cucumber/rails/capybara_javascript_emulation' # Lets you click links with onclick javascript handlers without using @culerity or @javascript
# Capybara defaults to XPath selectors rather than Webrat's default of CSS3. In
# order to ease the transition to Capybara we set the default here. If you'd
# prefer to use XPath just remove this line and adjust any selectors in your
# steps to use the XPath syntax.
Capybara.default_selector = :css
-# If you set this to false, any error raised from within your app will bubble
+# If you set this to false, any error raised from within your app will bubble
# up to your step definition and out to cucumber unless you catch it somewhere
# on the way. You can make Rails rescue errors and render error pages on a
# per-scenario basis by tagging a scenario or feature with the @allow-rescue tag.
@@ -34,15 +33,15 @@
ActionController::Base.allow_rescue = false
# If you set this to true, each scenario will run in a database transaction.
-# You can still turn off transactions on a per-scenario basis, simply tagging
+# You can still turn off transactions on a per-scenario basis, simply tagging
# a feature or scenario with the @no-txn tag. If you are using Capybara,
# tagging with @culerity or @javascript will also turn transactions off.
#
# If you set this to false, transactions will be off for all scenarios,
# regardless of whether you use @no-txn or not.
#
-# Beware that turning transactions off will leave data in your database
-# after each scenario, which can lead to hard-to-debug failures in
+# Beware that turning transactions off will leave data in your database
+# after each scenario, which can lead to hard-to-debug failures in
# subsequent scenarios. If you do this, we recommend you create a Before
# block that will explicitly put your database in a known state.
Cucumber::Rails::World.use_transactional_fixtures = true
51 public/javascripts/messages.js
View
@@ -1,26 +1,39 @@
$(function() {
- $('#new_message').each(function() {
- var form = $(this)
- form.submit(function() {
- $.ajax({
- url: form.attr('action'),
- data: form.serialize(),
- type: 'POST',
- success: function(data) {
- $('#messages').html(data);
- }
- });
+ $('a.new').click(function() {
+ var link = $(this);
+ $.get(link.attr('href'), {}, function(data) {
+ $('form.new_message').remove();
+ link.after(data);
+ }, 'html');
+ return false;
+ });
+
+ var Message = function() {
+ var message = $(this);
+ message.find('.reply').click(function() {
+ $.get($(this).attr('href'), {}, function(data) {
+ $('form.new_message').remove();
+ message.append(data);
+ }, 'html');
return false;
});
- });
- setInterval(function() {
- $.ajax({
- url: '/',
- data: {},
- success: function(data) {
- $('#messages').html(data);
- }
+ message.find('.in-reply-to').click(function() {
+ $($(this).attr('href')).addClass('highlighted');
});
+ }
+
+ $('#messages li').each(Message);
+
+ setInterval(function() {
+ $.get('/', {}, function(data) {
+ $(data).find('li').each(function() {
+ var newMessage = $(this);
+ if(!$('#' + newMessage.attr('id')).length) {
+ $('#messages').prepend(newMessage);
+ Message(newMessage);
+ }
+ });
+ }, 'html');
}, 1000);
});
3  public/stylesheets/master.css
View
@@ -0,0 +1,3 @@
+#messages li.highlighted {
+ background: yellow;
+}
1  talk/master.css
View
@@ -45,4 +45,5 @@ pre, pre.sh_sourceCode {
padding: 20px;
font-family: 'Monaco';
background: rgba(255,255,255,0.2);
+ border: 1px solid rgba(255,255,255,0.3);
}
Please sign in to comment.
Something went wrong with that request. Please try again.