contact_us_website 0.4.4.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. data/Gemfile +4 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +117 -0
  4. data/Rakefile +2 -0
  5. data/app/controllers/contact_us/contacts_controller.rb +30 -0
  6. data/app/helpers/contact_us/contacts_helper.rb +2 -0
  7. data/app/mailers/contact_us/contact_mailer.rb +10 -0
  8. data/app/models/contact_us/contact.rb +32 -0
  9. data/app/views/contact_us/contact_mailer/contact_email.html.erb +3 -0
  10. data/app/views/contact_us/contact_mailer/contact_email.text.plain.erb +4 -0
  11. data/app/views/contact_us/contacts/new.html.erb +47 -0
  12. data/app/views/contact_us/contacts/new_formtastic.html.erb +9 -0
  13. data/app/views/contact_us/contacts/new_simple_form.html.erb +9 -0
  14. data/config/locales/contact_us.de.yml +25 -0
  15. data/config/locales/contact_us.en.yml +25 -0
  16. data/config/locales/contact_us.es.yml +25 -0
  17. data/config/locales/contact_us.it.yml +25 -0
  18. data/config/locales/contact_us.ja.yml +25 -0
  19. data/config/locales/contact_us.pt-BR.yml +25 -0
  20. data/config/locales/contact_us.zh.yml +25 -0
  21. data/config/routes.rb +6 -0
  22. data/lib/contact_us.rb +25 -0
  23. data/lib/contact_us/engine.rb +7 -0
  24. data/lib/contact_us/tasks/install.rb +74 -0
  25. data/lib/contact_us/version.rb +3 -0
  26. data/lib/tasks/install.rake +18 -0
  27. data/lib/templates/contact_us.rb +27 -0
  28. data/spec/controllers/contact_us/contact_controller_spec.rb +33 -0
  29. data/spec/dummy/Gemfile +5 -0
  30. data/spec/dummy/Rakefile +7 -0
  31. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  32. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  33. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  34. data/spec/dummy/config.ru +4 -0
  35. data/spec/dummy/config/application.rb +43 -0
  36. data/spec/dummy/config/boot.rb +6 -0
  37. data/spec/dummy/config/database.yml +11 -0
  38. data/spec/dummy/config/environment.rb +5 -0
  39. data/spec/dummy/config/environments/development.rb +26 -0
  40. data/spec/dummy/config/environments/production.rb +49 -0
  41. data/spec/dummy/config/environments/test.rb +35 -0
  42. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  43. data/spec/dummy/config/initializers/inflections.rb +10 -0
  44. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  45. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  46. data/spec/dummy/config/initializers/session_store.rb +8 -0
  47. data/spec/dummy/config/routes.rb +58 -0
  48. data/spec/dummy/public/404.html +26 -0
  49. data/spec/dummy/public/422.html +26 -0
  50. data/spec/dummy/public/500.html +26 -0
  51. data/spec/dummy/public/favicon.ico +0 -0
  52. data/spec/dummy/public/javascripts/application.js +2 -0
  53. data/spec/dummy/public/javascripts/controls.js +965 -0
  54. data/spec/dummy/public/javascripts/dragdrop.js +974 -0
  55. data/spec/dummy/public/javascripts/effects.js +1123 -0
  56. data/spec/dummy/public/javascripts/prototype.js +6001 -0
  57. data/spec/dummy/public/javascripts/rails.js +191 -0
  58. data/spec/dummy/script/rails +6 -0
  59. data/spec/integration/contact_us_lint_spec.rb +144 -0
  60. data/spec/lib/contact_us_spec.rb +52 -0
  61. data/spec/lib/install_spec.rb +42 -0
  62. data/spec/mailers/contact_us/contact_mailer_spec.rb +65 -0
  63. data/spec/models/contact_us/contact_spec.rb +66 -0
  64. data/spec/spec_helper.rb +44 -0
  65. data/spec/support/active_model_lint.rb +17 -0
  66. metadata +276 -0
@@ -0,0 +1,191 @@
1
+ (function() {
2
+ // Technique from Juriy Zaytsev
3
+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
4
+ function isEventSupported(eventName) {
5
+ var el = document.createElement('div');
6
+ eventName = 'on' + eventName;
7
+ var isSupported = (eventName in el);
8
+ if (!isSupported) {
9
+ el.setAttribute(eventName, 'return;');
10
+ isSupported = typeof el[eventName] == 'function';
11
+ }
12
+ el = null;
13
+ return isSupported;
14
+ }
15
+
16
+ function isForm(element) {
17
+ return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
18
+ }
19
+
20
+ function isInput(element) {
21
+ if (Object.isElement(element)) {
22
+ var name = element.nodeName.toUpperCase()
23
+ return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
24
+ }
25
+ else return false
26
+ }
27
+
28
+ var submitBubbles = isEventSupported('submit'),
29
+ changeBubbles = isEventSupported('change')
30
+
31
+ if (!submitBubbles || !changeBubbles) {
32
+ // augment the Event.Handler class to observe custom events when needed
33
+ Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
34
+ function(init, element, eventName, selector, callback) {
35
+ init(element, eventName, selector, callback)
36
+ // is the handler being attached to an element that doesn't support this event?
37
+ if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
38
+ (!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
39
+ // "submit" => "emulated:submit"
40
+ this.eventName = 'emulated:' + this.eventName
41
+ }
42
+ }
43
+ )
44
+ }
45
+
46
+ if (!submitBubbles) {
47
+ // discover forms on the page by observing focus events which always bubble
48
+ document.on('focusin', 'form', function(focusEvent, form) {
49
+ // special handler for the real "submit" event (one-time operation)
50
+ if (!form.retrieve('emulated:submit')) {
51
+ form.on('submit', function(submitEvent) {
52
+ var emulated = form.fire('emulated:submit', submitEvent, true)
53
+ // if custom event received preventDefault, cancel the real one too
54
+ if (emulated.returnValue === false) submitEvent.preventDefault()
55
+ })
56
+ form.store('emulated:submit', true)
57
+ }
58
+ })
59
+ }
60
+
61
+ if (!changeBubbles) {
62
+ // discover form inputs on the page
63
+ document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
64
+ // special handler for real "change" events
65
+ if (!input.retrieve('emulated:change')) {
66
+ input.on('change', function(changeEvent) {
67
+ input.fire('emulated:change', changeEvent, true)
68
+ })
69
+ input.store('emulated:change', true)
70
+ }
71
+ })
72
+ }
73
+
74
+ function handleRemote(element) {
75
+ var method, url, params;
76
+
77
+ var event = element.fire("ajax:before");
78
+ if (event.stopped) return false;
79
+
80
+ if (element.tagName.toLowerCase() === 'form') {
81
+ method = element.readAttribute('method') || 'post';
82
+ url = element.readAttribute('action');
83
+ params = element.serialize();
84
+ } else {
85
+ method = element.readAttribute('data-method') || 'get';
86
+ url = element.readAttribute('href');
87
+ params = {};
88
+ }
89
+
90
+ new Ajax.Request(url, {
91
+ method: method,
92
+ parameters: params,
93
+ evalScripts: true,
94
+
95
+ onComplete: function(request) { element.fire("ajax:complete", request); },
96
+ onSuccess: function(request) { element.fire("ajax:success", request); },
97
+ onFailure: function(request) { element.fire("ajax:failure", request); }
98
+ });
99
+
100
+ element.fire("ajax:after");
101
+ }
102
+
103
+ function handleMethod(element) {
104
+ var method = element.readAttribute('data-method'),
105
+ url = element.readAttribute('href'),
106
+ csrf_param = $$('meta[name=csrf-param]')[0],
107
+ csrf_token = $$('meta[name=csrf-token]')[0];
108
+
109
+ var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
110
+ element.parentNode.insert(form);
111
+
112
+ if (method !== 'post') {
113
+ var field = new Element('input', { type: 'hidden', name: '_method', value: method });
114
+ form.insert(field);
115
+ }
116
+
117
+ if (csrf_param) {
118
+ var param = csrf_param.readAttribute('content'),
119
+ token = csrf_token.readAttribute('content'),
120
+ field = new Element('input', { type: 'hidden', name: param, value: token });
121
+ form.insert(field);
122
+ }
123
+
124
+ form.submit();
125
+ }
126
+
127
+
128
+ document.on("click", "*[data-confirm]", function(event, element) {
129
+ var message = element.readAttribute('data-confirm');
130
+ if (!confirm(message)) event.stop();
131
+ });
132
+
133
+ document.on("click", "a[data-remote]", function(event, element) {
134
+ if (event.stopped) return;
135
+ handleRemote(element);
136
+ event.stop();
137
+ });
138
+
139
+ document.on("click", "a[data-method]", function(event, element) {
140
+ if (event.stopped) return;
141
+ handleMethod(element);
142
+ event.stop();
143
+ });
144
+
145
+ document.on("submit", function(event) {
146
+ var element = event.findElement(),
147
+ message = element.readAttribute('data-confirm');
148
+ if (message && !confirm(message)) {
149
+ event.stop();
150
+ return false;
151
+ }
152
+
153
+ var inputs = element.select("input[type=submit][data-disable-with]");
154
+ inputs.each(function(input) {
155
+ input.disabled = true;
156
+ input.writeAttribute('data-original-value', input.value);
157
+ input.value = input.readAttribute('data-disable-with');
158
+ });
159
+
160
+ var element = event.findElement("form[data-remote]");
161
+ if (element) {
162
+ handleRemote(element);
163
+ event.stop();
164
+ }
165
+ });
166
+
167
+ document.on("ajax:after", "form", function(event, element) {
168
+ var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
169
+ inputs.each(function(input) {
170
+ input.value = input.readAttribute('data-original-value');
171
+ input.removeAttribute('data-original-value');
172
+ input.disabled = false;
173
+ });
174
+ });
175
+
176
+ Ajax.Responders.register({
177
+ onCreate: function(request) {
178
+ var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
179
+
180
+ if (csrf_meta_tag) {
181
+ var header = 'X-CSRF-Token',
182
+ token = csrf_meta_tag.readAttribute('content');
183
+
184
+ if (!request.options.requestHeaders) {
185
+ request.options.requestHeaders = {};
186
+ }
187
+ request.options.requestHeaders[header] = token;
188
+ }
189
+ }
190
+ });
191
+ })();
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3
+
4
+ APP_PATH = File.expand_path('../../config/application', __FILE__)
5
+ require File.expand_path('../../config/boot', __FILE__)
6
+ require 'rails/commands'
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Contact Us page' do
4
+
5
+ after do
6
+ ActionMailer::Base.deliveries = []
7
+ ContactUs.mailer_from = nil
8
+ ContactUs.mailer_to = nil
9
+ ContactUs.require_name = false
10
+ ContactUs.require_subject = false
11
+ end
12
+
13
+ before do
14
+ ActionMailer::Base.deliveries = []
15
+ ContactUs.mailer_to = 'test@test.com'
16
+ end
17
+
18
+ it 'displays default contact form properly' do
19
+ visit contact_us_path
20
+ within "form#new_contact_us_contact" do
21
+ page.should have_selector "input#contact_us_contact_email"
22
+ page.should have_selector "textarea#contact_us_contact_message"
23
+ page.should_not have_selector "input#contact_us_contact_name"
24
+ page.should_not have_selector "input#contact_us_contact_subject"
25
+ page.should have_selector "input.submit"
26
+ end
27
+ end
28
+
29
+ context "Submitting the form" do
30
+
31
+ before do
32
+ visit contact_us_path
33
+ end
34
+
35
+ context "when valid" do
36
+ before do
37
+ fill_in 'Email', :with => 'test@example.com'
38
+ fill_in 'Message', :with => 'howdy'
39
+ click_button 'Submit'
40
+ end
41
+
42
+ it "I should be redirected to the homepage" do
43
+ current_path.should == "/"
44
+ end
45
+
46
+ it "An email should have been sent" do
47
+ ActionMailer::Base.deliveries.size.should == 1
48
+ end
49
+
50
+ it "The email should have the correct attributes" do
51
+ mail = ActionMailer::Base.deliveries.last
52
+ mail.to.should == ['test@test.com']
53
+ mail.from.should == ['test@example.com']
54
+ mail.body.should match 'howdy'
55
+ end
56
+ end
57
+
58
+ context "when invalid" do
59
+ context "Email and message are invalid" do
60
+ before do
61
+ fill_in 'Email', :with => 'a'
62
+ fill_in 'Message', :with => ''
63
+ click_button 'Submit'
64
+ end
65
+
66
+ it "I should see two error messages" do
67
+ within '#contact_us_contact_email_input' do
68
+ page.should have_content "is invalid"
69
+ end
70
+ within '#contact_us_contact_message_input' do
71
+ page.should have_content "can't be blank"
72
+ end
73
+ end
74
+
75
+ it "An email should not have been sent" do
76
+ ActionMailer::Base.deliveries.size.should == 0
77
+ end
78
+ end
79
+ end
80
+ end
81
+
82
+ context 'with name and subject configuration' do
83
+
84
+ before do
85
+ ContactUs.require_name = true
86
+ ContactUs.require_subject = true
87
+ visit contact_us_path
88
+ end
89
+
90
+ it "displays an input for name and subject" do
91
+ page.should have_selector "input#contact_us_contact_name"
92
+ page.should have_selector "input#contact_us_contact_subject"
93
+ end
94
+
95
+ context "Submitting the form" do
96
+ context "when valid" do
97
+ before do
98
+ fill_in 'Email', :with => 'test@example.com'
99
+ fill_in 'Message', :with => 'howdy'
100
+ fill_in 'contact_us_contact[name]', :with => 'Jeff'
101
+ fill_in 'contact_us_contact[subject]', :with => 'Testing contact form.'
102
+ click_button 'Submit'
103
+ end
104
+
105
+ it "I should be redirected to the homepage" do
106
+ current_path.should == "/"
107
+ end
108
+
109
+ it "An email should have been sent" do
110
+ ActionMailer::Base.deliveries.size.should == 1
111
+ end
112
+
113
+ it "The email should have the correct attributes" do
114
+ mail = ActionMailer::Base.deliveries.last
115
+ mail.body.should match 'howdy'
116
+ mail.body.should match 'Jeff'
117
+ mail.from.should == ['test@example.com']
118
+ mail.subject.should match 'Testing contact form.'
119
+ mail.to.should == ['test@test.com']
120
+ end
121
+ end
122
+
123
+ context "when name and subject are blank" do
124
+ before do
125
+ click_button 'Submit'
126
+ end
127
+
128
+ it "I should see error messages" do
129
+ within '#contact_us_contact_name_input' do
130
+ page.should have_content "can't be blank"
131
+ end
132
+ within '#contact_us_contact_subject_input' do
133
+ page.should have_content "can't be blank"
134
+ end
135
+ end
136
+
137
+ it "An email should not have been sent" do
138
+ ActionMailer::Base.deliveries.size.should == 0
139
+ end
140
+ end
141
+ end
142
+ end
143
+
144
+ end
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe ContactUsWebsite do
4
+
5
+ after do
6
+ ContactUsWebsite.mailer_from = nil
7
+ ContactUsWebsite.mailer_to = nil
8
+ ContactUsWebsite.require_name = false
9
+ ContactUsWebsite.require_subject = false
10
+ end
11
+
12
+ it "should be valid" do
13
+ ContactUsWebsite.should be_a(Module)
14
+ end
15
+
16
+ describe 'setup block' do
17
+ it 'should yield self' do
18
+ ContactUsWebsite.setup do |config|
19
+ ContactUsWebsite.should eql(config)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe 'mailer_from' do
25
+ it 'should be configurable' do
26
+ ContactUsWebsite.mailer_from = "contact@please-change-me.com"
27
+ ContactUsWebsite.mailer_from.should eql("contact@please-change-me.com")
28
+ end
29
+ end
30
+
31
+ describe 'mailer_to' do
32
+ it 'should be configurable' do
33
+ ContactUsWebsite.mailer_to = "contact@please-change-me.com"
34
+ ContactUsWebsite.mailer_to.should eql("contact@please-change-me.com")
35
+ end
36
+ end
37
+
38
+ describe 'require_name' do
39
+ it 'should be configurable' do
40
+ ContactUsWebsite.require_name = true
41
+ ContactUsWebsite.require_name.should eql(true)
42
+ end
43
+ end
44
+
45
+ describe 'require_subject' do
46
+ it 'should be configurable' do
47
+ ContactUsWebsite.require_subject = true
48
+ ContactUsWebsite.require_subject.should eql(true)
49
+ end
50
+ end
51
+
52
+ end
@@ -0,0 +1,42 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Rake tasks" do
4
+
5
+ describe "contact_us:install" do
6
+
7
+ after(:each) do
8
+ @destination_root = File.expand_path("../../dummy", __FILE__)
9
+ FileUtils.rm_rf(@destination_root + "/config/initializers/contact_us.rb")
10
+ FileUtils.rm_rf(@destination_root + "/config/locales/contact_us.en.yml")
11
+ FileUtils.rm_rf(@destination_root + "/app/views/contact_us")
12
+ FileUtils.rm_rf(@destination_root + "/app/views/contact_us/contact_mailer")
13
+ FileUtils.rm_rf(@destination_root + "/app/views/contact_us/contacts")
14
+ end
15
+
16
+ before(:each) do
17
+ @destination_root = File.expand_path("../../dummy", __FILE__)
18
+ File.exists?(@destination_root + "/config/initializers/contact_us.rb").should eql(false)
19
+ File.exists?(@destination_root + "/config/locales/contact_us.en.yml").should eql(false)
20
+ File.directory?(@destination_root + "/app/views/contact_us").should eql(false)
21
+ File.directory?(@destination_root + "/app/views/contact_us/contact_mailer").should eql(false)
22
+ File.directory?(@destination_root + "/app/views/contact_us/contacts").should eql(false)
23
+ ContactUs::Tasks::Install.run
24
+ end
25
+
26
+ it "creates initializer file" do
27
+ File.exists?(File.join(@destination_root + "/config/initializers/contact_us.rb")).should eql(true)
28
+ end
29
+
30
+ it "creates locales files" do
31
+ File.exists?(File.join(@destination_root + "/config/locales/contact_us.en.yml")).should eql(true)
32
+ end
33
+
34
+ it "creates view files" do
35
+ File.directory?(@destination_root + "/app/views/contact_us").should eql(true)
36
+ File.directory?(@destination_root + "/app/views/contact_us/contact_mailer").should eql(true)
37
+ File.directory?(@destination_root + "/app/views/contact_us/contacts").should eql(true)
38
+ end
39
+
40
+ end
41
+
42
+ end
@@ -0,0 +1,65 @@
1
+ require 'spec_helper'
2
+
3
+ describe ContactUs::ContactMailer do
4
+
5
+ describe "#contact_email" do
6
+
7
+ before do
8
+ ContactUs.mailer_to = "contact@please-change-me.com"
9
+ @contact = ContactUs::Contact.new(:email => 'test@email.com', :message => 'Thanks!')
10
+ end
11
+
12
+ it "should render successfully" do
13
+ lambda { ContactUs::ContactMailer.contact_email(@contact) }.should_not raise_error
14
+ end
15
+
16
+ it "should use the ContactUs.mailer_from setting when it is set" do
17
+ ContactUs.mailer_from = "contact@please-change-me.com"
18
+ @mailer = ContactUs::ContactMailer.contact_email(@contact)
19
+ @mailer.from.should eql([ContactUs.mailer_from])
20
+ ContactUs.mailer_from = nil
21
+ end
22
+
23
+ describe "rendered without error" do
24
+
25
+ before do
26
+ @mailer = ContactUs::ContactMailer.contact_email(@contact)
27
+ end
28
+
29
+ it "should have the initializers to address" do
30
+ @mailer.to.should eql([ContactUs.mailer_to])
31
+ end
32
+
33
+ it "should use the users email in the from field when ContactUs.mailer_from is not set" do
34
+ @mailer.from.should eql([@contact.email])
35
+ end
36
+
37
+ it "should use the users email in the reply_to field" do
38
+ @mailer.reply_to.should eql([@contact.email])
39
+ end
40
+
41
+ it "should have users email in the subject line" do
42
+ @mailer.subject.should eql("Contact Us message from #{@contact.email}")
43
+ end
44
+
45
+ it "should have the message in the body" do
46
+ @mailer.body.should match("<p>Thanks!</p>")
47
+ end
48
+
49
+ it "should deliver successfully" do
50
+ lambda { ContactUs::ContactMailer.contact_email(@contact).deliver }.should_not raise_error
51
+ end
52
+
53
+ describe "and delivered" do
54
+
55
+ it "should be added to the delivery queue" do
56
+ lambda { ContactUs::ContactMailer.contact_email(@contact).deliver }.should change(ActionMailer::Base.deliveries,:size).by(1)
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ end
64
+
65
+ end