noodall-form-builder 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. data/.gitignore +7 -0
  2. data/Gemfile +24 -0
  3. data/Gemfile.lock +202 -0
  4. data/MIT-LICENSE +20 -0
  5. data/README.rdoc +3 -0
  6. data/Rakefile +39 -0
  7. data/app/controllers/noodall/admin/fields_controller.rb +21 -0
  8. data/app/controllers/noodall/admin/form_responses_controller.rb +75 -0
  9. data/app/controllers/noodall/admin/forms_controller.rb +97 -0
  10. data/app/controllers/noodall/form_responses_controller.rb +39 -0
  11. data/app/helpers/admin/forms_helper.rb +2 -0
  12. data/app/helpers/forms_helper.rb +11 -0
  13. data/app/mailers/form_mailer.rb +21 -0
  14. data/app/models/contact_form.rb +16 -0
  15. data/app/models/noodall/check_box.rb +5 -0
  16. data/app/models/noodall/field.rb +25 -0
  17. data/app/models/noodall/form.rb +38 -0
  18. data/app/models/noodall/form_response.rb +88 -0
  19. data/app/models/noodall/radio.rb +4 -0
  20. data/app/models/noodall/select.rb +5 -0
  21. data/app/models/noodall/text_field.rb +12 -0
  22. data/app/views/admin/components/_contact_form.html.erb +11 -0
  23. data/app/views/components/_contact_form.html.erb +8 -0
  24. data/app/views/form_mailer/_form_response_fields.html.erb +3 -0
  25. data/app/views/form_mailer/form_response.html.erb +5 -0
  26. data/app/views/form_mailer/form_response_thankyou.html.erb +19 -0
  27. data/app/views/noodall/admin/fields/_check_box.html.erb +14 -0
  28. data/app/views/noodall/admin/fields/_radio.html.erb +14 -0
  29. data/app/views/noodall/admin/fields/_select.html.erb +14 -0
  30. data/app/views/noodall/admin/fields/_text_field.html.erb +26 -0
  31. data/app/views/noodall/admin/form_responses/index.csv.csvbuilder +12 -0
  32. data/app/views/noodall/admin/form_responses/index.html.erb +41 -0
  33. data/app/views/noodall/admin/forms/_field_select.html.erb +11 -0
  34. data/app/views/noodall/admin/forms/index.html.erb +41 -0
  35. data/app/views/noodall/admin/forms/show.html.erb +138 -0
  36. data/app/views/noodall/form_responses/_form.html.erb +45 -0
  37. data/app/views/noodall/form_responses/create.html.erb +5 -0
  38. data/app/views/noodall/form_responses/new.html.erb +5 -0
  39. data/app/views/noodall/forms/edit.html.erb +12 -0
  40. data/app/views/noodall/forms/index.html.erb +18 -0
  41. data/app/views/noodall/forms/new.html.erb +11 -0
  42. data/app/views/noodall/forms/show.html.erb +3 -0
  43. data/cucumber.yml +8 -0
  44. data/features/form_builder.feature +54 -0
  45. data/features/form_module.feature +40 -0
  46. data/features/step_definitions/cms_node_steps.rb +126 -0
  47. data/features/step_definitions/component_steps.rb +138 -0
  48. data/features/step_definitions/email_steps.rb +182 -0
  49. data/features/step_definitions/form_builder_steps.rb +247 -0
  50. data/features/step_definitions/sign_in_steps.rb +48 -0
  51. data/features/step_definitions/web_steps.rb +219 -0
  52. data/features/support/defensio_mock.rb +6 -0
  53. data/features/support/env.rb +52 -0
  54. data/features/support/paths.rb +60 -0
  55. data/lib/noodall/form_builder/engine.rb +13 -0
  56. data/lib/noodall/form_builder/routes.rb +35 -0
  57. data/lib/noodall/form_builder/version.rb +5 -0
  58. data/lib/noodall-form-builder.rb +1 -0
  59. data/noodall-form-builder.gemspec +23 -0
  60. data/public/images/admin/spam.png +0 -0
  61. data/public/javascripts/admin/formbuilder.js +52 -0
  62. data/spec/dummy/Rakefile +7 -0
  63. data/spec/dummy/app/controllers/application_controller.rb +22 -0
  64. data/spec/dummy/app/helpers/application_helper.rb +8 -0
  65. data/spec/dummy/app/models/page_a.rb +8 -0
  66. data/spec/dummy/app/models/user.rb +14 -0
  67. data/spec/dummy/app/views/admin/nodes/_page_a.html.erb +47 -0
  68. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  69. data/spec/dummy/app/views/nodes/page_a.html.erb +14 -0
  70. data/spec/dummy/config/application.rb +46 -0
  71. data/spec/dummy/config/boot.rb +10 -0
  72. data/spec/dummy/config/database.yml +12 -0
  73. data/spec/dummy/config/defensio.yml +16 -0
  74. data/spec/dummy/config/environment.rb +5 -0
  75. data/spec/dummy/config/environments/development.rb +26 -0
  76. data/spec/dummy/config/environments/production.rb +49 -0
  77. data/spec/dummy/config/environments/test.rb +35 -0
  78. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/spec/dummy/config/initializers/dragonfly.rb +1 -0
  80. data/spec/dummy/config/initializers/inflections.rb +10 -0
  81. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  82. data/spec/dummy/config/initializers/mongo_mapper.rb +13 -0
  83. data/spec/dummy/config/initializers/noodall.rb +5 -0
  84. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  85. data/spec/dummy/config/initializers/session_store.rb +8 -0
  86. data/spec/dummy/config/locales/en.yml +5 -0
  87. data/spec/dummy/config/routes.rb +4 -0
  88. data/spec/dummy/config.ru +4 -0
  89. data/spec/dummy/public/404.html +26 -0
  90. data/spec/dummy/public/422.html +26 -0
  91. data/spec/dummy/public/500.html +26 -0
  92. data/spec/dummy/public/favicon.ico +0 -0
  93. data/spec/dummy/public/javascripts/application.js +2 -0
  94. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  95. data/spec/dummy/script/rails +6 -0
  96. data/spec/factories/asset.rb +6 -0
  97. data/spec/factories/contact_form.rb +3 -0
  98. data/spec/factories/field.rb +15 -0
  99. data/spec/factories/form.rb +13 -0
  100. data/spec/factories/node.rb +5 -0
  101. data/spec/factories/response.rb +7 -0
  102. data/spec/factories/user.rb +15 -0
  103. data/spec/files/beef.png +0 -0
  104. data/spec/integration/navigation_spec.rb +9 -0
  105. data/spec/noodall_form_builder_spec.rb +7 -0
  106. data/spec/spec_helper.rb +30 -0
  107. metadata +204 -0
@@ -0,0 +1,54 @@
1
+ Feature: Form builder
2
+ In order to capture data from website visitors a website editor will be able to create custom forms that can be placed on the website
3
+
4
+ Scenario: Create a Form
5
+ Given I visit the form builder admin page
6
+ And I follow "New Form"
7
+ Then I should see a form with at least the following fields:
8
+ | Field |
9
+ | Name |
10
+ | Email |
11
+ When I fill the following fields:
12
+ | Field | Value |
13
+ | Title | A Contact Form |
14
+ | Description | So people can get in touch |
15
+ | Email | hello@weaarebeef.co.uk |
16
+ And I add the fields I want on the form
17
+ And I press "Create"
18
+ Then I should see the new form in the Form List
19
+
20
+ @javscript @wip
21
+ Scenario Outline: Add fields
22
+ Given I am creating a form
23
+ When I select "<Field Type>" from "Add a new field"
24
+ And I click "Add"
25
+ Then I should see a new field with the options "<Options>"
26
+
27
+ Examples:
28
+ | Field Type | Options |
29
+ | Text | Name, Label, Default, Rows, Required |
30
+ | Select | Name, Label, Default Option, Options, Required |
31
+ | Radio | Name, Label, Default Option, Options, Required |
32
+ | Check Box | Name, Label, Default state, Required |
33
+
34
+ @javscript @wip
35
+ Scenario: Reorder fields
36
+ Given a form exists with the following fields:
37
+ | Name | Text Field |
38
+ | Email | Text Field |
39
+ | Title | Select Field: Mr, Mrs |
40
+ | Message | Text Field |
41
+ When I am editing the form
42
+ And I click the "up" arrow next to "Title" twice
43
+ Then the "Title" field should be at position 1
44
+ When I click the "down" arrow next to "Email" once
45
+ Then the "Email" field should be at position 4
46
+ When I press "Save"
47
+ And I view the form on the website
48
+ Then I should see the fields in the order I set
49
+
50
+ Scenario: Response CSV Download
51
+ Given a form exists that has had many responses
52
+ When I visit the form builder admin page
53
+ And I click "Download Responses" on the forms row in the Form List
54
+ Then I should receive a CSV file containing all the responses to that form
@@ -0,0 +1,40 @@
1
+ @website
2
+ Feature: Form Module
3
+ In order to place the forms from the form builder on the website a website
4
+ editor will be able to place a form within a template
5
+
6
+ @javascript
7
+ Scenario: Add Form
8
+ Given forms have been created with the form builder
9
+ And I am editing content
10
+ When I click a "Wide" component slot
11
+ And select the "Contact Form" component
12
+ Then I should see a form select element containing the exisitng forms
13
+ When I select a form
14
+ And I press "Save" within the component
15
+ And I press "Publish"
16
+ When I visit the content page
17
+ Then I should see the form I selected
18
+
19
+ Scenario: Submit Form
20
+ Given content exists with a form added via the contact module
21
+ When a website visitor visits the content
22
+ Then they should see the form
23
+ When they fill in and submit the form
24
+ Then the email address of the form should receive an email detailing the information submitted
25
+ And they should receive an email confirming the request has been sent
26
+ And the response should be stored in the database along with the time submitted, IP address, and page it was submitted from
27
+
28
+ Scenario: Spam Filter
29
+ Given content exists with a form added via the contact module
30
+ When a form response is deemed to be spam
31
+ Then it should marked as spam
32
+ And they should receive no emails
33
+
34
+ Scenario: Validation
35
+ Given content exists with a form added via the contact module
36
+ When a website visitor visits the content
37
+ And they submit the form
38
+ Then it should be checked against the validation speficied in the form builder
39
+ And it should be rejected if the the response does not meet the validation
40
+ And the website visitor should see an error message
@@ -0,0 +1,126 @@
1
+ Given /^the website has been populated with content based on the site map$/ do
2
+ seed_file = File.join(Rails.root, "demo", "seeds.rb")
3
+ load(seed_file)
4
+ end
5
+
6
+ When /^I click on a root$/ do
7
+ @_page = Noodall::Node.roots.last
8
+ within("tbody tr:last") { click_link "Children" }
9
+ end
10
+
11
+ Then /^I should see a list the of the root’s children$/ do
12
+ @_page.children.each do |child|
13
+ page.should have_content(child.title)
14
+ end
15
+ end
16
+
17
+ When /^I click on a child$/ do
18
+ @_child = @_page.children.first
19
+ within(:css, "tbody tr:first") { click_link "Children" }
20
+ end
21
+
22
+ Then /^I should see a list of the child’s children$/ do
23
+ @_child.children.each do |gchild|
24
+ page.should have_content(gchild.title)
25
+ end
26
+ end
27
+
28
+ Then /^I should be able to create a new root$/ do
29
+ click_link 'New'
30
+
31
+ fill_in 'Title', :with => 'New Root'
32
+
33
+ click_button 'Create'
34
+
35
+ page.should have_content(' was successfully created.')
36
+ end
37
+
38
+ Then /^I should see the root listed within the roots$/ do
39
+ visit noodall_admin_nodes_path
40
+ page.should have_content('New Root')
41
+ end
42
+
43
+ Then /^I should be able to create a new child$/ do
44
+ click_link 'New'
45
+
46
+ fill_in 'Title', :with => 'New Child'
47
+
48
+ click_button 'Create'
49
+
50
+ page.should have_content(' was successfully created.')
51
+ end
52
+
53
+ Then /^I should see the child listed within the root’s children$/ do
54
+ visit noodall_admin_node_nodes_path(@_page)
55
+ page.should have_content('New Child')
56
+ end
57
+
58
+ Then /^I should be able to delete content$/ do
59
+ @_deleted_node = Noodall::Node.roots.last
60
+ @_deleted_node_children = @_deleted_node.children
61
+
62
+ within(:css, 'table tbody tr:last') { click_link "Delete" }
63
+ page.should have_content("deleted")
64
+ end
65
+
66
+ Then /^the content and all of it’s sub content will be removed from the website$/ do
67
+
68
+ lambda { visit node_path(@_deleted_node) }.should raise_error(MongoMapper::DocumentNotFound)
69
+
70
+ @_deleted_node_children.each do |child|
71
+ lambda { visit node_path(child) }.should raise_error(MongoMapper::DocumentNotFound)
72
+ end
73
+ end
74
+
75
+ Then /^I should be able to move a child content to another parent$/ do
76
+ @_child = @_page.children.first
77
+ @_new_parent = Noodall::Node.roots.first
78
+ within(:css, "table tbody tr#node-#{@_child.id}") { click_link "Edit" }
79
+ # Simulates what we are now doing with JS
80
+ click_link "Advanced"
81
+ within(:css, '#parent-title' ) { click_link "Edit" }
82
+ within(:css, 'ol.tree' ) { click_link @_new_parent.title }
83
+ click_button 'Draft'
84
+ end
85
+
86
+ Then /^I should see the child listed within the other parent’s children$/ do
87
+ visit noodall_admin_node_nodes_path(@_new_parent)
88
+ within('tbody') do
89
+ page.should have_content(@_child.title)
90
+ end
91
+ end
92
+
93
+ Then /^I should be able change the order of the root’s children$/ do
94
+ table = table(tableish("table tr", 'td, th'))
95
+ title = table.hashes[2]['Title'] # 2 as zero index
96
+ within(:css, 'table tbody tr:nth(3)') { click_link "up" }
97
+ table = table(tableish("table tr", 'td, th'))
98
+ table.hashes[1]['Title'].should == title
99
+ within(:css, 'table tbody tr:nth(2)' ) { click_link "down" }
100
+ within(:css, 'table tbody tr:nth(3)' ) { click_link "down" }
101
+ table = table(tableish("table tr", 'td, th'))
102
+ table.hashes[3]['Title'].should == title
103
+ end
104
+
105
+ When /^I create a new child under an ancestor in "([^"]+)" template$/ do |template_title|
106
+ template = template_title.downcase.gsub(' ','_')
107
+ #create the ancester
108
+ parent = Factory(template.to_sym)
109
+
110
+ visit noodall_admin_node_nodes_path(parent)
111
+ click_link 'New'
112
+ end
113
+
114
+ Then /^I should be able select a template from the "([^"]+)"$/ do |sub_template_string|
115
+ sub_templates = sub_template_string.split(', ')
116
+
117
+ sub_templates.each do |sub_template|
118
+ choose sub_template
119
+ end
120
+ end
121
+
122
+ Then /^I should see a list of the roots$/ do
123
+ Noodall::Node.roots.each do |root|
124
+ page.should have_content(root.title)
125
+ end
126
+ end
@@ -0,0 +1,138 @@
1
+ Given /^I am editing content$/ do
2
+ @_content = Factory(:page_a)
3
+ visit noodall_admin_node_path(@_content)
4
+ end
5
+
6
+ When /^(?:|I )click a "([^"]*)" component slot$/ do |slot_name|
7
+ @_slot_type = slot_name.downcase
8
+ within('ol#slot-list') do
9
+ click_link "#{slot_name} Slot"
10
+ end
11
+ end
12
+
13
+ When /^(?:|I )select the "([^\"]+)" component$/ do |component_name|
14
+ within "#fancybox-inner" do
15
+ select component_name, :from => 'Select the type of component'
16
+ end
17
+ end
18
+
19
+ When /^(?:|I )fill in the following within the component:$/ do |fields|
20
+ within "#fancybox-inner" do
21
+ fields.rows_hash.each do |name, value|
22
+ When %{I fill in "#{name}" with "#{value}"}
23
+ end
24
+ end
25
+ end
26
+
27
+ When /^(?:|I )press "([^"]*)" within the component$/ do |button|
28
+ within "#fancybox-inner" do
29
+ click_button(button)
30
+ end
31
+ end
32
+
33
+ When /^(?:|I )select an image from the asset library$/ do
34
+ asset = Factory(:asset, :title => "My Image")
35
+ within "#fancybox-inner" do
36
+ pending
37
+ end
38
+ end
39
+
40
+ When /^(?:I|a website visitor) visit(?:s|) the content page$/ do
41
+ visit node_path(@_content)
42
+ end
43
+
44
+
45
+ Then /^I should see the general content$/ do
46
+ within("div##{@_slot_type}_slot_0.general-content") do |slot|
47
+ slot.should contain('Test Title One')
48
+ end
49
+ end
50
+
51
+ Then /^I select an image from the asset library$/ do
52
+ within "li.multi-file:last" do
53
+ asset = Factory(:asset, :title => "Image 1")
54
+ set_hidden_field "node[#{@_slot_type}_slot_0][contents][][asset_id]", :to => asset.id
55
+ end
56
+ end
57
+
58
+ Then /^I add some images to from the asset library$/ do
59
+ 5.times do |i|
60
+ Factory(:asset, :title => "Image #{i}")
61
+ end
62
+ page.find(:css, 'span.add-multi-asset').click
63
+ 3.times do |i|
64
+ within "#asset-browser li:nth(#{i + 1})" do
65
+ click_link "Add"
66
+ end
67
+ end
68
+ page.find(:css, 'li.action a').click
69
+ end
70
+
71
+ Then /^I should see the gallery thumbnails$/ do
72
+ page.should have_css("ul.gallery li img", :count => 3)
73
+ end
74
+
75
+
76
+ Given /^content exists with a gallery$/ do
77
+ @_content = Factory(:page_a)
78
+ @_content.small_slot_0 = Factory(:gallery)
79
+ @_content.save
80
+ end
81
+
82
+ Given /^I have not entered a URL for the first image$/ do
83
+ @_content.small_slot_0.contents.first.url = ''
84
+ @_content.save
85
+ end
86
+
87
+ Given /^I have entered a URL for the second image$/ do
88
+ @_content.small_slot_0.contents[1].url = 'http://example.com'
89
+ @_content.save
90
+ end
91
+
92
+ When /^I click on the first image$/ do
93
+ @_image = @_content.small_slot_0.contents.first
94
+ click_link_within("ul.gallery li:first", @_image.title)
95
+ end
96
+
97
+ Then /^I should see a larger version of the image$/ do
98
+ # taadaa
99
+ end
100
+
101
+ When /^I click on the second image$/ do
102
+ @_image = @_content.small_slot_0.contents[1]
103
+ response.should have_selector("ul.gallery li:nth(2) a[href='#{@_image.url}']")
104
+ end
105
+ #
106
+ Then /^I should be taken to the URL location$/ do
107
+ # Link already checked
108
+ end
109
+
110
+ Then /^I select some files from the asset library$/ do
111
+ 3.times do |i|
112
+ within "li.multi-file:last" do
113
+ asset = Factory(:document_asset, :title => "Download #{i+1}")
114
+ set_hidden_field 'node[wide_slot_0][contents][][asset_id]', :to => asset.id
115
+ end
116
+ click_button "Publish"
117
+ visit admin_node_path(@_content)
118
+ end
119
+ end
120
+
121
+ Then /^I should see the list of files$/ do
122
+ @_content.reload
123
+ @_content.wide_slot_0.contents.should have(8).things
124
+ response.should have_selector('ul#download-list li', :count => 8)
125
+ end
126
+
127
+ Then /^each file should have an icon based on file\-type$/ do
128
+ response.should have_selector("ul#download-list li.file-type-#{@_content.wide_slot_0.contents.first.asset.file_mime_type.parameterize}")
129
+ end
130
+
131
+ When /^I click on a file's listing$/ do
132
+ click_link_within("ul#download-list", @_content.wide_slot_0.contents.first.asset.title)
133
+ end
134
+
135
+ Then /^the file should start downloading$/ do
136
+ # ||||||||||||||||||=> done
137
+ end
138
+
@@ -0,0 +1,182 @@
1
+ # Commonly used email steps
2
+ #
3
+ # To add your own steps make a custom_email_steps.rb
4
+ # The provided methods are:
5
+ #
6
+ # last_email_address
7
+ # reset_mailer
8
+ # open_last_email
9
+ # visit_in_email
10
+ # unread_emails_for
11
+ # mailbox_for
12
+ # current_email
13
+ # open_email
14
+ # read_emails_for
15
+ # find_email
16
+ #
17
+ # General form for email scenarios are:
18
+ # - clear the email queue (done automatically by email_spec)
19
+ # - execute steps that sends an email
20
+ # - check the user received an/no/[0-9] emails
21
+ # - open the email
22
+ # - inspect the email contents
23
+ # - interact with the email (e.g. click links)
24
+ #
25
+ # The Cucumber steps below are setup in this order.
26
+
27
+ module EmailHelpers
28
+ def current_email_address
29
+ # Replace with your a way to find your current email. e.g @current_user.email
30
+ # last_email_address will return the last email address used by email spec to find an email.
31
+ # Note that last_email_address will be reset after each Scenario.
32
+ last_email_address || "example@example.com"
33
+ end
34
+ end
35
+
36
+ World(EmailHelpers)
37
+
38
+ #
39
+ # Reset the e-mail queue within a scenario.
40
+ # This is done automatically before each scenario.
41
+ #
42
+
43
+ Given /^(?:a clear email queue|no emails have been sent)$/ do
44
+ reset_mailer
45
+ end
46
+
47
+ #
48
+ # Check how many emails have been sent/received
49
+ #
50
+
51
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails?$/ do |address, amount|
52
+ unread_emails_for(address).size.should == parse_email_count(amount)
53
+ end
54
+
55
+ Then /^(?:I|they|"([^"]*?)") should have (an|no|\d+) emails?$/ do |address, amount|
56
+ mailbox_for(address).size.should == parse_email_count(amount)
57
+ end
58
+
59
+ Then /^(?:I|they|"([^"]*?)") should receive (an|no|\d+) emails? with subject "([^"]*?)"$/ do |address, amount, subject|
60
+ unread_emails_for(address).select { |m| m.subject =~ Regexp.new(subject) }.size.should == parse_email_count(amount)
61
+ end
62
+
63
+ Then /^(?:I|they|"([^"]*?)") should receive an email with the following body:$/ do |address, expected_body|
64
+ open_email(address, :with_text => expected_body)
65
+ end
66
+
67
+ #
68
+ # Accessing emails
69
+ #
70
+
71
+ # Opens the most recently received email
72
+ When /^(?:I|they|"([^"]*?)") opens? the email$/ do |address|
73
+ open_email(address)
74
+ end
75
+
76
+ When /^(?:I|they|"([^"]*?)") opens? the email with subject "([^"]*?)"$/ do |address, subject|
77
+ open_email(address, :with_subject => subject)
78
+ end
79
+
80
+ When /^(?:I|they|"([^"]*?)") opens? the email with text "([^"]*?)"$/ do |address, text|
81
+ open_email(address, :with_text => text)
82
+ end
83
+
84
+ #
85
+ # Inspect the Email Contents
86
+ #
87
+
88
+ Then /^(?:I|they) should see "([^"]*?)" in the email subject$/ do |text|
89
+ current_email.should have_subject(text)
90
+ end
91
+
92
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email subject$/ do |text|
93
+ current_email.should have_subject(Regexp.new(text))
94
+ end
95
+
96
+ Then /^(?:I|they) should see "([^"]*?)" in the email body$/ do |text|
97
+ current_email.body.should include(text)
98
+ end
99
+
100
+ Then /^(?:I|they) should see \/([^"]*?)\/ in the email body$/ do |text|
101
+ current_email.body.should =~ Regexp.new(text)
102
+ end
103
+
104
+ Then /^(?:I|they) should see the email delivered from "([^"]*?)"$/ do |text|
105
+ current_email.should be_delivered_from(text)
106
+ end
107
+
108
+ Then /^(?:I|they) should see "([^\"]*)" in the email "([^"]*?)" header$/ do |text, name|
109
+ current_email.should have_header(name, text)
110
+ end
111
+
112
+ Then /^(?:I|they) should see \/([^\"]*)\/ in the email "([^"]*?)" header$/ do |text, name|
113
+ current_email.should have_header(name, Regexp.new(text))
114
+ end
115
+
116
+ #
117
+ # Inspect the Email Attachments
118
+ #
119
+
120
+ Then /^(?:I|they) should see (an|no|\d+) attachments? with the email$/ do |amount|
121
+ current_email_attachments.size.should == parse_email_count(amount)
122
+ end
123
+
124
+ Then /^there should be (an|no|\d+) attachments? named "([^"]*?)"$/ do |amount, filename|
125
+ current_email_attachments.select { |a| a.original_filename == filename }.size.should == parse_email_count(amount)
126
+ end
127
+
128
+ Then /^attachment (\d+) should be named "([^"]*?)"$/ do |index, filename|
129
+ current_email_attachments[(index.to_i - 1)].original_filename.should == filename
130
+ end
131
+
132
+ Then /^there should be (an|no|\d+) attachments? of type "([^"]*?)"$/ do |amount, content_type|
133
+ current_email_attachments.select { |a| a.content_type == content_type }.size.should == parse_email_count(amount)
134
+ end
135
+
136
+ Then /^attachment (\d+) should be of type "([^"]*?)"$/ do |index, content_type|
137
+ current_email_attachments[(index.to_i - 1)].content_type.should == content_type
138
+ end
139
+
140
+ Then /^all attachments should not be blank$/ do
141
+ current_email_attachments.each do |attachment|
142
+ attachment.size.should_not == 0
143
+ end
144
+ end
145
+
146
+ Then /^show me a list of email attachments$/ do
147
+ EmailSpec::EmailViewer::save_and_open_email_attachments_list(current_email)
148
+ end
149
+
150
+ #
151
+ # Interact with Email Contents
152
+ #
153
+
154
+ When /^(?:I|they) follow "([^"]*?)" in the email$/ do |link|
155
+ visit_in_email(link)
156
+ end
157
+
158
+ When /^(?:I|they) click the first link in the email$/ do
159
+ click_first_link_in_email
160
+ end
161
+
162
+ #
163
+ # Debugging
164
+ # These only work with Rails and OSx ATM since EmailViewer uses RAILS_ROOT and OSx's 'open' command.
165
+ # Patches accepted. ;)
166
+ #
167
+
168
+ Then /^save and open current email$/ do
169
+ EmailSpec::EmailViewer::save_and_open_email(current_email)
170
+ end
171
+
172
+ Then /^save and open all text emails$/ do
173
+ EmailSpec::EmailViewer::save_and_open_all_text_emails
174
+ end
175
+
176
+ Then /^save and open all html emails$/ do
177
+ EmailSpec::EmailViewer::save_and_open_all_html_emails
178
+ end
179
+
180
+ Then /^save and open all raw emails$/ do
181
+ EmailSpec::EmailViewer::save_and_open_all_raw_emails
182
+ end