adva-core 0.0.9 → 0.0.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. data/app/models/section.rb +0 -6
  2. data/app/views/admin/sites/index.html.rb +2 -2
  3. data/config/redirects.rb +2 -1
  4. data/lib/adva.rb +41 -0
  5. data/lib/adva/controller/internal_redirect.rb +2 -1
  6. data/lib/adva/core.rb +8 -0
  7. data/lib/adva/engine.rb +1 -0
  8. data/lib/adva/generators/app.rb +7 -8
  9. data/lib/adva/generators/templates/app/Gemfile +4 -4
  10. data/lib/adva/generators/templates/app/Thorfile +9 -0
  11. data/lib/adva/generators/templates/app/app_template.rb +4 -2
  12. data/lib/adva/generators/templates/engine/Gemfile.erb +15 -0
  13. data/lib/adva/testing.rb +9 -2
  14. data/lib/adva/testing/engine.rb +1 -0
  15. data/lib/adva/view/form.rb +4 -1
  16. data/lib/adva_core/version.rb +1 -1
  17. data/lib/bundler/repository.rb +117 -0
  18. data/lib/patches/inherited_resources.rb +4 -3
  19. data/lib/patches/rails/integretion_runner_respond_to.rb +1 -1
  20. data/lib/patches/rails/polymorphic_url_for.rb +3 -1
  21. data/lib/patches/rails/recognize_path_env.rb +33 -29
  22. data/lib/patches/rails/route_set_to_param.rb +19 -17
  23. data/lib/patches/rails/route_set_trailing_segment.rb +1 -1
  24. data/lib/patches/rails/sti_associations.rb +10 -4
  25. data/lib/patches/rails/translation_helper.rb +2 -1
  26. data/lib/patches/responders/flash_responder.rb +1 -0
  27. data/lib/patches/simple_form.rb +2 -2
  28. data/lib/testing/env.rb +19 -13
  29. data/lib/testing/factories.rb +5 -1
  30. data/lib/testing/paths.rb +4 -4
  31. data/lib/testing/selectors.rb +72 -0
  32. data/lib/testing/step_definitions/capybara_steps.rb +211 -0
  33. data/lib/testing/step_definitions/common_steps.rb +87 -98
  34. data/lib/testing/step_definitions/debug_steps.rb +11 -4
  35. data/lib/testing/step_definitions/email_steps.rb +195 -0
  36. data/lib/testing/step_definitions/menu_steps.rb +7 -2
  37. data/lib/testing/step_definitions/more_web_steps.rb +4 -0
  38. data/lib/testing/step_definitions/pickle_steps.rb +104 -0
  39. data/lib/testing/step_definitions/transforms.rb +10 -1
  40. data/lib/testing/support/pickle.rb +24 -0
  41. data/public/javascripts/adva-core/jquery/jquery.table_tree.js +5 -1
  42. metadata +340 -305
  43. data/lib/patches/rails/asset_expansion_multiple_registrations.rb +0 -21
  44. data/lib/patches/rails/template_resolver_caching.rb +0 -9
  45. data/lib/patches/webrat/links-data-method.rb +0 -15
  46. data/lib/patches/webrat/logger.rb +0 -14
  47. data/lib/patches/webrat/upload_file.rb +0 -23
  48. data/lib/patches/webrat/within_xpath.rb +0 -13
  49. data/lib/testing/step_definitions/webrat_steps.rb +0 -284
  50. data/lib/testing/step_definitions/within_steps.rb +0 -16
@@ -1,3 +1,11 @@
1
+ Then /^the "([^\"]*)" field should be empty$/ do |field|
2
+ if defined?(Spec::Rails::Matchers)
3
+ field_labeled(field).value.should be_blank
4
+ else
5
+ assert field_labeled(field).value.blank?
6
+ end
7
+ end
8
+
1
9
  Given 'a site' do
2
10
  @site = Factory(:site)
3
11
  end
@@ -79,35 +87,26 @@ When /^(.+) that link$/ do |step|
79
87
  end
80
88
 
81
89
  When /^I (press|click|follow) "(.*)" in the row (of the ([a-z ]+) table )?where "(.*)" is "(.*)"$/ do |action, target, _, table_id, header, content|
82
- body = Nokogiri::HTML(response.body)
83
- table_xpath = table_id.nil? ? 'table' : "table[@id='#{table_id.gsub(/ /, '_')}']"
84
- headers = body.xpath("//#{table_xpath}/descendant::th[normalize-space(text())='#{header}']/@id")
90
+ table_id = table_id.gsub(/ /, '_') unless table_id.nil?
91
+ table_xpath = table_id.nil? ? 'table' : "table[@id='#{table_id}']"
92
+ headers = page.all(:xpath, "//#{table_xpath}/descendant::th[normalize-space(text())='#{header}']")
85
93
  assert !headers.empty?, "could not find table header cell #{header.inspect}"
86
94
 
87
- header_id = headers.first.value
95
+ header_id = headers.first['id']
88
96
  cell_path = "//#{table_xpath}/descendant::td[@headers='#{header_id}']"
89
97
  content = "normalize-space(text())='#{content}'"
90
- tag_path = "#{cell_path}[#{content}]/ancestor::tr/@id"
91
- nested_tag_path = "#{cell_path}/descendant::*[#{content}]/ancestor::tr/@id"
98
+ tag_path = "#{cell_path}[#{content}]/ancestor::tr"
99
+ nested_tag_path = "#{cell_path}/descendant::*[#{content}]/ancestor::tr"
92
100
 
93
- rows = body.xpath([tag_path, nested_tag_path].join('|'))
101
+ rows = page.all(:xpath, [tag_path, nested_tag_path].join('|'))
94
102
  assert !rows.empty?, "could not find table row where a cell has the header id #{header_id.inspect} and the content #{content.inspect}"
95
103
 
96
104
  map = { 'press' => 'click_button', 'click' => 'click_link' }
97
- within("##{rows.first.value}") { map[action] ? send(map[action], target) : When(%(I #{action} "#{target}")) }
98
- end
99
-
100
- When /^I order the (.*)s list by "([^"]*)"$/ do |model, order|
101
- When %(I select "#{order}" from "#{model}s_order")
102
- select = Webrat::Locators::FieldLocator.new(webrat, webrat.dom, "#{model}s_order", Webrat::SelectField).locate!
103
- select.send(:form).submit
104
- end
105
-
106
- When /^I visit the url from the email to (.*)$/ do |to|
107
- email = ::ActionMailer::Base.deliveries.detect { |email| email.to.include?(to) }
108
- assert email, "email to #{to} could not be found"
109
- url = email.body.to_s =~ %r((http://[^\s"]+)) && $1
110
- visit(url)
105
+ if table_id.nil?
106
+ within("##{rows.first['id']}") { map[action] ? send(map[action], target) : When(%(I #{action} "#{target}")) }
107
+ else
108
+ within("table##{table_id} ##{rows.first['id']}") { map[action] ? send(map[action], target) : When(%(I #{action} "#{target}")) }
109
+ end
111
110
  end
112
111
 
113
112
  # Examples:
@@ -115,25 +114,24 @@ end
115
114
  # I should not see a product row where "Name" is "Apple Powerbook"
116
115
  # I should see a row in the products table where "Name" is "Apple Powerbook"
117
116
  Then /^I should (not )?see a ([a-z ]+ )?row (?:of the ([a-z ]+) table )?where "(.*)" is "(.*)"$/ do |optional_not, row_classes, table_id, header, cell_content|
118
- body = Nokogiri::HTML(response.body)
119
- table_xpath = table_id.nil? ? 'table' : "table[@id='#{table_id.gsub(/ /, '_')}']"
120
- table_header_cells = body.xpath("//#{table_xpath}/descendant::th[normalize-space(text())='#{header}']/@id")
117
+ table_xpath = table_id.nil? ? 'table' : "table[@id='#{table_id.gsub(/ /, '_')}' or @id='#{table_id.gsub(/ /, '-')}']"
118
+ table_header_cells = page.all(:xpath, "//#{table_xpath}/descendant::th[normalize-space(text())='#{header}']")
121
119
 
122
120
  unless optional_not.present?
123
121
  assert !table_header_cells.empty?, "could not find table header cell '#{header}'"
124
122
  end
125
- header_id = body.xpath("//#{table_xpath}/descendant::th[normalize-space(text())='#{header}']/@id").first.try(:value)
123
+ header_id = table_header_cells.first['id']
126
124
 
127
125
  class_condition = row_classes.to_s.split(' ').map do |row_class|
128
126
  "contains(concat(' ', normalize-space(@class), ' '), ' #{row_class} ')"
129
127
  end.join(' and ')
130
128
  tr_xpath = class_condition.empty? ? 'ancestor::tr' : "ancestor::tr[#{class_condition}]"
131
- xpath_result = body.xpath("//#{table_xpath}/descendant::td[@headers='#{header_id}'][normalize-space(text())='#{cell_content}']/#{tr_xpath}")
129
+ final_path = "//#{table_xpath}/descendant::td[@headers='#{header_id}'][normalize-space(text())='#{cell_content}']/#{tr_xpath}"
132
130
 
133
131
  if optional_not.present?
134
- assert xpath_result.empty?, "Expected not find a row where #{header.inspect} is #{cell_content}."
132
+ assert page.has_no_xpath?(final_path), "Expected not find a row where #{header.inspect} is #{cell_content}."
135
133
  else
136
- assert xpath_result.any?, "Expected to find at least one row where #{header.inspect} is #{cell_content}."
134
+ assert page.has_xpath?(final_path), "Expected to find at least one row where #{header.inspect} is #{cell_content}."
137
135
  end
138
136
  end
139
137
 
@@ -172,62 +170,52 @@ Then /^that (\w+) should have (\w+)s with the following attributes:$/ do |last,
172
170
  end
173
171
 
174
172
  Then /^the title should be "([^"]+)"$/ do |title|
175
- assert_select('title', title)
173
+ Then %Q{I should see "#{title}" within "title"}
176
174
  end
177
175
 
178
176
  # TODO: This is an almost duplicate step
179
177
  # Use the one with un-quoted 'thing' expression
180
178
  Then /^I should see (an?|the) "([^"]+)"$/ do |kind, thing|
181
179
  kind = { 'a' => '.', 'the' => '#' }[kind]
182
- assert_select("#{kind}#{thing}")
180
+ assert page.has_css?("#{kind}#{thing}")
183
181
  end
184
182
 
185
183
  Then /^I should see a link "([^"]+)"$/ do |link|
186
184
  @last_link = link
187
- assert_select('a', link)
185
+ assert page.has_css?('a', :text => link)
188
186
  end
189
187
 
190
188
  Then /^I should not see any ([a-z_ ]+)$/ do |type|
191
- assert_select(".#{type.gsub(' ', '_').singularize}", :count => 0)
189
+ assert page.has_no_css?(".#{type.gsub(' ', '_').singularize}")
192
190
  end
193
191
 
192
+ # FIXME: this step and the ones above do not deal with use perception
193
+ # for example: "I should see a fn0rd" looks nice, but users cannot see elements, only text
194
194
  Then /^I should see an? (\w+)$/ do |type|
195
- assert_select(".#{type}")
195
+ assert page.has_css?(".#{type}")
196
196
  end
197
197
 
198
198
  Then /^I should see a "([^"]*)" select box with the following options:$/ do |name, options|
199
- select = Webrat::Locators::FieldLocator.new(webrat, webrat.dom, 'products_order', Webrat::SelectField).locate!
200
- actual = select.options.map(&:inner_text).uniq
199
+ field = find_field(name)
200
+ actual = field.all(:css, 'option').map {|o| o.text }
201
201
  expected = options.raw.flatten[1..-1] # ignores the first row
202
202
  assert_equal expected, actual
203
203
  end
204
204
 
205
- Then /^I should see an? (\w+) (?:titled|named) "([^"]+)"$/ do |type, text|
206
- assert_select(".#{type} h2", text)
205
+ Then /^I should see an? (\w+) (?:titled|named) "([^"]+)"$/ do |thingy, text|
206
+ Then %Q~I should see "#{text}" within ".#{thingy} h2"~
207
207
  end
208
208
 
209
- Then /^I should see an? (\w+) containing "([^"]+)"$/ do |type, text|
210
- assert_select(".#{type}", /#{text}/)
211
- end
212
-
213
- # TODO: the sinature of this step should really be:
214
- # I should see 'foo' within 'bar'
215
- # However, the generic "within 'bar'" meta step uses 'within' which doesn't currently work with assertions
216
- # only with navigation ('click', 'press')
217
- Then /^the ([^"]+) should(?: (not))? contain "([^"]+)"$/ do |container_name, optional_negation, text|
218
- container_id = container_name.gsub(' ', '_')
219
- # 'within' doesn't currently work with assertions, so we need to resort to xpath
220
- # within('#' + container_id) { assert_contain text }
221
- assert(parsed_html.xpath("//*[@id=\"#{container_id}\"]").any?, "Could not find the #{container_name}")
222
- assert(parsed_html.xpath("//*[@id=\"#{container_id}\"]/descendant::*[contains(normalize-space(text()), \"#{text}\")]").send(optional_negation ? :'none?' : :'any?'), "Could not see '#{text}' in the #{container_name}")
209
+ Then /^I should see an? (\w+) containing "([^"]+)"$/ do |thingy, text|
210
+ Then %Q~I should see "#{text}" within ".#{thingy}"~
223
211
  end
224
212
 
225
213
  Then /^I should see an? (\w+) list$/ do |type|
226
- assert_select(".#{type}.list")
214
+ assert page.has_css?(".#{type}.list")
227
215
  end
228
216
 
229
217
  Then /^I should see a list of (\w+)$/ do |type|
230
- assert_select(".#{type}.list")
218
+ assert page.has_css?(".#{type}.list")
231
219
  end
232
220
 
233
221
  Then /^the (.*) list should display (.*)s in the following order:$/ do |list, model, values|
@@ -244,32 +232,35 @@ Then /^I should see an? ([a-z ]+) form$/ do |type|
244
232
  tokens = type.split(' ')
245
233
  types = [tokens.join('_'), tokens.reverse.join('_')]
246
234
  selectors = types.map { |type| "form.#{type}, form##{type}" }
247
- assert_select(selectors.join(', '))
235
+ assert page.has_css?(selectors.join(', '))
248
236
  end
249
237
 
250
238
  Then /^I should not see an? ([a-z ]+) form$/ do |type|
251
239
  type = type.gsub(' ', '_') #.gsub(/edit_/, '')
252
- assert_select("form.#{type}, form##{type}", :count => 0)
240
+ assert page.has_no_css?("form.#{type}, form##{type}")
253
241
  end
254
242
 
255
- Then /^I should see an? ([a-z ]+) form with the following values:$/ do |type, table|
256
- type = type.gsub(' ', '_') #.gsub(/edit_/, '')
257
- assert_select("form.#{type}, form##{type}") do |form|
243
+ Then /^I should see an? ([a-z ]+) form with the following values:$/ do |kind, table|
244
+ with_scope("#{kind} form") do
258
245
  table.rows_hash.each do |name, value|
259
- assert_equal value, webrat.current_scope.field_labeled(name).value
246
+ Then %Q~the "#{name}" field should contain "#{value}"~
260
247
  end
261
248
  end
262
249
  end
263
250
 
264
- Then /^I should see a "(.+)" table with the following entries:$/ do |table_id, expected_table|
265
- actual_table = table(tableish("table##{table_id} tr", 'td,th'))
266
- begin
267
- diff_table = expected_table.dup
268
- diff_table.diff!(actual_table.dup)
269
- rescue
270
- puts tables_differ_message(actual_table, expected_table, diff_table)
271
- raise
251
+ Then /^I should see a "(.+)" table with the following entries:$/ do |dom_id, expected|
252
+ actual = table(tableish("table##{dom_id} tr", 'th,td'))
253
+ expected.diff! actual
254
+ end
255
+
256
+ Then /^I should see a "(.+)" list with the following entries:$/ do |dom_id, expected|
257
+ value_selector = expected.column_names.map {|n| '.' + n.downcase.gsub(/[ _]/, '-') }.join(',')
258
+ list = tableish("ul##{dom_id} li", value_selector)
259
+ actual = table( [expected.column_names] + list )
260
+ actual.column_names.each do |col|
261
+ actual.map_column!(col) { |text| text.sub(/\n/,' ') }
272
262
  end
263
+ expected.diff! actual
273
264
  end
274
265
 
275
266
  Then /^I should see a "(.+)" table with the following entries in no particular order:$/ do |table_id, expected_table|
@@ -286,7 +277,7 @@ def tables_differ_message(actual, expected, diff = nil)
286
277
  end
287
278
 
288
279
  Then /^I should see the "([^"]+)" page$/ do |name|
289
- assert_select('h2', name)
280
+ Then %Q~I should see "#{name}" within "h2"~
290
281
  end
291
282
 
292
283
  Then(/(?:\$|eval) (.*)$/) do |code|
@@ -302,13 +293,8 @@ Then /^I should not see a flash (error|notice) "(.+)"$/ do |message_type, messag
302
293
  end
303
294
 
304
295
  Then /^I should (see|not see) the error "([^"]+)" for attribute "([^"]+)" of the "([^"]+)"$/ do |should_see, error_msg, attribute, model|
305
- if should_see == 'see' # ugh ...
306
- assert_select "*[id*=#{model.downcase.gsub(' ', '_')}_#{attribute.downcase.gsub(' ', '_')}] + span.error",
307
- :text => error_msg
308
- elsif should_see == 'not see'
309
- assert_select "*[id*=#{model.downcase.gsub(' ', '_')}_#{attribute.downcase.gsub(' ', '_')}] + span.error",
310
- :text => error_msg, :count => 0
311
- end
296
+ selector = "*[id*=#{model.downcase.gsub(' ', '_')}_#{attribute.downcase.gsub(' ', '_')}] + span.error"
297
+ Then %Q~I should #{should_see} "#{error_msg}" within "#{selector}"~
312
298
  end
313
299
 
314
300
  Then /^the following emails should have been sent:$/ do |expected_emails|
@@ -322,34 +308,27 @@ Then /^no emails should have been sent$/ do
322
308
  end
323
309
 
324
310
  Then /^"([^"]*)" should be filled in with "([^"]*)"$/ do |field, value|
325
- field = webrat.field_labeled(field)
326
- assert_equal value, field.value
311
+ field = find_field(field)
312
+ field_value = (field.tag_name == 'textarea') ? field.text : field.value
313
+ assert_equal(value, field_value)
327
314
  end
328
315
 
329
- Then /^"([^"]*)" should be checked$/ do |label|
330
- field = webrat.field_labeled(label)
331
- assert field.checked?, "expected the checkbox #{label} to be checked"
332
- end
333
-
334
- Then /^"([^"]*)" should not be checked$/ do |label|
335
- field = webrat.field_labeled(label)
336
- assert !field.checked?, "expected the checkbox #{label} not to be checked"
316
+ Then /^"([^"]*)" should (be|not be) checked$/ do |label, be_or_not_to_be|
317
+ Then %Q{the "#{label}" checkbox should #{be_or_not_to_be} checked}
337
318
  end
338
319
 
339
320
  Then /^"([^"]*)" should be selected as "([^"]*)"$/ do |value, label|
340
- select = webrat.field_labeled(label)
341
- assert select, "count not find a select field labeled #{label}"
342
- selected = select.element.xpath(".//option[@selected = 'selected']").first
343
- assert selected, "could not find a selected option"
321
+ select_box = find_field(label)
322
+ selected = select_box.find(:xpath, ".//option[@selected = 'selected']")
344
323
  assert_equal value, selected.text
345
324
  end
346
325
 
347
326
  Then /^I should see "([^"]*)" formatted as a "([^"]*)" tag$/ do |value, tag|
348
- assert_select(tag, value)
327
+ Then %Q~I should see "#{value}" within "#{tag}"~
349
328
  end
350
329
 
351
- Then(/^I should see (\d+|no|one|two|three) ([a-z ]+?)(?: in the ([a-z ]+))?$/) do |amount, item_class, container_id|
352
- container_selector = container_id ? '#' + container_id.gsub(' ', '_') : nil
330
+ # TODO remove the manual (?: in..) to leverage cucumber selectors
331
+ Then(/^I should see (\d+|no|one|two|three) ([-a-z ]+?)(?: in (the [a-z -]+))?$/) do |amount, item_class, container|
353
332
  amount = case amount
354
333
  when 'no' then 0
355
334
  when 'one' then 1
@@ -358,13 +337,23 @@ Then(/^I should see (\d+|no|one|two|three) ([a-z ]+?)(?: in the ([a-z ]+))?$/) d
358
337
  else amount.to_i
359
338
  end
360
339
  item_selector = '.' + item_class.gsub(' ', '_').singularize
361
- # assertions do not work with 'within' yet, so we need to resort to cancatenating selectors:
362
- # container_selector ? within(container_selector) { assert_select(item_selector) } : assert_select(item_selector)
363
- if container_selector
364
- assert_select container_selector
365
- assert_select [container_selector, item_selector].join(' '), amount
340
+ with_scope container do
341
+ assert page.has_css?(item_selector,:count => amount)
342
+ end
343
+ end
344
+
345
+ Then /^the "([^"]*)" radio button should (be|not be) checked$/ do |label, be_or_not_to_be|
346
+ Then %Q~the "#{label}" checkbox should #{be_or_not_to_be} checked~
347
+ end
348
+
349
+ Then /^(?:|I )should not be on (.+)$/ do |page_name|
350
+ current_path = URI.parse(current_url).path
351
+ if current_path.respond_to? :should
352
+ current_path.should_not == path_to(page_name)
366
353
  else
367
- assert_select item_selector, amount
354
+ assert_not_equal path_to(page_name), current_path
368
355
  end
369
356
  end
370
357
 
358
+
359
+
@@ -12,11 +12,18 @@ Then 'debug' do
12
12
  true
13
13
  end
14
14
 
15
- Then /^show me the page$/ do
16
- save_and_open_page
15
+ Then /^(?:|I )output the page$/ do
16
+ puts page.body
17
17
  end
18
18
 
19
- Then /^(?:|I )output the page$/ do
20
- puts response.body
19
+ When /^I pause$/ do
20
+ STDERR.puts "pausing - press enter to continue"
21
+ STDIN.gets
21
22
  end
22
23
 
24
+ Then /^dump the table "([^"]*)"$/ do |table_name|
25
+ filename = Rails.root.join('tmp').join("dump-#{table_name}.csv").expand_path
26
+ sql = "COPY #{table_name} TO '#{filename}' WITH CSV HEADER"
27
+
28
+ ActiveRecord::Base.connection.execute sql
29
+ end
@@ -0,0 +1,195 @@
1
+ require 'email_spec/cucumber'
2
+ # Commonly used email steps
3
+ #
4
+ # To add your own steps make a custom_email_steps.rb
5
+ # The provided methods are:
6
+ #
7
+ # last_email_address
8
+ # reset_mailer
9
+ # open_last_email
10
+ # visit_in_email
11
+ # unread_emails_for
12
+ # mailbox_for
13
+ # current_email
14
+ # open_email
15
+ # read_emails_for
16
+ # find_email
17
+ #
18
+ # General form for email scenarios are:
19
+ # - clear the email queue (done automatically by email_spec)
20
+ # - execute steps that sends an email
21
+ # - check the user received an/no/[0-9] emails
22
+ # - open the email
23
+ # - inspect the email contents
24
+ # - interact with the email (e.g. click links)
25
+ #
26
+ # The Cucumber steps below are setup in this order.
27
+
28
+ module EmailHelpers
29
+ def current_email_address
30
+ # Replace with your a way to find your current email. e.g @current_user.email
31
+ # last_email_address will return the last email address used by email spec to find an email.
32
+ # Note that last_email_address will be reset after each Scenario.
33
+ last_email_address || "example@example.com"
34
+ end
35
+ end
36
+
37
+ World(EmailHelpers)
38
+
39
+ #
40
+ # Reset the e-mail queue within a scenario.
41
+ # This is done automatically before each scenario.
42
+ #
43
+
44
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
45
+ reset_mailer
46
+ end
47
+
48
+ #
49
+ # Check how many emails have been sent/received
50
+ #
51
+
52
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
53
+ unread_emails_for(address).size.should == parse_email_count(amount)
54
+ end
55
+
56
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
57
+ mailbox_for(address).size.should == parse_email_count(amount)
58
+ end
59
+
60
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject|
61
+ unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size.should == parse_email_count(amount)
62
+ end
63
+
64
+ Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body|
65
+ open_email(address, :with_text => expected_body)
66
+ end
67
+
68
+ #
69
+ # Accessing emails
70
+ #
71
+
72
+ # Opens the most recently received email
73
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
74
+ open_email(address)
75
+ end
76
+
77
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
78
+ open_email(address, :with_subject => subject)
79
+ end
80
+
81
+ When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
82
+ open_email(address, :with_text => text)
83
+ end
84
+
85
+ #
86
+ # Inspect the Email Contents
87
+ #
88
+
89
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
90
+ current_email.should have_subject(text)
91
+ end
92
+
93
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
94
+ current_email.should have_subject(Regexp.new(text))
95
+ end
96
+
97
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
98
+ current_email.default_part_body.to_s.should include(text)
99
+ end
100
+
101
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
102
+ current_email.default_part_body.to_s.should =~ Regexp.new(text)
103
+ end
104
+
105
+ Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text|
106
+ current_email.should be_delivered_from(text)
107
+ end
108
+
109
+ Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
110
+ current_email.should have_header(name, text)
111
+ end
112
+
113
+ Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
114
+ current_email.should have_header(name, Regexp.new(text))
115
+ end
116
+
117
+ Then /^I should see it is a multi\-part email$/ do
118
+ current_email.should be_multipart
119
+ end
120
+
121
+ Then /^(?:I|they) should see "([^"]*?)" in the email html part body$/ do |text|
122
+ current_email.html_part.body.to_s.should include(text)
123
+ end
124
+
125
+ Then /^(?:I|they) should see "([^"]*?)" in the email text part body$/ do |text|
126
+ current_email.text_part.body.to_s.should include(text)
127
+ end
128
+
129
+ #
130
+ # Inspect the Email Attachments
131
+ #
132
+
133
+ Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount|
134
+ current_email_attachments.size.should == parse_email_count(amount)
135
+ end
136
+
137
+ Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename|
138
+ current_email_attachments.select { |a| a.filename == filename }.size.should == parse_email_count(amount)
139
+ end
140
+
141
+ Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename|
142
+ current_email_attachments[(index.to_i - 1)].filename.should == filename
143
+ end
144
+
145
+ Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type|
146
+ current_email_attachments.select { |a| a.content_type.include?(content_type) }.size.should == parse_email_count(amount)
147
+ end
148
+
149
+ Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type|
150
+ current_email_attachments[(index.to_i - 1)].content_type.should include(content_type)
151
+ end
152
+
153
+ Then /^all attachments should not be blank$/ do
154
+ current_email_attachments.each do |attachment|
155
+ attachment.read.size.should_not == 0
156
+ end
157
+ end
158
+
159
+ Then /^show me a list of email attachments$/ do
160
+ EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email)
161
+ end
162
+
163
+ #
164
+ # Interact with Email Contents
165
+ #
166
+
167
+ When /^(?:I|they) follow "([^"]*?)" in the email$/ do |link|
168
+ visit_in_email(link)
169
+ end
170
+
171
+ When /^(?:I|they) click the first link in the email$/ do
172
+ click_first_link_in_email
173
+ end
174
+
175
+ #
176
+ # Debugging
177
+ # These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command.
178
+ # Patches accepted. ;)
179
+ #
180
+
181
+ Then /^save and open current email$/ do
182
+ EmailSpec::EmailViewer::save_and_open_email(current_email)
183
+ end
184
+
185
+ Then /^save and open all text emails$/ do
186
+ EmailSpec::EmailViewer::save_and_open_all_text_emails
187
+ end
188
+
189
+ Then /^save and open all html emails$/ do
190
+ EmailSpec::EmailViewer::save_and_open_all_html_emails
191
+ end
192
+
193
+ Then /^save and open all raw emails$/ do
194
+ EmailSpec::EmailViewer::save_and_open_all_raw_emails
195
+ end