Commit 97db792e350fc9dad1b30214d89d2f772e67a4a3

Authored by Antonio Terceiro
1 parent f7d6ffda

ActionItem1032: allowing login with custom domain

app/controllers/my_profile/profile_editor_controller.rb
... ... @@ -11,6 +11,7 @@ class ProfileEditorController < MyProfileController
11 11 # edits the profile info (posts back)
12 12 def edit
13 13 @profile_data = profile
  14 + @possible_domains = profile.possible_domains
14 15 if request.post?
15 16 if profile.update_attributes(params[:profile_data])
16 17 redirect_to :action => 'index'
... ...
app/helpers/application_helper.rb
... ... @@ -130,21 +130,6 @@ module ApplicationHelper
130 130 link_to text, p.url, options
131 131 end
132 132  
133   - def link_to_myprofile(text, url = {}, profile = nil, options = {})
134   - p = if profile
135   - Profile[profile]
136   - else
137   - user
138   - end
139   - link_to text, p.admin_url.merge(url), options
140   - end
141   -
142   - def link_to_document(doc, text = nil, html_options = {}, url_options = {})
143   - text ||= doc.title
144   - path = doc.path.split(/\//)
145   - link_to text, homepage_path({:profile => doc.profile.identifier , :page => path, :view => true}.merge(url_options)), html_options
146   - end
147   -
148 133 def link_if_permitted(link, permission = nil, target = nil)
149 134 if permission.nil? || current_user.person.has_permission?(permission, target)
150 135 link
... ... @@ -736,9 +721,7 @@ module ApplicationHelper
736 721 end
737 722  
738 723 def login_url
739   - options = { :controller => 'account', :action => 'login' }
740   - options.merge!(:protocol => 'https://', :host => request.host) unless ENV['RAILS_ENV'] == 'development' || environment.disable_ssl
741   - url_for(options)
  724 + url_for(Noosfero.url_options.merge({ :controller => 'account', :action => 'login', :host => request.host }))
742 725 end
743 726  
744 727 def base_url
... ...
app/helpers/profile_editor_helper.rb
... ... @@ -117,4 +117,20 @@ module ProfileEditorHelper
117 117 select(object, method, [[_('[Select ...]'), nil]] + ProfileEditorHelper::SCHOOLING_STATUS.map{|s| [gettext(s), s]}, {}, options)
118 118 end
119 119  
  120 + def select_preferred_domain(object)
  121 + profile = instance_variable_get("@#{object}")
  122 + domains = []
  123 + if profile
  124 + if profile.preferred_domain
  125 + # FIXME should be able to change
  126 + return ''
  127 + else
  128 + domains = profile.possible_domains
  129 + end
  130 + else
  131 + domains = environment.domains
  132 + end
  133 + labelled_form_field(__('Preferred domain name:'), select(object, :preferred_domain_id, domains.map {|item| [item.name, item.id]}, :prompt => '<' + _('Select domain') + '>'))
  134 + end
  135 +
120 136 end
... ...
app/models/domain.rb
... ... @@ -63,4 +63,25 @@ class Domain < ActiveRecord::Base
63 63 end
64 64 end
65 65  
  66 + @hosting = {}
  67 +
  68 + # Tells whether the given domain name is hosting a profile or not.
  69 + #
  70 + # Since this is going to be called a lot, The queries are cached so the
  71 + # database is hit only for the first query for a given domain name. This way,
  72 + # transfering a domain from a profile to an environment of vice-versa
  73 + # requires restarting the application.
  74 + def self.hosting_profile_at(domainname)
  75 + @hosting[domainname] ||=
  76 + begin
  77 + domain = Domain.find_by_name(domainname)
  78 + !domain.nil? && (domain.owner_type == 'Profile')
  79 + end
  80 + end
  81 +
  82 + # clears the cache of hosted domains. Used for testing.
  83 + def self.clear_cache
  84 + @hosting = {}
  85 + end
  86 +
66 87 end
... ...
app/models/environment.rb
... ... @@ -45,6 +45,7 @@ class Environment < ActiveRecord::Base
45 45 'warn_obsolete_browser' => _('Enable warning of obsolete browser'),
46 46 'wysiwyg_editor_for_environment_home' => _('Use WYSIWYG editor to edit environment home page'),
47 47 'media_panel' => _('Media panel in WYSIWYG editor'),
  48 + 'select_preferred_domain' => _('Select preferred domains per profile'),
48 49 }
49 50 end
50 51  
... ...
app/models/person.rb
... ... @@ -42,6 +42,7 @@ class Person < Profile
42 42 end
43 43  
44 44 FIELDS = %w[
  45 + preferred_domain
45 46 nickname
46 47 sex
47 48 address
... ...
app/models/profile.rb
... ... @@ -94,6 +94,7 @@ class Profile < ActiveRecord::Base
94 94 belongs_to :user
95 95  
96 96 has_many :domains, :as => :owner
  97 + belongs_to :preferred_domain, :class_name => 'Domain', :foreign_key => 'preferred_domain_id'
97 98 belongs_to :environment
98 99  
99 100 has_many :articles, :dependent => :destroy
... ... @@ -327,19 +328,15 @@ class Profile < ActiveRecord::Base
327 328 end
328 329  
329 330 def url
330   - @url ||= if self.domains.empty?
331   - generate_url(:controller => 'content_viewer', :action => 'view_page', :page => [])
332   - else
333   - Noosfero.url_options.merge({ :host => self.domains.first.name, :controller => 'content_viewer', :action => 'view_page', :page => []})
334   - end
  331 + @url ||= generate_url(:controller => 'content_viewer', :action => 'view_page', :page => [])
335 332 end
336 333  
337 334 def admin_url
338   - generate_url(:controller => 'profile_editor', :action => 'index')
  335 + { :profile => identifier, :controller => 'profile_editor', :action => 'index' }
339 336 end
340 337  
341 338 def public_profile_url
342   - generate_url(:controller => 'profile', :action => 'index')
  339 + generate_url(:profile => identifier, :controller => 'profile', :action => 'index')
343 340 end
344 341  
345 342 def generate_url(options)
... ... @@ -347,7 +344,25 @@ class Profile < ActiveRecord::Base
347 344 end
348 345  
349 346 def url_options
350   - Noosfero.url_options.merge({ :host => self.environment.default_hostname, :profile => self.identifier})
  347 + options = { :host => default_hostname, :profile => (hostname ? nil : self.identifier) }
  348 + Noosfero.url_options.merge(options)
  349 + end
  350 +
  351 + def default_hostname
  352 + @default_hostname ||= (hostname || environment.default_hostname)
  353 + end
  354 +
  355 + def hostname
  356 + if preferred_domain
  357 + return preferred_domain.name
  358 + else
  359 + domain = self.domains.first
  360 + domain ? domain.name : nil
  361 + end
  362 + end
  363 +
  364 + def possible_domains
  365 + environment.domains + domains
351 366 end
352 367  
353 368 # FIXME this can be SLOW
... ...
app/models/profile_list_block.rb
... ... @@ -64,12 +64,10 @@ class ProfileListBlock < Block
64 64 title = self.title
65 65 nl = "\n"
66 66 lambda do
67   - #list = profiles.map {|item| content_tag( 'li', profile_image_link(item) ) }.join("\n ")
68 67 count=0
69 68 list = profiles.map {|item|
70 69 count+=1
71 70 profile_image_link( item ) #+
72   - #( ( count%2 == 0 && count < profiles.size ) ? nl+'</tr><tr>' : '' )
73 71 }.join("\n ")
74 72 if list.empty?
75 73 list = '<div class="common-profile-list-block-none">'+ _('None') +'</div>'
... ...
app/views/account/index.rhtml
... ... @@ -6,7 +6,7 @@
6 6 </p>
7 7  
8 8 <p>
9   -<%= link_to_myprofile _('Edit Personal details.'), :controller => 'profile_editor' %>
  9 +<%= link_to _('Edit Personal details.'), :controller => 'profile_editor', :profile => user.identifier, :action => 'index' %>
10 10 <%= _('You can change your personal details.') %>
11 11 </p>
12 12  
... ... @@ -16,7 +16,7 @@
16 16 </p>
17 17  
18 18 <p>
19   -<%= link_to_myprofile(_('Manage content.'), :controller => 'cms') %>
  19 +<%= link_to(_('Manage content.'), :controller => 'cms', :profile => user.identifier, :action => 'index') %>
20 20 <%= _('Manage your content.') %>
21 21 </p>
22 22  
... ...
app/views/blocks/profile_info.rhtml
... ... @@ -19,7 +19,7 @@
19 19 <li><%= link_to _('View profile'), block.owner.public_profile_url %></li>
20 20 <li><%= link_to(_('Products/Services'), :controller => 'catalog', :profile => block.owner.identifier) if block.owner.enterprise? && !block.owner.environment.enabled?('disable_products_for_enterprises') %></li>
21 21 <% if !user.nil? and user.has_permission?('edit_profile', profile) %>
22   - <li><%= link_to _('Control panel'), :controller => 'profile_editor' %></li>
  22 + <li><%= link_to _('Control panel'), block.owner.admin_url %></li>
23 23 <% end %>
24 24 <% if profile.person? %>
25 25 <li><%= _('Since %{year}/%{month}') % { :year => block.owner.created_at.year, :month => block.owner.created_at.month } %></li>
... ...
app/views/cms/view.rhtml
... ... @@ -7,7 +7,7 @@
7 7 <h1 id='article-full-path'>
8 8 <%= icon('cms') %>
9 9 <%= link_to profile.identifier, :action => 'index' %>
10   - <%= @article.hierarchy.map {|item| " / " + ((item == @article) ? item.name : link_to_document(item)) } %>
  10 + <%= @article.hierarchy.map {|item| " / " + ((item == @article) ? item.name : link_to(item.slug, :id => item.id)) } %>
11 11 </h1>
12 12 <% end %>
13 13  
... ... @@ -42,7 +42,7 @@
42 42 </td>
43 43 <td>
44 44 <%= link_to _('Properties'), :action => 'edit', :id => folder.id %>
45   - <%= link_to_document(folder, _('Public view')) %>
  45 + <%= link_to _('Public view'), folder.url %>
46 46 <%= link_to _('Use as homepage'), { :action => 'set_home_page', :id => folder.id }, :method => :post %>
47 47 <%= link_to _('Delete'), { :action => 'destroy', :id => folder.id }, :method => :post, :confirm => _('Are you sure that you want to remove this folder? Note that all the items inside it will also be removed!') %>
48 48 </td>
... ... @@ -68,7 +68,7 @@
68 68 </td>
69 69 <td>
70 70 <%= link_to _('Edit'), :action => 'edit', :id => item.id %>
71   - <%= link_to_document(item, _('Public view')) %>
  71 + <%= link_to _('Public view'), item.url %>
72 72 <%= link_to _('Spread this'), :action => 'publish', :id => item.id %>
73 73 <%= link_to _('Use as homepage'), { :action => 'set_home_page', :id => item.id }, :method => :post %>
74 74 <%= link_to _('Delete'), { :action => 'destroy', :id => item.id }, :method => :post, :confirm => _('Are you sure that you want to remove this item?') %>
... ...
app/views/content_viewer/_article.rhtml
1   -<%= link_to_document(article, '', :class => article.css_class_name) %>
2   -<span><%= link_to_document(article) %></span>
  1 +<%= link_to '', article.url, '', :class => article.css_class_name) %>
  2 +<span><%= link_to article.title, article.view_url %></span>
... ...
app/views/content_viewer/_uploaded_file.rhtml
1 1 <% if uploaded_file.image? %>
2   - <div> <%= link_to_document(uploaded_file, image_tag(uploaded_file.public_filename(:thumb))) %> </div>
  2 + <div> <%= link_to image_tag(uploaded_file.public_filename(:thumb)), uploaded_file.view_url %> </div>
3 3 <% else %>
4 4 <%= render :partial => 'article', :object => uploaded_file %>
5 5 <% end %>
... ...
app/views/content_viewer/view_page.rhtml
... ... @@ -34,24 +34,24 @@
34 34 <div id="article-actions" class="hidden">
35 35 <% unless @page.blog? %>
36 36 <%= link_to content_tag( 'span', label_for_edit_article(@page) ),
37   - { :controller => 'cms', :action => 'edit', :id => @page },
  37 + profile.admin_url.merge({ :controller => 'cms', :action => 'edit', :id => @page.id }),
38 38 :class => 'button with-text icon-edit' %>
39 39 <% end %>
40 40 <% if !(profile.kind_of?(Enterprise) && environment.enabled?('disable_cms')) %>
41 41 <% if @page != profile.home_page %>
42 42 <%= link_to content_tag( 'span', _('Delete') ),
43   - { :controller => 'cms', :action => 'destroy', :id => @page },
  43 + profile.admin_url.merge({ :controller => 'cms', :action => 'destroy', :id => @page }),
44 44 :class => 'button with-text icon-delete' %>
45 45 <% end %>
46 46 <% if profile.kind_of?(Person) && !environment.enabled?('disable_cms') %>
47 47 <%= link_to content_tag( 'span', _('Spread this') ),
48   - { :controller => 'cms', :action => 'publish', :id => @page },
  48 + profile.admin_url.merge({ :controller => 'cms', :action => 'publish', :id => @page }),
49 49 :class => 'button with-text icon-spread' %>
50 50 <% end %>
51 51 <% if @page.display_as_gallery? %>
52   - <%= button('upload-file', _('Upload files'), :controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent)) %>
  52 + <%= button('upload-file', _('Upload files'), profile.admin_url.merge(:controller => 'cms', :action => 'upload_files', :parent_id => (@page.folder? ? @page : @page.parent))) %>
53 53 <% else %>
54   - <%= lightbox_button(:new, label_for_new_article(@page), :controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent))) %>
  54 + <%= lightbox_button(:new, label_for_new_article(@page), profile.admin_url.merge(:controller => 'cms', :action => 'new', :parent_id => (@page.folder? ? @page : (@page.parent.nil? ? nil : @page.parent)))) %>
55 55 <% end %>
56 56 <% end %>
57 57 </div>
... ... @@ -73,7 +73,7 @@
73 73  
74 74 <% if @page.parent && !@page.parent.path.blank? %>
75 75 <div id="article-parent">
76   - <%= link_to_document(@page.parent, _('Go back')) %>
  76 + <%= link_to _('Go back'), @page.parent.url %>
77 77 </div>
78 78 <% end %>
79 79  
... ...
app/views/layouts/application.rhtml
... ... @@ -49,7 +49,6 @@
49 49 <%= icon_theme_stylesheet_tag %>
50 50  
51 51 <%= stylesheet_link_tag 'iepngfix/iepngfix.css' %>
52   - <base href="<%= base_url %>"/>
53 52 </head>
54 53  
55 54 <body class='noosfero category<%= category_color %><%=
... ... @@ -110,7 +109,7 @@
110 109  
111 110 <div id="navigation_bar">
112 111 <%= link_to "<span>"+ @environment.name() +"</span>",
113   - { :controller=>"home" },
  112 + @environment.top_url,
114 113 :id=>"menu_link_to_envhome",
115 114 :title=>@environment.name %>
116 115 <% unless environment.enabled?(:disable_categories) %>
... ...
app/views/manage_products/index.rhtml
... ... @@ -47,6 +47,6 @@
47 47 <%= button :add, _('Add raw material'), :action => 'new_consumption' %>
48 48  
49 49 <p>
50   -<%= link_to_myprofile( '<span>'+ _('Back') +'</span>', {}, @profile.identifier, :class => 'button with-text icon-back' ) %>
  50 +<%= link_to( '<span>'+ _('Back') +'</span>', { :controller => 'profile_editor', :profile => @profile.identifier, :action => 'index' }, :class => 'button with-text icon-back' ) %>
51 51 </p>
52 52  
... ...
app/views/profile_editor/_person_form.rhtml
... ... @@ -9,6 +9,7 @@
9 9 </div>
10 10 <% end %>
11 11  
  12 +<%= optional_field(@person, 'preferred_domain', select_preferred_domain(:profile_data)) %>
12 13 <%= optional_field(@person, 'contact_information', f.text_field(:contact_information)) %>
13 14 <%= optional_field(@person, 'contact_phone', labelled_form_field(_('Home phone'), text_field(:profile_data, :contact_phone))) %>
14 15 <%= optional_field(@person, 'cell_phone', f.text_field(:cell_phone)) %>
... ...
app/views/profile_editor/edit.rhtml
... ... @@ -13,6 +13,7 @@
13 13 <% end %>
14 14 </div>
15 15  
  16 +
16 17 <h2><%= _('Privacy options') %></h2>
17 18 <p>
18 19 <%= _('This profile is:') %>
... ...
app/views/shared/user_menu.rhtml
... ... @@ -27,10 +27,9 @@
27 27 </li>
28 28 <% end %>
29 29  
30   - <li><%= link_to_myprofile( '<span class="icon-menu-ctrl-panel"></span>'+ _('Control panel'),
31   - {}, nil, :id => 'link_edit_profile',
32   - :help => _('Control panel: change your picture, edit your personal information, create content or change the way your home page looks.')
33   - ) %></li>
  30 + <li>
  31 + <%= link_to('<span class="icon-menu-ctrl-panel"></span>'+ _('Control panel'), { :controller => 'profile_editor', :action => 'index', :profile => user.identifier }, :id => 'link_edit_profile', :help => _('Control panel: change your picture, edit your personal information, create content or change the way your home page looks.')) %>
  32 + </li>
34 33  
35 34 <% if user.is_admin?(environment) %>
36 35 <li><%= link_to( '<span class="icon-menu-"></span>'+ _('Admin'),
... ...
config/routes.rb
... ... @@ -15,18 +15,11 @@ ActionController::Routing::Routes.draw do |map|
15 15 ## Public controllers
16 16 ######################################################
17 17  
18   - # You can have the root of your site routed by hooking up ''
19   - hosted_domain_matcher = lambda do |env|
20   - domain = Domain.find_by_name(env[:host])
21   - domain && (domain.owner_type == 'Profile')
22   - end
23   - map.connect 'profile/:profile/:action/:id', :controller => 'profile', :id => /.*/, :profile => /#{Noosfero.identifier_format}/, :conditions => { :if => hosted_domain_matcher }
24   - map.connect '*page', :controller => 'content_viewer', :action => 'view_page', :conditions => { :if => hosted_domain_matcher }
25   -
26 18 map.connect 'test/:controller/:action/:id' , :controller => /.*test.*/
27 19  
28 20 # -- just remember to delete public/index.html.
29   - map.connect '', :controller => "home"
  21 + # You can have the root of your site routed by hooking up ''
  22 + map.connect '', :controller => "home", :conditions => { :if => lambda { |env| !Domain.hosting_profile_at(env[:host]) } }
30 23  
31 24 # user account controller
32 25 map.connect 'account/new_password/:code', :controller => 'account', :action => 'new_password'
... ... @@ -83,7 +76,9 @@ ActionController::Routing::Routes.draw do |map|
83 76 # cache stuff - hack
84 77 map.cache 'public/:action/:id', :controller => 'public'
85 78  
86   - # *content viewing*
  79 + # match requests for content in domains hosted for profiles
  80 + map.connect '*page', :controller => 'content_viewer', :action => 'view_page', :conditions => { :if => lambda { |env| Domain.hosting_profile_at(env[:host])} }
  81 +
87 82 # XXX this route must come last so other routes have priority over it.
88 83 map.homepage ':profile/*page', :controller => 'content_viewer', :action => 'view_page', :profile => /#{Noosfero.identifier_format}/
89 84  
... ...
db/schema.rb
... ... @@ -9,7 +9,7 @@
9 9 #
10 10 # It's strongly recommended to check this file into your version control system.
11 11  
12   -ActiveRecord::Schema.define(:version => 65) do
  12 +ActiveRecord::Schema.define(:version => 66) do
13 13  
14 14 create_table "article_versions", :force => true do |t|
15 15 t.integer "article_id"
... ... @@ -87,8 +87,8 @@ ActiveRecord::Schema.define(:version =&gt; 65) do
87 87 t.boolean "virtual", :default => false
88 88 end
89 89  
90   - add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id"
91 90 add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id"
  91 + add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id"
92 92  
93 93 create_table "blocks", :force => true do |t|
94 94 t.string "title"
... ... @@ -128,8 +128,8 @@ ActiveRecord::Schema.define(:version =&gt; 65) do
128 128 t.boolean "virtual", :default => false
129 129 end
130 130  
131   - add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id"
132 131 add_index "categories_profiles", ["category_id"], :name => "index_categories_profiles_on_category_id"
  132 + add_index "categories_profiles", ["profile_id"], :name => "index_categories_profiles_on_profile_id"
133 133  
134 134 create_table "comments", :force => true do |t|
135 135 t.string "title"
... ... @@ -207,8 +207,8 @@ ActiveRecord::Schema.define(:version =&gt; 65) do
207 207 t.datetime "updated_at"
208 208 end
209 209  
210   - add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id"
211 210 add_index "product_categorizations", ["category_id"], :name => "index_product_categorizations_on_category_id"
  211 + add_index "product_categorizations", ["product_id"], :name => "index_product_categorizations_on_product_id"
212 212  
213 213 create_table "products", :force => true do |t|
214 214 t.integer "enterprise_id"
... ... @@ -230,7 +230,7 @@ ActiveRecord::Schema.define(:version =&gt; 65) do
230 230 t.string "type"
231 231 t.string "identifier"
232 232 t.integer "environment_id"
233   - t.boolean "active", :default => true
  233 + t.boolean "active", :default => true
234 234 t.string "address"
235 235 t.string "contact_phone"
236 236 t.integer "home_page_id"
... ... @@ -241,13 +241,14 @@ ActiveRecord::Schema.define(:version =&gt; 65) do
241 241 t.float "lat"
242 242 t.float "lng"
243 243 t.integer "geocode_precision"
244   - t.boolean "enabled", :default => true
245   - t.string "nickname", :limit => 16
  244 + t.boolean "enabled", :default => true
  245 + t.string "nickname", :limit => 16
246 246 t.text "custom_header"
247 247 t.text "custom_footer"
248 248 t.string "theme"
249   - t.boolean "public_profile", :default => true
  249 + t.boolean "public_profile", :default => true
250 250 t.date "birth_date"
  251 + t.integer "preferred_domain_id"
251 252 end
252 253  
253 254 add_index "profiles", ["environment_id"], :name => "index_profiles_on_environment_id"
... ... @@ -285,8 +286,8 @@ ActiveRecord::Schema.define(:version =&gt; 65) do
285 286 t.datetime "created_at"
286 287 end
287 288  
288   - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
289 289 add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type"
  290 + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id"
290 291  
291 292 create_table "tags", :force => true do |t|
292 293 t.string "name"
... ...
lib/zen3_terminology.rb
... ... @@ -65,6 +65,7 @@ class Zen3Terminology &lt; Noosfero::Terminology::Custom
65 65 'Disable activation of enterprises' => N_('Disable activation of organizations'),
66 66 'Manage community fields' => N_('Manage group fields'),
67 67 'Create a new community' => N_('Create a new group'),
  68 + 'Preferred domain name:' => N_('Choose your host community:'),
68 69 })
69 70 end
70 71  
... ...
test/functional/account_controller_test.rb
... ... @@ -600,6 +600,7 @@ class AccountControllerTest &lt; Test::Unit::TestCase
600 600 end
601 601  
602 602 should 'not point to SSL URL in login popup when in development mode' do
  603 + @request.stubs(:ssl?).returns(false)
603 604 ENV.expects(:[]).with('RAILS_ENV').returns('development').at_least_once
604 605 get :login_popup
605 606 assert_no_tag :tag => 'form', :attributes => { :action => /^https:\/\// }
... ...
test/functional/application_controller_test.rb
... ... @@ -234,32 +234,6 @@ class ApplicationControllerTest &lt; Test::Unit::TestCase
234 234 assert_no_tag :tag => 'div', :attributes => { :id => 'user_box' }, :descendant => { :tag => 'a', :attributes => { :href => 'http://web.mail/' } }
235 235 end
236 236  
237   - should 'use environment top_url as base' do
238   - Environment.any_instance.expects(:top_url).returns('http://www.lala.net')
239   - get :index
240   - assert_tag :tag => 'base', :attributes => { :href => 'http://www.lala.net' }
241   - end
242   -
243   - should 'request environment top_url with ssl when under ssl for base' do
244   - Environment.any_instance.expects(:top_url).with(true).returns('https://www.lala.net/')
245   - @request.expects(:ssl?).returns(true).at_least_once
246   - get :index
247   - assert_tag :tag => 'base', :attributes => { :href => 'https://www.lala.net/' }
248   - end
249   -
250   - should 'use correct environment for base tag' do
251   - default = Environment.default
252   - Environment.stubs(:default).returns(default)
253   - default.stubs(:top_url).returns('http://default.com/')
254   -
255   - current = Environment.create!(:name => 'test environment')
256   - current.domains.create!(:name => 'example.com')
257   -
258   - @request.expects(:host).returns('example.com').at_least_once
259   - get :index
260   - assert_tag :tag => 'base', :attributes => { :href => 'http://example.com' }
261   - end
262   -
263 237 should 'display theme test panel when testing theme' do
264 238 @request.session[:theme] = 'my-test-theme'
265 239 theme = mock
... ...
test/functional/profile_editor_controller_test.rb
... ... @@ -632,4 +632,39 @@ class ProfileEditorControllerTest &lt; Test::Unit::TestCase
632 632 assert_tag :tag => 'a', :attributes => { :href => "/myprofile/default_user/cms/edit/#{profile.blog.id}" }
633 633 end
634 634  
  635 + should 'not show select preferred domain if not enabled in environment' do
  636 + profile.environment.custom_person_fields = {}; profile.environment.save!
  637 +
  638 + get :edit, :profile => profile.identifier
  639 + assert_no_tag :tag => 'select', :attributes => { :name => 'profile_data[preferred_domain_id]' }
  640 + end
  641 +
  642 + should 'be able to choose preferred domain' do
  643 + profile.environment.custom_person_fields = {'preferred_domain' => {'required' => 'true', 'active' => 'true'} }; profile.environment.save!
  644 +
  645 + profile.domains << Domain.new(:name => 'myowndomain.net')
  646 + profile.environment.domains << Domain.new(:name => 'myenv.net')
  647 +
  648 + get :edit, :profile => profile.identifier
  649 + assert_tag :tag => 'select', :attributes => { :name => 'profile_data[preferred_domain_id]' }, :descendant => { :tag => "option", :content => 'myowndomain.net' }
  650 + assert_tag :tag => 'select', :attributes => { :name => 'profile_data[preferred_domain_id]' }, :descendant => { :tag => "option", :content => 'myenv.net' }
  651 +
  652 + post :edit, :profile => profile.identifier, :profile_data => { :preferred_domain_id => profile.domains.first.id.to_s }
  653 +
  654 + assert_equal 'myowndomain.net', Profile.find(profile.id).preferred_domain.name
  655 + end
  656 +
  657 + should 'be able to set no preferred domain at all' do
  658 + profile.environment.custom_person_fields = {'preferred_domain' => {'required' => 'true', 'active' => 'true'} }; profile.environment.save!
  659 +
  660 + profile.domains << Domain.new(:name => 'myowndomain.net')
  661 + profile.environment.domains << Domain.new(:name => 'myenv.net')
  662 +
  663 + get :edit, :profile => profile.identifier
  664 + assert_tag :tag => "select", :attributes => { :name => 'profile_data[preferred_domain_id]'}, :descendant => { :tag => 'option', :content => '&lt;Select domain&gt;', :attributes => { :value => '' } }
  665 +
  666 + post :edit, :profile => profile.identifier, :profile_data => { :preferred_domain_id => '' }
  667 + assert_nil Profile.find(profile.id).preferred_domain
  668 + end
  669 +
635 670 end
... ...
test/integration/routing_test.rb
... ... @@ -2,6 +2,10 @@ require &quot;#{File.dirname(__FILE__)}/../test_helper&quot;
2 2  
3 3 class RoutingTest < ActionController::IntegrationTest
4 4  
  5 + def setup
  6 + Domain.clear_cache
  7 + end
  8 +
5 9 # home page
6 10 ################################################################
7 11 def test_homepage
... ... @@ -165,7 +169,6 @@ class RoutingTest &lt; ActionController::IntegrationTest
165 169 end
166 170  
167 171 def test_hosted_domain_routing
168   -
169 172 user = create_user('testuser').person
170 173 domain = Domain.create!(:name => 'example.com', :owner => user)
171 174  
... ... @@ -174,6 +177,15 @@ class RoutingTest &lt; ActionController::IntegrationTest
174 177 assert_routing('/work/free-software', :controller => 'content_viewer', :action => 'view_page', :page => [ 'work', 'free-software'] )
175 178 end
176 179  
  180 + def test_root_of_hosted_domain
  181 + user = create_user('testuser').person
  182 + domain = Domain.create!(:name => 'example.com', :owner => user)
  183 +
  184 + ActionController::TestRequest.any_instance.expects(:host).returns('www.example.com')
  185 +
  186 + assert_routing('', :controller => 'content_viewer', :action => 'view_page', :page => [])
  187 + end
  188 +
177 189 def test_profile_under_hosted_domain
178 190 community = Community.create!(:identifier => 'testcomm', :name => "test community")
179 191 domain = Domain.create!(:name => 'example.com', :owner => community)
... ...
test/unit/application_helper_test.rb
... ... @@ -202,6 +202,9 @@ class ApplicationHelperTest &lt; Test::Unit::TestCase
202 202 environment = mock
203 203 environment.expects(:disable_ssl).returns(true).at_least_once
204 204 stubs(:environment).returns(environment)
  205 + request = mock
  206 + request.stubs(:host).returns('localhost')
  207 + stubs(:request).returns(request)
205 208  
206 209 expects(:url_for).with(has_entries(:protocol => 'https://')).never
207 210 expects(:url_for).with(has_key(:controller)).returns("LALALA")
... ...
test/unit/domain_test.rb
... ... @@ -3,6 +3,10 @@ require File.dirname(__FILE__) + &#39;/../test_helper&#39;
3 3 class DomainTest < Test::Unit::TestCase
4 4 fixtures :domains, :environments, :profiles, :users
5 5  
  6 + def setup
  7 + Domain.clear_cache
  8 + end
  9 +
6 10 # Replace this with your real tests.
7 11 def test_domain_name_format
8 12 c = Domain.new
... ... @@ -83,4 +87,17 @@ class DomainTest &lt; Test::Unit::TestCase
83 87 assert_nil Domain.find_by_name('colivre.net').profile
84 88 end
85 89  
  90 + def test_hosted_domain
  91 + assert_equal false, Domain.hosting_profile_at('example.com')
  92 +
  93 + profile = create_user('hosted_user').person
  94 + Domain.create!(:name => 'example.com', :owner => profile)
  95 + assert_equal true, Domain.hosting_profile_at('example.com')
  96 + end
  97 +
  98 + def test_not_report_profile_hosted_for_environment_domains
  99 + Domain.create!(:name => 'example.com', :owner => Environment.default)
  100 + assert_equal false, Domain.hosting_profile_at('example.com')
  101 + end
  102 +
86 103 end
... ...
test/unit/profile_test.rb
1 1 require File.dirname(__FILE__) + '/../test_helper'
2 2  
3 3 class ProfileTest < Test::Unit::TestCase
4   - fixtures :profiles, :environments, :users, :roles
  4 + fixtures :profiles, :environments, :users, :roles, :domains
5 5  
6 6 def test_identifier_validation
7 7 p = Profile.new
... ... @@ -284,7 +284,7 @@ class ProfileTest &lt; Test::Unit::TestCase
284 284 should "use own domain name instead of environment's for home page url" do
285 285 profile = Profile.create!(:name => "Test Profile", :identifier => 'testprofile', :environment_id => create_environment('mycolivre.net').id)
286 286 profile.domains << Domain.new(:name => 'micojones.net')
287   - assert_equal({:host => 'micojones.net', :controller => 'content_viewer', :action => 'view_page', :page => []}, profile.url)
  287 + assert_equal({:host => 'micojones.net', :profile => nil, :controller => 'content_viewer', :action => 'view_page', :page => []}, profile.url)
288 288 end
289 289  
290 290 should 'help developers by adding a suitable port to url options' do
... ... @@ -1258,6 +1258,44 @@ class ProfileTest &lt; Test::Unit::TestCase
1258 1258 assert_nil person.find_in_all_tasks(task2.id)
1259 1259 end
1260 1260  
  1261 + should 'use environment hostname by default' do
  1262 + profile = Profile.new
  1263 + env = mock
  1264 + env.stubs(:default_hostname).returns('myenvironment.net')
  1265 + profile.stubs(:environment).returns(env)
  1266 + assert_equal 'myenvironment.net', profile.default_hostname
  1267 + end
  1268 +
  1269 + should 'use its first domain hostname name if available' do
  1270 + profile = create_user('testuser').person
  1271 + profile.domains << Domain.new(:name => 'myowndomain.net')
  1272 + assert_equal 'myowndomain.net', profile.default_hostname
  1273 + end
  1274 +
  1275 + should 'have a preferred domain name' do
  1276 + person = create_user('testuser').person
  1277 + domain = Domain.create!(:name => 'myowndomain.net', :owner => person)
  1278 + person.preferred_domain = domain
  1279 + person.save!
  1280 +
  1281 + assert_equal domain, Person.find(person.id).preferred_domain(true)
  1282 + end
  1283 +
  1284 + should 'use preferred domain for hostname' do
  1285 + profile = Profile.new
  1286 + profile.stubs(:preferred_domain).returns(Domain.new(:name => 'preferred.net'))
  1287 + assert_equal 'preferred.net', profile.url[:host]
  1288 + end
  1289 +
  1290 + should 'provide a list of possible preferred domain names' do
  1291 + profile = create_user('testuser').person
  1292 + domain1 = Domain.create!(:name => 'envdomain.net', :owner => profile.environment)
  1293 + domain2 = Domain.create!(:name => 'profiledomain.net', :owner => profile)
  1294 +
  1295 + assert_includes profile.possible_domains, domain1
  1296 + assert_includes profile.possible_domains, domain2
  1297 + end
  1298 +
1261 1299 private
1262 1300  
1263 1301 def assert_invalid_identifier(id)
... ...