Skip to content

Commit

Permalink
Merge branch '57-fix-html-escaping'
Browse files Browse the repository at this point in the history
  • Loading branch information
marnen committed Sep 9, 2011
2 parents a9a9a3c + 3a42388 commit 8be1820
Show file tree
Hide file tree
Showing 12 changed files with 186 additions and 30 deletions.
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ group :test, :development do
gem 'rspec-rails', '~> 2.6.1', :require => false
gem 'test-unit', '1.2.3', :require => false # amazingly, RSpec needs this
gem 'cucumber-rails', :require => false
gem 'pickle'
gem 'database_cleaner'
gem 'factory_girl_rails'
gem 'ffaker'
Expand Down
4 changes: 4 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ GEM
net-ssh (>= 1.99.1)
nokogiri (1.5.0)
pg (0.11.0)
pickle (0.4.8)
cucumber (>= 0.8)
rake
polyglot (0.3.2)
prawn (0.4.0)
prawn-layout
Expand Down Expand Up @@ -189,6 +192,7 @@ DEPENDENCIES
gettext_i18n_rails
haml
pg
pickle
prawn
rails (= 3.0.10)
rdiscount
Expand Down
11 changes: 6 additions & 5 deletions app/helpers/events_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def event_map(event, hostname)

map = GMap.new(:map)
result = ''.html_safe
result << info(event).html_safe
result << info(event)
result << content_tag(:div, event.coords.lat, :id => :lat, :class => :hidden)
result << content_tag(:div, event.coords.lng, :id => :lng, :class => :hidden)
result << map.div(:width => 500, :height => 400).html_safe
Expand All @@ -85,11 +85,12 @@ def ical_uid(event)
#
# TODO: this should probably become a partial.
def info(event)
# TODO: Switch this to the HTML 5 outline model.
return nil if (event.nil? or !event.kind_of?(Event))
result = ""
result << content_tag(:h3, h(event.site || event.name))
city = [h(event.city), h(event.state.code), h(event.state.country.code)].compact.join(', ')
result << content_tag(:p, [h(event.street), h(event.street2), city].compact.join(tag(:br)))
result = ''.html_safe
result << content_tag(:h3, (event.site || event.name))
city = [event.city, event.state.code, event.state.country.code].compact.join(', ')
result << content_tag(:p, [h(event.street), h(event.street2), h(city)].compact.join(tag :br).html_safe)

gmaps = 'http://maps.google.com'
from = "saddr=#{u User.current_user.address.to_s(:geo)}"
Expand Down
4 changes: 3 additions & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@
match 'events/index' => 'events#index'

match 'events/feed.:fmt/:key' => 'events#feed', :as => :feed_events
resources :events
resources :events do
member { get :map }
end

resources :permissions do
member do
Expand Down
11 changes: 11 additions & 0 deletions features/events/event_map.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Feature: Event map
As a registered user
I can see a map of any event on calendars I subscribe to
So I can figure out how to get there

Scenario:
Given I am logged in
And an event exists
When I go to the event's map page
Then I should see a map of the event
And I should see "Get directions" within a link to somewhere at "http://maps.google.com"
4 changes: 4 additions & 0 deletions features/step_definitions/event_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@
cal = Calendar.find_by_name(calendar)
cal.should_not be_nil
Event.find_by_name_and_calendar_id(name, cal.id).should_not be_nil
end

Then /^I should see a map of the event$/ do
Then 'I should see an element matching "#map"'
end
100 changes: 100 additions & 0 deletions features/step_definitions/pickle_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# this file generated by script/generate pickle

# create a model
Given(/^#{capture_model} exists?(?: with #{capture_fields})?$/) do |name, fields|
create_model(name, fields)
end

# create n models
Given(/^(\d+) #{capture_plural_factory} exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields|
count.to_i.times { create_model(plural_factory.singularize, fields) }
end

# create models from a table
Given(/^the following #{capture_plural_factory} exists?:?$/) do |plural_factory, table|
create_models_from_table(plural_factory, table)
end

# find a model
Then(/^#{capture_model} should exist(?: with #{capture_fields})?$/) do |name, fields|
find_model!(name, fields)
end

# not find a model
Then(/^#{capture_model} should not exist(?: with #{capture_fields})?$/) do |name, fields|
find_model(name, fields).should be_nil
end

# find models with a table
Then(/^the following #{capture_plural_factory} should exists?:?$/) do |plural_factory, table|
find_models_from_table(plural_factory, table).should_not be_any(&:nil?)
end

# find exactly n models
Then(/^(\d+) #{capture_plural_factory} should exist(?: with #{capture_fields})?$/) do |count, plural_factory, fields|
find_models(plural_factory.singularize, fields).size.should == count.to_i
end

# assert equality of models
Then(/^#{capture_model} should be #{capture_model}$/) do |a, b|
model!(a).should == model!(b)
end

# assert model is in another model's has_many assoc
Then(/^#{capture_model} should be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
model!(owner).send(association).should include(model!(target))
end

# assert model is not in another model's has_many assoc
Then(/^#{capture_model} should not be (?:in|one of|amongst) #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
model!(owner).send(association).should_not include(model!(target))
end

# assert model is another model's has_one/belongs_to assoc
Then(/^#{capture_model} should be #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
model!(owner).send(association).should == model!(target)
end

# assert model is not another model's has_one/belongs_to assoc
Then(/^#{capture_model} should not be #{capture_model}(?:'s)? (\w+)$/) do |target, owner, association|
model!(owner).send(association).should_not == model!(target)
end

# assert model.predicate?
Then(/^#{capture_model} should (?:be|have) (?:an? )?#{capture_predicate}$/) do |name, predicate|
if model!(name).respond_to?("has_#{predicate.gsub(' ', '_')}")
model!(name).should send("have_#{predicate.gsub(' ', '_')}")
else
model!(name).should send("be_#{predicate.gsub(' ', '_')}")
end
end

# assert not model.predicate?
Then(/^#{capture_model} should not (?:be|have) (?:an? )?#{capture_predicate}$/) do |name, predicate|
if model!(name).respond_to?("has_#{predicate.gsub(' ', '_')}")
model!(name).should_not send("have_#{predicate.gsub(' ', '_')}")
else
model!(name).should_not send("be_#{predicate.gsub(' ', '_')}")
end
end

# model.attribute.should eql(value)
# model.attribute.should_not eql(value)
Then(/^#{capture_model}'s (\w+) (should(?: not)?) be #{capture_value}$/) do |name, attribute, expectation, expected|
actual_value = model(name).send(attribute)
expectation = expectation.gsub(' ', '_')

case expected
when 'nil', 'true', 'false'
actual_value.send(expectation, send("be_#{expected}"))
when /^[+-]?[0-9_]+(\.\d+)?$/
actual_value.send(expectation, eql(expected.to_f))
else
actual_value.to_s.send(expectation, eql(eval(expected)))
end
end

# assert size of association
Then /^#{capture_model} should have (\d+) (\w+)$/ do |name, size, association|
model!(name).send(association).size.should == size.to_i
end
13 changes: 6 additions & 7 deletions features/support/paths.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@ def path_to(page_name)
# when /^(.*)'s profile page$/i
# user_profile_path(User.find_by_login($1))

when /\badmin page/
when /the admin page$/
'/admin'

when /\bevent list/
when /the event list$/
events_path

when /\blogin page/
when /#{capture_model}'s map page$/
map_event_path model!($1)
when /the login page$/
login_path

when /\buser list for "([^"]*)"/
when /the user list for "([^"]*)"$/
url_for :controller => 'calendars', :id => Calendar.find_by_name($1).id, :action => 'users', :only_path => true

else
Expand Down
24 changes: 24 additions & 0 deletions features/support/pickle.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# this file generated by script/generate pickle [paths] [email]
#
# Make sure that you are loading your factory of choice in your cucumber environment
#
# For machinist add: features/support/machinist.rb
#
# require 'machinist/active_record' # or your chosen adaptor
# require File.dirname(__FILE__) + '/../../spec/blueprints' # or wherever your blueprints are
# Before { Sham.reset } # to reset Sham's seed between scenarios so each run has same random sequences
#
# For FactoryGirl add: features/support/factory_girl.rb
#
# require 'factory_girl'
# require File.dirname(__FILE__) + '/../../spec/factories' # or wherever your factories are
#
# You may also need to add gem dependencies on your factory of choice in <tt>config/environments/cucumber.rb</tt>

require 'pickle/world'
# Example of configuring pickle:
#
# Pickle.configure do |config|
# config.adapters = [:machinist]
# config.map 'I', 'myself', 'me', 'my', :to => 'user: "me"'
# end
3 changes: 3 additions & 0 deletions features/support/selectors.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ def selector_for(locator)
# web steps:
when /^"(.+)"$/
$1
when %r{^a link to somewhere at "([^"]+)"$}
url = $1
"a[href^='#{url}']"

else
raise "Can't find mapping from \"#{locator}\" to a selector.\n" +
Expand Down
26 changes: 24 additions & 2 deletions spec/helpers/events_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@
User.stub!(:current_user).and_return(FactoryGirl.create :user)
end

it "should return a safe string" do
helper.event_map(Factory(:event), DOMAIN).should be_html_safe
end

it "should set up a GMap with all the options" do
event = FactoryGirl.create :event

Expand Down Expand Up @@ -107,8 +111,6 @@
gmap_div = '<div id="gmap">GMap div</div>'
gmap.should_receive(:div).and_return(gmap_div)
GMap.should_receive(:new).and_return(gmap)
info_div = '<div id="info">Event info</div>'
helper.should_receive(:info).with(event).at_least(:once).and_return(info_div)

map = helper.event_map(event, DOMAIN)
{'#gmap' => nil, '#info' => nil, '#lat' => ERB::Util::h(event.coords.lat), '#lng' => ERB::Util::h(event.coords.lng)}.each do |k, v|
Expand Down Expand Up @@ -138,6 +140,26 @@
end
end

describe EventsHelper, "info" do
before :each do
User.stub(:current_user).and_return(Factory :user)
@event = Factory :event
@info = helper.info(@event)
end

it "should return a safe string" do
@info.should be_html_safe
end

it "should display a <h3> with the site name" do
@info.should have_selector('h3', :content => @event.site)
end

it "should display the address separated by line breaks" do
@info.should include([h(@event.street), h(@event.street2), h([@event.city, @event.state.code, @event.state.country.code].join(', '))].join(tag :br))
end
end

describe EventsHelper, "list_names" do
it "should return an empty string when called with nil argument" do
helper.list_names(nil).should == ''
Expand Down
15 changes: 0 additions & 15 deletions spec/views/events/map.html.haml_spec.rb

This file was deleted.

0 comments on commit 8be1820

Please sign in to comment.