noodall-form-builder 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +7 -0
- data/Gemfile +24 -0
- data/Gemfile.lock +202 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +39 -0
- data/app/controllers/noodall/admin/fields_controller.rb +21 -0
- data/app/controllers/noodall/admin/form_responses_controller.rb +75 -0
- data/app/controllers/noodall/admin/forms_controller.rb +97 -0
- data/app/controllers/noodall/form_responses_controller.rb +39 -0
- data/app/helpers/admin/forms_helper.rb +2 -0
- data/app/helpers/forms_helper.rb +11 -0
- data/app/mailers/form_mailer.rb +21 -0
- data/app/models/contact_form.rb +16 -0
- data/app/models/noodall/check_box.rb +5 -0
- data/app/models/noodall/field.rb +25 -0
- data/app/models/noodall/form.rb +38 -0
- data/app/models/noodall/form_response.rb +88 -0
- data/app/models/noodall/radio.rb +4 -0
- data/app/models/noodall/select.rb +5 -0
- data/app/models/noodall/text_field.rb +12 -0
- data/app/views/admin/components/_contact_form.html.erb +11 -0
- data/app/views/components/_contact_form.html.erb +8 -0
- data/app/views/form_mailer/_form_response_fields.html.erb +3 -0
- data/app/views/form_mailer/form_response.html.erb +5 -0
- data/app/views/form_mailer/form_response_thankyou.html.erb +19 -0
- data/app/views/noodall/admin/fields/_check_box.html.erb +14 -0
- data/app/views/noodall/admin/fields/_radio.html.erb +14 -0
- data/app/views/noodall/admin/fields/_select.html.erb +14 -0
- data/app/views/noodall/admin/fields/_text_field.html.erb +26 -0
- data/app/views/noodall/admin/form_responses/index.csv.csvbuilder +12 -0
- data/app/views/noodall/admin/form_responses/index.html.erb +41 -0
- data/app/views/noodall/admin/forms/_field_select.html.erb +11 -0
- data/app/views/noodall/admin/forms/index.html.erb +41 -0
- data/app/views/noodall/admin/forms/show.html.erb +138 -0
- data/app/views/noodall/form_responses/_form.html.erb +45 -0
- data/app/views/noodall/form_responses/create.html.erb +5 -0
- data/app/views/noodall/form_responses/new.html.erb +5 -0
- data/app/views/noodall/forms/edit.html.erb +12 -0
- data/app/views/noodall/forms/index.html.erb +18 -0
- data/app/views/noodall/forms/new.html.erb +11 -0
- data/app/views/noodall/forms/show.html.erb +3 -0
- data/cucumber.yml +8 -0
- data/features/form_builder.feature +54 -0
- data/features/form_module.feature +40 -0
- data/features/step_definitions/cms_node_steps.rb +126 -0
- data/features/step_definitions/component_steps.rb +138 -0
- data/features/step_definitions/email_steps.rb +182 -0
- data/features/step_definitions/form_builder_steps.rb +247 -0
- data/features/step_definitions/sign_in_steps.rb +48 -0
- data/features/step_definitions/web_steps.rb +219 -0
- data/features/support/defensio_mock.rb +6 -0
- data/features/support/env.rb +52 -0
- data/features/support/paths.rb +60 -0
- data/lib/noodall/form_builder/engine.rb +13 -0
- data/lib/noodall/form_builder/routes.rb +35 -0
- data/lib/noodall/form_builder/version.rb +5 -0
- data/lib/noodall-form-builder.rb +1 -0
- data/noodall-form-builder.gemspec +23 -0
- data/public/images/admin/spam.png +0 -0
- data/public/javascripts/admin/formbuilder.js +52 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +22 -0
- data/spec/dummy/app/helpers/application_helper.rb +8 -0
- data/spec/dummy/app/models/page_a.rb +8 -0
- data/spec/dummy/app/models/user.rb +14 -0
- data/spec/dummy/app/views/admin/nodes/_page_a.html.erb +47 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/nodes/page_a.html.erb +14 -0
- data/spec/dummy/config/application.rb +46 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +12 -0
- data/spec/dummy/config/defensio.yml +16 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +26 -0
- data/spec/dummy/config/environments/production.rb +49 -0
- data/spec/dummy/config/environments/test.rb +35 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/dragonfly.rb +1 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/mongo_mapper.rb +13 -0
- data/spec/dummy/config/initializers/noodall.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +4 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/factories/asset.rb +6 -0
- data/spec/factories/contact_form.rb +3 -0
- data/spec/factories/field.rb +15 -0
- data/spec/factories/form.rb +13 -0
- data/spec/factories/node.rb +5 -0
- data/spec/factories/response.rb +7 -0
- data/spec/factories/user.rb +15 -0
- data/spec/files/beef.png +0 -0
- data/spec/integration/navigation_spec.rb +9 -0
- data/spec/noodall_form_builder_spec.rb +7 -0
- data/spec/spec_helper.rb +30 -0
- 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
|