Commit 946bd81026a5103e75454301a0118840015a5d4c
1 parent
f0141cef
Exists in
master
and in
29 other branches
ActionItem791: 'contact us' feature for enterprises
users can send message to enterprises the enterprise must choose if 'contact us' is available or not
Showing
17 changed files
with
223 additions
and
4 deletions
Show diff stats
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +class ContactController < PublicController | ||
2 | + | ||
3 | + needs_profile | ||
4 | + | ||
5 | + def new | ||
6 | + @contact = Contact.new(params[:contact]) | ||
7 | + if request.post? | ||
8 | + if @contact.save | ||
9 | + flash[:notice] = _('Contact successfully sent') | ||
10 | + redirect_to :controller => 'profile', :profile => profile.identifier | ||
11 | + else | ||
12 | + flash[:notice] = _('Contact not sent') | ||
13 | + end | ||
14 | + end | ||
15 | + end | ||
16 | + | ||
17 | +end |
@@ -0,0 +1,13 @@ | @@ -0,0 +1,13 @@ | ||
1 | +class Contact < Task | ||
2 | + | ||
3 | + validates_presence_of :target_id, :subject, :email, :message | ||
4 | + validates_format_of :email, :with => Noosfero::Constants::EMAIL_FORMAT | ||
5 | + | ||
6 | + acts_as_having_settings :field => :data | ||
7 | + settings_items :subject, :message, :city_and_state, :email, :phone | ||
8 | + | ||
9 | + def description | ||
10 | + _('%s sent a new message') % (requestor ? requestor.name : _('Someone')) | ||
11 | + end | ||
12 | + | ||
13 | +end |
app/models/enterprise.rb
@@ -57,7 +57,6 @@ class Enterprise < Organization | @@ -57,7 +57,6 @@ class Enterprise < Organization | ||
57 | end | 57 | end |
58 | end | 58 | end |
59 | 59 | ||
60 | - | ||
61 | def default_set_of_blocks | 60 | def default_set_of_blocks |
62 | blocks = [ | 61 | blocks = [ |
63 | [MainBlock], | 62 | [MainBlock], |
@@ -74,6 +73,8 @@ class Enterprise < Organization | @@ -74,6 +73,8 @@ class Enterprise < Organization | ||
74 | environment.enterprise_template | 73 | environment.enterprise_template |
75 | end | 74 | end |
76 | 75 | ||
76 | + settings_items :enable_contact_us, :type => :boolean, :default => true | ||
77 | + | ||
77 | protected | 78 | protected |
78 | 79 | ||
79 | def default_homepage(attrs) | 80 | def default_homepage(attrs) |
app/views/blocks/profile_info_actions/enterprise.rhtml
@@ -9,4 +9,7 @@ | @@ -9,4 +9,7 @@ | ||
9 | <li><%= link_to content_tag('span', _('Join')), { :profile => user.identifier, :controller => 'memberships', :action => 'join', :id => profile.id }, :class => 'button with-text icon-add', :title => __('Join this enterprise') %></li> | 9 | <li><%= link_to content_tag('span', _('Join')), { :profile => user.identifier, :controller => 'memberships', :action => 'join', :id => profile.id }, :class => 'button with-text icon-add', :title => __('Join this enterprise') %></li> |
10 | <% end %> | 10 | <% end %> |
11 | <% end %> | 11 | <% end %> |
12 | + <% if profile.enable_contact_us %> | ||
13 | + <li> <%= link_to content_tag('span', _('Contact us')), {:profile => profile.identifier, :controller => 'contact', :action => 'new'}, :class => 'button with-text icon-menu-mail' %> </li> | ||
14 | + <% end %> | ||
12 | </ul> | 15 | </ul> |
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +<h1><%= _('Contact %s') % profile.name %></h1> | ||
2 | + | ||
3 | +<%= error_messages_for 'contact' %> | ||
4 | + | ||
5 | +<% labelled_form_for :contact, @contact do |f| %> | ||
6 | + | ||
7 | + <%= hidden_field_tag 'contact[target_id]', profile.id %> | ||
8 | + <%= hidden_field_tag 'contact[requestor_id]', (logged_in? ? current_user.person.id : nil) %> | ||
9 | + <%= f.text_field :subject %> | ||
10 | + <%= f.text_field :email %> | ||
11 | + <%= f.text_field :city_and_state %> | ||
12 | + <%= f.text_field :phone %> | ||
13 | + <%= f.text_area :message, :rows => 5 %> | ||
14 | + | ||
15 | + <%= submit_button(:send, _('Send')) %> | ||
16 | + | ||
17 | +<% end %> |
app/views/profile_editor/_organization.rhtml
@@ -9,12 +9,13 @@ | @@ -9,12 +9,13 @@ | ||
9 | 9 | ||
10 | </div> | 10 | </div> |
11 | <%= f.text_field(:acronym) %> | 11 | <%= f.text_field(:acronym) %> |
12 | - <%= f.text_field(:address, 'size' => 50) if @profile.kind_of?(Enterprise) %> | 12 | + <%= f.text_field(:address, 'size' => 50) if @profile.enterprise? %> |
13 | <%= f.text_field(:foundation_year) %> | 13 | <%= f.text_field(:foundation_year) %> |
14 | <%= f.text_field(:contact_person) %> | 14 | <%= f.text_field(:contact_person) %> |
15 | <%= f.text_field(:contact_email) %> | 15 | <%= f.text_field(:contact_email) %> |
16 | <%= f.text_field(:economic_activity) %> | 16 | <%= f.text_field(:economic_activity) %> |
17 | - <%= f.text_area(:description, :rows => 5) if @profile.kind_of?(Community) %> | 17 | + <%= f.text_area(:description, :rows => 5) if @profile.community? %> |
18 | + <%= f.check_box(:enable_contact_us) if @profile.enterprise? %> | ||
18 | <h1><%= _('Moderation options') %></h1> | 19 | <h1><%= _('Moderation options') %></h1> |
19 | <div style='margin-bottom: 1em'> | 20 | <div style='margin-bottom: 1em'> |
20 | <%= _('New members must be approved:')%> | 21 | <%= _('New members must be approved:')%> |
@@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
1 | +<h2><%= task.description %></h2> | ||
2 | + | ||
3 | +<% form_for('task', task, :url => { :action => 'close', :id => task.id}) do |f| %> | ||
4 | + | ||
5 | + <%= hidden_field_tag(:decision, :finish) %> | ||
6 | + <table> | ||
7 | + <% %w[ subject email phone city_and_state message ].each do |field| %> | ||
8 | + <% if task.respond_to?(field) and !task.send(field).nil? and !task.send(field).empty? %> | ||
9 | + <tr> <td><strong><%= _(field.humanize) %></strong></td> <td><%= task.send(field) %></td> </tr> | ||
10 | + <% end %> | ||
11 | + <% end %> | ||
12 | + </table> | ||
13 | + | ||
14 | + <% button_bar do %> | ||
15 | + <%= submit_button(:ok, _('Ok!')) %> | ||
16 | + <% end %> | ||
17 | + | ||
18 | +<% end %> |
config/routes.rb
@@ -53,6 +53,9 @@ ActionController::Routing::Routes.draw do |map| | @@ -53,6 +53,9 @@ ActionController::Routing::Routes.draw do |map| | ||
53 | map.catalog 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/ | 53 | map.catalog 'catalog/:profile', :controller => 'catalog', :action => 'index', :profile => /#{Noosfero.identifier_format}/ |
54 | map.product 'catalog/:profile/:id', :controller => 'catalog', :action => 'show', :profile => /#{Noosfero.identifier_format}/ | 54 | map.product 'catalog/:profile/:id', :controller => 'catalog', :action => 'show', :profile => /#{Noosfero.identifier_format}/ |
55 | 55 | ||
56 | + # contact | ||
57 | + map.contact 'contact/:profile/:action/:id', :controller => 'contact', :action => 'index', :id => /.*/, :profile => /#{Noosfero.identifier_format}/ | ||
58 | + | ||
56 | ###################################################### | 59 | ###################################################### |
57 | ## Controllers that are profile-specific (for profile admins ) | 60 | ## Controllers that are profile-specific (for profile admins ) |
58 | ###################################################### | 61 | ###################################################### |
public/designs/icons/default/style.css
@@ -5,6 +5,7 @@ | @@ -5,6 +5,7 @@ | ||
5 | .icon-open { background-image: url(folder-open.gif) } | 5 | .icon-open { background-image: url(folder-open.gif) } |
6 | .icon-cms { background-image: url(abiword_48.png) } | 6 | .icon-cms { background-image: url(abiword_48.png) } |
7 | .icon-save { background-image: url(save-HC.gif) } | 7 | .icon-save { background-image: url(save-HC.gif) } |
8 | +.icon-send { background-image: url(mail-HC.gif) } | ||
8 | .icon-up { background-image: url(go-up-HC.gif) } | 9 | .icon-up { background-image: url(go-up-HC.gif) } |
9 | .icon-cancel { background-image: url(cancel-HC.gif) } | 10 | .icon-cancel { background-image: url(cancel-HC.gif) } |
10 | .icon-person { background-image: url(user_icon.png) } | 11 | .icon-person { background-image: url(user_icon.png) } |
@@ -0,0 +1,75 @@ | @@ -0,0 +1,75 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | +require 'contact_controller' | ||
3 | + | ||
4 | +# Re-raise errors caught by the controller. | ||
5 | +class ContactController; def rescue_action(e) raise e end; end | ||
6 | + | ||
7 | +class ContactControllerTest < Test::Unit::TestCase | ||
8 | + | ||
9 | + all_fixtures | ||
10 | + | ||
11 | + def setup | ||
12 | + @controller = ContactController.new | ||
13 | + @request = ActionController::TestRequest.new | ||
14 | + @response = ActionController::TestResponse.new | ||
15 | + | ||
16 | + @profile = create_user('contact_test_user').person | ||
17 | + @enterprise = Enterprise.create!(:identifier => 'contact_test_enterprise', :name => 'Test contact enteprise') | ||
18 | + end | ||
19 | + attr_reader :profile, :enterprise | ||
20 | + | ||
21 | + should 'respond to new' do | ||
22 | + get :new, :profile => enterprise.identifier | ||
23 | + assert_response :success | ||
24 | + end | ||
25 | + | ||
26 | + should 'display destinatary name in title' do | ||
27 | + get :new, :profile => enterprise.identifier | ||
28 | + assert_tag :tag => 'h1', :content => "Contact #{enterprise.name}" | ||
29 | + end | ||
30 | + | ||
31 | + should 'add form to create contact via post' do | ||
32 | + get :new, :profile => enterprise.identifier | ||
33 | + assert_tag :tag => 'form', :attributes => { :action => "/contact/#{enterprise.identifier}/new", :method => 'post' } | ||
34 | + end | ||
35 | + | ||
36 | + should 'display input for destinatary email' do | ||
37 | + get :new, :profile => enterprise.identifier | ||
38 | + assert_tag :tag => 'input', :attributes => { :name => 'contact[email]', :type => 'text' } | ||
39 | + end | ||
40 | + | ||
41 | + should 'display input for message' do | ||
42 | + get :new, :profile => enterprise.identifier | ||
43 | + assert_tag :tag => 'textarea', :attributes => { :name => 'contact[message]' } | ||
44 | + end | ||
45 | + | ||
46 | + should 'add hidden field with target_id' do | ||
47 | + get :new, :profile => enterprise.identifier | ||
48 | + assert_tag :tag => 'input', :attributes => { :name => 'contact[target_id]', :value => enterprise.id, :type => 'hidden' } | ||
49 | + end | ||
50 | + | ||
51 | + should 'add requestor id if logged in' do | ||
52 | + login_as(profile.identifier) | ||
53 | + @controller.stubs(:current_user).returns(profile.user) | ||
54 | + get :new, :profile => enterprise.identifier | ||
55 | + assert_tag :tag => 'input', :attributes => { :name => 'contact[requestor_id]', :value => profile.id } | ||
56 | + end | ||
57 | + | ||
58 | + should 'nil requestor id if not logged in' do | ||
59 | + get :new, :profile => enterprise.identifier | ||
60 | + assert_tag :tag => 'input', :attributes => { :name => 'contact[requestor_id]', :value => nil } | ||
61 | + end | ||
62 | + | ||
63 | + should 'redirect to profile page after contact' do | ||
64 | + post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :email => 'visitor@mail.invalid', :message => 'Hi, all', :target_id => enterprise.id} | ||
65 | + assert_response :redirect | ||
66 | + assert_redirected_to :controller => 'profile', :profile => enterprise.identifier | ||
67 | + end | ||
68 | + | ||
69 | + should 'be able to send contact' do | ||
70 | + assert_difference Contact, :count do | ||
71 | + post :new, :profile => enterprise.identifier, :contact => {:subject => 'Hi', :email => 'visitor@mail.invalid', :message => 'Hi, all', :target_id => enterprise.id} | ||
72 | + end | ||
73 | + end | ||
74 | + | ||
75 | +end |
test/functional/profile_controller_test.rb
@@ -249,7 +249,7 @@ class ProfileControllerTest < Test::Unit::TestCase | @@ -249,7 +249,7 @@ class ProfileControllerTest < Test::Unit::TestCase | ||
249 | get :index, :profile => 'my-test-enterprise' | 249 | get :index, :profile => 'my-test-enterprise' |
250 | assert_tag :tag => 'a', :attributes => { :href => '/catalog/my-test-enterprise'}, :content => /Products\/Services/ | 250 | assert_tag :tag => 'a', :attributes => { :href => '/catalog/my-test-enterprise'}, :content => /Products\/Services/ |
251 | end | 251 | end |
252 | - | 252 | + |
253 | should 'not display "Products" link for enterprise if environment do not let' do | 253 | should 'not display "Products" link for enterprise if environment do not let' do |
254 | env = Environment.default | 254 | env = Environment.default |
255 | env.enable('disable_products_for_enterprises') | 255 | env.enable('disable_products_for_enterprises') |
@@ -304,4 +304,21 @@ class ProfileControllerTest < Test::Unit::TestCase | @@ -304,4 +304,21 @@ class ProfileControllerTest < Test::Unit::TestCase | ||
304 | assert_no_tag :content => /t2@t2.com/ | 304 | assert_no_tag :content => /t2@t2.com/ |
305 | end | 305 | end |
306 | 306 | ||
307 | + should 'display contact us for enterprises' do | ||
308 | + ent = Enterprise.create!(:name => 'my test enterprise', :identifier => 'my-test-enterprise') | ||
309 | + get :index, :profile => 'my-test-enterprise' | ||
310 | + assert_tag :tag => 'a', :attributes => { :href => "/contact/my-test-enterprise/new" }, :content => 'Contact us' | ||
311 | + end | ||
312 | + | ||
313 | + should 'not display contact us for non-enterprises' do | ||
314 | + get :index, :profile => @profile.identifier | ||
315 | + assert_no_tag :tag => 'a', :attributes => { :href => "/contact/#{@profile.identifier}/new" }, :content => 'Contact us' | ||
316 | + end | ||
317 | + | ||
318 | + should 'display contact us only if enabled' do | ||
319 | + ent = Enterprise.create!(:name => 'my test enterprise', :identifier => 'my-test-enterprise', :enable_contact_us => false) | ||
320 | + get :index, :profile => 'my-test-enterprise' | ||
321 | + assert_no_tag :tag => 'a', :attributes => { :href => "/contact/my-test-enterprise/new" }, :content => 'Contact us' | ||
322 | + end | ||
323 | + | ||
307 | end | 324 | end |
test/functional/profile_editor_controller_test.rb
@@ -517,4 +517,10 @@ class ProfileEditorControllerTest < Test::Unit::TestCase | @@ -517,4 +517,10 @@ class ProfileEditorControllerTest < Test::Unit::TestCase | ||
517 | :attributes => { :name=>'profile_data[email]', :value=>'teste_user@teste.com' } | 517 | :attributes => { :name=>'profile_data[email]', :value=>'teste_user@teste.com' } |
518 | end | 518 | end |
519 | 519 | ||
520 | + should 'display enable contact us for enterprise' do | ||
521 | + org = Enterprise.create!(:name => 'test org', :identifier => 'testorg') | ||
522 | + get :edit, :profile => 'testorg' | ||
523 | + assert_tag :tag => 'input', :attributes => {:name => 'profile_data[enable_contact_us]', :type => 'checkbox'} | ||
524 | + end | ||
525 | + | ||
520 | end | 526 | end |
test/functional/tasks_controller_test.rb
@@ -151,4 +151,16 @@ class TasksControllerTest < Test::Unit::TestCase | @@ -151,4 +151,16 @@ class TasksControllerTest < Test::Unit::TestCase | ||
151 | 151 | ||
152 | assert_equal f, assigns(:ticket).target | 152 | assert_equal f, assigns(:ticket).target |
153 | end | 153 | end |
154 | + | ||
155 | + should 'list enterprise contacts' do | ||
156 | + ent = Enterprise.create!(:identifier => 'contact_test_enterprise', :name => 'Test contact enteprise') | ||
157 | + task = Contact.create!(:subject => 'test', :target_id => profile.id, :email => 'visitor@invalid.com', :message => 'Hi, all') | ||
158 | + | ||
159 | + login_as(profile.identifier) | ||
160 | + get :index, :profile => ent.identifier | ||
161 | + | ||
162 | + assert_includes assigns(:tasks), task | ||
163 | + assert_tag :tag => 'li', :attributes => { :class => 'task-Contact' }, :content => 'Someone sent a new message' | ||
164 | + end | ||
165 | + | ||
154 | end | 166 | end |
test/integration/routing_test.rb
@@ -186,4 +186,8 @@ class RoutingTest < ActionController::IntegrationTest | @@ -186,4 +186,8 @@ class RoutingTest < ActionController::IntegrationTest | ||
186 | assert_routing('/myprofile/profile.withdot', :controller => 'profile_editor', :action => 'index', :profile => 'profile.withdot') | 186 | assert_routing('/myprofile/profile.withdot', :controller => 'profile_editor', :action => 'index', :profile => 'profile.withdot') |
187 | end | 187 | end |
188 | 188 | ||
189 | + def test_contact_routing | ||
190 | + assert_routing('/contact/wintermute/new', :controller => 'contact', :action => 'new', :profile => 'wintermute') | ||
191 | + end | ||
192 | + | ||
189 | end | 193 | end |
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +require File.dirname(__FILE__) + '/../test_helper' | ||
2 | + | ||
3 | +class ContactTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + should 'have serialized data' do | ||
6 | + t = Contact.new | ||
7 | + t.data[:test] = 'test' | ||
8 | + | ||
9 | + assert_equal({:test => 'test'}, t.data) | ||
10 | + end | ||
11 | + | ||
12 | + should 'validates required fields' do | ||
13 | + contact = Contact.new | ||
14 | + assert !contact.valid? | ||
15 | + contact.subject = 'Hi' | ||
16 | + assert !contact.valid? | ||
17 | + contact.email = 'visitor@invalid.com' | ||
18 | + assert !contact.valid? | ||
19 | + contact.message = 'Hi, all' | ||
20 | + assert !contact.valid? | ||
21 | + contact.target = create_user('contact_user_test').person | ||
22 | + assert contact.save! | ||
23 | + end | ||
24 | + | ||
25 | +end |
test/unit/enterprise_test.rb
@@ -211,5 +211,9 @@ class EnterpriseTest < Test::Unit::TestCase | @@ -211,5 +211,9 @@ class EnterpriseTest < Test::Unit::TestCase | ||
211 | assert_kind_of Enterprise, p.template | 211 | assert_kind_of Enterprise, p.template |
212 | end | 212 | end |
213 | 213 | ||
214 | + should 'contact us enabled by default' do | ||
215 | + e = Enterprise.create!(:name => 'test_com', :identifier => 'test_com', :environment => Environment.default) | ||
216 | + assert e.enable_contact_us | ||
217 | + end | ||
214 | 218 | ||
215 | end | 219 | end |