Commit 09a87726fac518a161779a7348882cd28a89d689

Authored by AntonioTerceiro
1 parent d7aa1364

ActionItem8: initial effort on VirtualCommunity, Profile and Domain



git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@25 3f533792-8f58-4932-b0fe-aaf55b0a4547
app/controllers/application.rb
1 # Filters added to this controller will be run for all controllers in the application. 1 # Filters added to this controller will be run for all controllers in the application.
2 # Likewise, all the methods added will be available for all controllers. 2 # Likewise, all the methods added will be available for all controllers.
3 class ApplicationController < ActionController::Base 3 class ApplicationController < ActionController::Base
4 -end  
5 \ No newline at end of file 4 \ No newline at end of file
  5 +
  6 + before_filter :detect_stuff_by_domain
  7 +
  8 + protected
  9 +
  10 + def detect_stuff_by_domain
  11 + @domain = Domain.find_by_name(request.host)
  12 + @virtual_community = @domain.virtual_community
  13 + @profile = @domain.profile
  14 + end
  15 +
  16 +end
app/controllers/home_controller.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +class HomeController < ApplicationController
  2 +end
app/helpers/home_helper.rb 0 → 100644
@@ -0,0 +1,2 @@ @@ -0,0 +1,2 @@
  1 +module HomeHelper
  2 +end
app/models/domain.rb
1 class Domain < ActiveRecord::Base 1 class Domain < ActiveRecord::Base
2 2
  3 + # relationships
  4 + ###############
  5 +
3 belongs_to :owner, :polymorphic => true 6 belongs_to :owner, :polymorphic => true
4 7
5 - validates_format_of :name, :with => /^(\w+\.)+\w+$/ 8 + # validations
  9 + #############
  10 +
  11 + # <tt>name</tt> must be a sequence of word characters (a to z, plus 0 to 9,
  12 + # plus '_'). Letters must be lowercase
  13 + validates_format_of :name, :with => /^([a-z0-9_]+\.)+[a-z0-9_]+$/, :message => _('%{fn} must be composed only of lowercase latters (a to z), numbers (0 to 9) and "_"')
  14 +
  15 + # checks validations that could not be expressed using Rails' predefined
  16 + # validations. In particular:
  17 + # * <tt>name</tt> must not start with 'www.'
  18 + def validate
  19 + if self.name =~ /^www\./
  20 + self.errors.add(:name, _('%{fn} must not start with www.'))
  21 + end
  22 + end
  23 +
  24 + # we cannot have two domains with the same name
  25 + validates_uniqueness_of :name
  26 +
  27 + # businessl logic
  28 + #################
  29 +
  30 + # finds a domain by its name. The argument <tt>name</tt> can start with
  31 + # "www.", but it will be removed before searching. So searching for
  32 + # 'www.example.net' is exactly the same as searching for just 'example.net'
  33 + def self.find_by_name(name)
  34 + self.find(:first, :conditions => [ 'name = ?', self.extract_domain_name(name) ])
  35 + end
  36 +
  37 + # turns the argument (expected to be a String) into a domain name that is
  38 + # accepted, by removing any leading 'www.' and turning the downcasing it.
  39 + def self.extract_domain_name(name)
  40 + name.downcase.sub(/^www\./, '')
  41 + end
  42 +
  43 + # detects the VirtualCommunity to which this domain belongs, either if it's
  44 + # directly owned by one, or through a profile who owns the domain but belongs
  45 + # to a VirtualCommunity.
  46 + def virtual_community
  47 + case owner
  48 + when VirtualCommunity
  49 + owner
  50 + when Profile
  51 + owner.virtual_community
  52 + end
  53 + end
  54 +
  55 + # returns the profile associated to this domain. Returns nil if the domain is
  56 + # not directly associated with a profile.
  57 + def profile
  58 + case owner
  59 + when VirtualCommunity
  60 + nil
  61 + when Profile
  62 + owner
  63 + end
  64 + end
6 65
7 end 66 end
app/models/profile.rb
  1 +# A Profile is the representation and web-presence of an individual or an
  2 +# organization. Every Profile is attached to its VirtualCommunity of origin,
  3 +# which by default is the one returned by VirtualCommunity:default.
1 class Profile < ActiveRecord::Base 4 class Profile < ActiveRecord::Base
  5 +
  6 + has_many :domains, :as => :owner
  7 + belongs_to :virtual_community
  8 +
2 validates_presence_of :identifier 9 validates_presence_of :identifier
3 validates_format_of :identifier, :with => /^[a-z][a-z0-9_]+[a-z0-9]$/ 10 validates_format_of :identifier, :with => /^[a-z][a-z0-9_]+[a-z0-9]$/
  11 +
  12 + # creates a new Profile. By default, it is attached to the default
  13 + # VirtualCommunity (see VirtualCommunity#default)
  14 + def initialize(*args)
  15 + super(*args)
  16 + self.virtual_community ||= VirtualCommunity.default
  17 + end
  18 +
4 end 19 end
app/models/virtual_community.rb
1 class VirtualCommunity < ActiveRecord::Base 1 class VirtualCommunity < ActiveRecord::Base
2 2
  3 + # One VirtualCommunity can be reached by many domains
3 has_many :domains, :as => :owner 4 has_many :domains, :as => :owner
4 5
  6 + # <tt>name</tt> is mandatory
  7 + validates_presence_of :name
  8 +
  9 + # only one virtual community can be the default one
  10 + validates_uniqueness_of :is_default, :if => (lambda do |virtual_community| virtual_community.is_default? end), :message => _('Only one Virtual Community can be the default one')
  11 +
  12 + # VirtualCommunity configuration
5 serialize :configuration, Hash 13 serialize :configuration, Hash
  14 +
  15 + # a Hash with configuration parameters for this community. The configuration
  16 + # contains general parameters of the VirtualCommunity as well as
  17 + # enabling/disabling optional features.
6 def configuration 18 def configuration
7 self[:configuration] ||= Hash.new 19 self[:configuration] ||= Hash.new
8 end 20 end
9 21
  22 + # the default VirtualCommunity.
  23 + def self.default
  24 + self.find(:first, :conditions => [ 'is_default = ?', true ] )
  25 + end
  26 +
10 end 27 end
app/views/home/index.rhtml 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +Start page of Virtual Community <%# @virtual_community.name %>
config/routes.rb
@@ -11,7 +11,7 @@ ActionController::Routing::Routes.draw do |map| @@ -11,7 +11,7 @@ ActionController::Routing::Routes.draw do |map|
11 11
12 # You can have the root of your site routed by hooking up '' 12 # You can have the root of your site routed by hooking up ''
13 # -- just remember to delete public/index.html. 13 # -- just remember to delete public/index.html.
14 - # map.connect '', :controller => "welcome" 14 + map.connect '', :controller => "home"
15 15
16 # Allow downloading Web Service WSDL as a file with an extension 16 # Allow downloading Web Service WSDL as a file with an extension
17 # instead of a file named 'wsdl' 17 # instead of a file named 'wsdl'
db/migrate/001_create_virtual_communities.rb
@@ -2,8 +2,8 @@ class CreateVirtualCommunities &lt; ActiveRecord::Migration @@ -2,8 +2,8 @@ class CreateVirtualCommunities &lt; ActiveRecord::Migration
2 def self.up 2 def self.up
3 create_table :virtual_communities do |t| 3 create_table :virtual_communities do |t|
4 t.column :name, :string 4 t.column :name, :string
5 - t.column :domain, :string  
6 t.column :configuration, :text 5 t.column :configuration, :text
  6 + t.column :is_default, :boolean
7 end 7 end
8 end 8 end
9 9
db/migrate/002_create_profiles.rb
@@ -3,6 +3,7 @@ class CreateProfiles &lt; ActiveRecord::Migration @@ -3,6 +3,7 @@ class CreateProfiles &lt; ActiveRecord::Migration
3 create_table :profiles do |t| 3 create_table :profiles do |t|
4 t.column :name, :string 4 t.column :name, :string
5 t.column :identifier, :string 5 t.column :identifier, :string
  6 + t.column :virtual_community_id, :integer
6 end 7 end
7 end 8 end
8 9
db/migrate/003_create_domains.rb
@@ -2,7 +2,7 @@ class CreateDomains &lt; ActiveRecord::Migration @@ -2,7 +2,7 @@ class CreateDomains &lt; ActiveRecord::Migration
2 def self.up 2 def self.up
3 create_table :domains do |t| 3 create_table :domains do |t|
4 t.column :name, :string 4 t.column :name, :string
5 - t.column :ownwer_type, :string 5 + t.column :owner_type, :string
6 t.column :owner_id, :integer 6 t.column :owner_id, :integer
7 end 7 end
8 end 8 end
public/index.html
@@ -1,277 +0,0 @@ @@ -1,277 +0,0 @@
1 -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
2 - "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
3 -<html>  
4 - <head>  
5 - <meta http-equiv="Content-type" content="text/html; charset=utf-8" />  
6 - <title>Ruby on Rails: Welcome aboard</title>  
7 - <style type="text/css" media="screen">  
8 - body {  
9 - margin: 0;  
10 - margin-bottom: 25px;  
11 - padding: 0;  
12 - background-color: #f0f0f0;  
13 - font-family: "Lucida Grande", "Bitstream Vera Sans", "Verdana";  
14 - font-size: 13px;  
15 - color: #333;  
16 - }  
17 -  
18 - h1 {  
19 - font-size: 28px;  
20 - color: #000;  
21 - }  
22 -  
23 - a {color: #03c}  
24 - a:hover {  
25 - background-color: #03c;  
26 - color: white;  
27 - text-decoration: none;  
28 - }  
29 -  
30 -  
31 - #page {  
32 - background-color: #f0f0f0;  
33 - width: 750px;  
34 - margin: 0;  
35 - margin-left: auto;  
36 - margin-right: auto;  
37 - }  
38 -  
39 - #content {  
40 - float: left;  
41 - background-color: white;  
42 - border: 3px solid #aaa;  
43 - border-top: none;  
44 - padding: 25px;  
45 - width: 500px;  
46 - }  
47 -  
48 - #sidebar {  
49 - float: right;  
50 - width: 175px;  
51 - }  
52 -  
53 - #footer {  
54 - clear: both;  
55 - }  
56 -  
57 -  
58 - #header, #about, #getting-started {  
59 - padding-left: 75px;  
60 - padding-right: 30px;  
61 - }  
62 -  
63 -  
64 - #header {  
65 - background-image: url("images/rails.png");  
66 - background-repeat: no-repeat;  
67 - background-position: top left;  
68 - height: 64px;  
69 - }  
70 - #header h1, #header h2 {margin: 0}  
71 - #header h2 {  
72 - color: #888;  
73 - font-weight: normal;  
74 - font-size: 16px;  
75 - }  
76 -  
77 -  
78 - #about h3 {  
79 - margin: 0;  
80 - margin-bottom: 10px;  
81 - font-size: 14px;  
82 - }  
83 -  
84 - #about-content {  
85 - background-color: #ffd;  
86 - border: 1px solid #fc0;  
87 - margin-left: -11px;  
88 - }  
89 - #about-content table {  
90 - margin-top: 10px;  
91 - margin-bottom: 10px;  
92 - font-size: 11px;  
93 - border-collapse: collapse;  
94 - }  
95 - #about-content td {  
96 - padding: 10px;  
97 - padding-top: 3px;  
98 - padding-bottom: 3px;  
99 - }  
100 - #about-content td.name {color: #555}  
101 - #about-content td.value {color: #000}  
102 -  
103 - #about-content.failure {  
104 - background-color: #fcc;  
105 - border: 1px solid #f00;  
106 - }  
107 - #about-content.failure p {  
108 - margin: 0;  
109 - padding: 10px;  
110 - }  
111 -  
112 -  
113 - #getting-started {  
114 - border-top: 1px solid #ccc;  
115 - margin-top: 25px;  
116 - padding-top: 15px;  
117 - }  
118 - #getting-started h1 {  
119 - margin: 0;  
120 - font-size: 20px;  
121 - }  
122 - #getting-started h2 {  
123 - margin: 0;  
124 - font-size: 14px;  
125 - font-weight: normal;  
126 - color: #333;  
127 - margin-bottom: 25px;  
128 - }  
129 - #getting-started ol {  
130 - margin-left: 0;  
131 - padding-left: 0;  
132 - }  
133 - #getting-started li {  
134 - font-size: 18px;  
135 - color: #888;  
136 - margin-bottom: 25px;  
137 - }  
138 - #getting-started li h2 {  
139 - margin: 0;  
140 - font-weight: normal;  
141 - font-size: 18px;  
142 - color: #333;  
143 - }  
144 - #getting-started li p {  
145 - color: #555;  
146 - font-size: 13px;  
147 - }  
148 -  
149 -  
150 - #search {  
151 - margin: 0;  
152 - padding-top: 10px;  
153 - padding-bottom: 10px;  
154 - font-size: 11px;  
155 - }  
156 - #search input {  
157 - font-size: 11px;  
158 - margin: 2px;  
159 - }  
160 - #search-text {width: 170px}  
161 -  
162 -  
163 - #sidebar ul {  
164 - margin-left: 0;  
165 - padding-left: 0;  
166 - }  
167 - #sidebar ul h3 {  
168 - margin-top: 25px;  
169 - font-size: 16px;  
170 - padding-bottom: 10px;  
171 - border-bottom: 1px solid #ccc;  
172 - }  
173 - #sidebar li {  
174 - list-style-type: none;  
175 - }  
176 - #sidebar ul.links li {  
177 - margin-bottom: 5px;  
178 - }  
179 -  
180 - </style>  
181 - <script type="text/javascript" src="javascripts/prototype.js"></script>  
182 - <script type="text/javascript" src="javascripts/effects.js"></script>  
183 - <script type="text/javascript">  
184 - function about() {  
185 - if (Element.empty('about-content')) {  
186 - new Ajax.Updater('about-content', 'rails/info/properties', {  
187 - method: 'get',  
188 - onFailure: function() {Element.classNames('about-content').add('failure')},  
189 - onComplete: function() {new Effect.BlindDown('about-content', {duration: 0.25})}  
190 - });  
191 - } else {  
192 - new Effect[Element.visible('about-content') ?  
193 - 'BlindUp' : 'BlindDown']('about-content', {duration: 0.25});  
194 - }  
195 - }  
196 -  
197 - window.onload = function() {  
198 - $('search-text').value = '';  
199 - $('search').onsubmit = function() {  
200 - $('search-text').value = 'site:rubyonrails.org ' + $F('search-text');  
201 - }  
202 - }  
203 - </script>  
204 - </head>  
205 - <body>  
206 - <div id="page">  
207 - <div id="sidebar">  
208 - <ul id="sidebar-items">  
209 - <li>  
210 - <form id="search" action="http://www.google.com/search" method="get">  
211 - <input type="hidden" name="hl" value="en" />  
212 - <input type="text" id="search-text" name="q" value="site:rubyonrails.org " />  
213 - <input type="submit" value="Search" /> the Rails site  
214 - </form>  
215 - </li>  
216 -  
217 - <li>  
218 - <h3>Join the community</h3>  
219 - <ul class="links">  
220 - <li><a href="http://www.rubyonrails.org/">Ruby on Rails</a></li>  
221 - <li><a href="http://weblog.rubyonrails.org/">Official weblog</a></li>  
222 - <li><a href="http://lists.rubyonrails.org/">Mailing lists</a></li>  
223 - <li><a href="http://wiki.rubyonrails.org/rails/pages/IRC">IRC channel</a></li>  
224 - <li><a href="http://wiki.rubyonrails.org/">Wiki</a></li>  
225 - <li><a href="http://dev.rubyonrails.org/">Bug tracker</a></li>  
226 - </ul>  
227 - </li>  
228 -  
229 - <li>  
230 - <h3>Browse the documentation</h3>  
231 - <ul class="links">  
232 - <li><a href="http://api.rubyonrails.org/">Rails API</a></li>  
233 - <li><a href="http://stdlib.rubyonrails.org/">Ruby standard library</a></li>  
234 - <li><a href="http://corelib.rubyonrails.org/">Ruby core</a></li>  
235 - </ul>  
236 - </li>  
237 - </ul>  
238 - </div>  
239 -  
240 - <div id="content">  
241 - <div id="header">  
242 - <h1>Welcome aboard</h1>  
243 - <h2>You&rsquo;re riding the Rails!</h2>  
244 - </div>  
245 -  
246 - <div id="about">  
247 - <h3><a href="rails/info/properties" onclick="about(); return false">About your application&rsquo;s environment</a></h3>  
248 - <div id="about-content" style="display: none"></div>  
249 - </div>  
250 -  
251 - <div id="getting-started">  
252 - <h1>Getting started</h1>  
253 - <h2>Here&rsquo;s how to get rolling:</h2>  
254 -  
255 - <ol>  
256 - <li>  
257 - <h2>Create your databases and edit <tt>config/database.yml</tt></h2>  
258 - <p>Rails needs to know your login and password.</p>  
259 - </li>  
260 -  
261 - <li>  
262 - <h2>Use <tt>script/generate</tt> to create your models and controllers</h2>  
263 - <p>To see all available options, run it without parameters.</p>  
264 - </li>  
265 -  
266 - <li>  
267 - <h2>Set up a default route and remove or rename this file</h2>  
268 - <p>Routes are setup in config/routes.rb.</p>  
269 - </li>  
270 - </ol>  
271 - </div>  
272 - </div>  
273 -  
274 - <div id="footer">&nbsp;</div>  
275 - </div>  
276 - </body>  
277 -</html>  
278 \ No newline at end of file 0 \ No newline at end of file
test/fixtures/domains.yml
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 one: 2 one:
3 id: 1 3 id: 1
  4 + name: colivre.net
  5 + owner_type: VirtualCommunity
  6 + owner_id: 1
4 two: 7 two:
5 id: 2 8 id: 2
  9 + name: anhetegua.net
  10 + owner_type: VirtualCommunity
  11 + owner_id: 2
  12 +three:
  13 + id: 3
  14 + name: johndoe.net
  15 + owner_type: Profile
  16 + owner_id: 1
  17 +four:
  18 + id: 4
  19 + name: jrh.net
  20 + owner_type: Profile
  21 + owner_id: 2
test/fixtures/profiles.yml
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 first: 2 first:
3 id: 1 3 id: 1
  4 + name: 'John Doe'
  5 + identifier: johndoe
  6 + virtual_community_id: 1
4 another: 7 another:
5 id: 2 8 id: 2
  9 + name: 'Joe Random Hacker'
  10 + identifier: joerandomhacker
  11 + virtual_community_id: 1
test/fixtures/virtual_communities.yml
1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 first: 2 first:
3 id: 1 3 id: 1
4 - name: 'Anheteguá'  
5 - domain: 'anhetegua.net' 4 + name: 'Colivre.net'
  5 + is_default: true
6 another: 6 another:
7 id: 2 7 id: 2
8 - name: 'Colivre.net'  
9 - domain: 'colivre.net' 8 + name: 'Anheteguá'
  9 + is_default: false
test/functional/home_controller_test.rb 0 → 100644
@@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +require 'home_controller'
  3 +
  4 +# Re-raise errors caught by the controller.
  5 +class HomeController; def rescue_action(e) raise e end; end
  6 +
  7 +class HomeControllerTest < Test::Unit::TestCase
  8 +
  9 + fixtures :profiles, :virtual_communities, :domains
  10 +
  11 + def setup
  12 + @controller = HomeController.new
  13 + @request = ActionController::TestRequest.new
  14 + @response = ActionController::TestResponse.new
  15 + end
  16 +
  17 + def test_detection_of_virtual_community_by_host
  18 + uses_host 'www.colivre.net'
  19 + get :index
  20 + assert_template 'index'
  21 +
  22 + assert_kind_of VirtualCommunity, assigns(:virtual_community)
  23 +
  24 + assert_kind_of Domain, assigns(:domain)
  25 + assert_equal 'colivre.net', assigns(:domain).name
  26 +
  27 + assert_nil assigns(:profile)
  28 + end
  29 +
  30 + def test_detect_profile_by_host
  31 + uses_host 'www.jrh.net'
  32 + get :index
  33 + assert_template 'index'
  34 +
  35 + assert_kind_of VirtualCommunity, assigns(:virtual_community)
  36 +
  37 + assert_kind_of Domain, assigns(:domain)
  38 + assert_equal 'jrh.net', assigns(:domain).name
  39 +
  40 + assert_kind_of Profile, assigns(:profile)
  41 + end
  42 +end
test/test_helper.rb
@@ -25,4 +25,11 @@ class Test::Unit::TestCase @@ -25,4 +25,11 @@ class Test::Unit::TestCase
25 self.use_instantiated_fixtures = false 25 self.use_instantiated_fixtures = false
26 26
27 # Add more helper methods to be used by all tests here... 27 # Add more helper methods to be used by all tests here...
  28 +
  29 + private
  30 +
  31 + def uses_host(name)
  32 + @request.instance_variable_set('@host', name)
  33 + end
  34 +
28 end 35 end
test/unit/domain_test.rb
1 require File.dirname(__FILE__) + '/../test_helper' 1 require File.dirname(__FILE__) + '/../test_helper'
2 2
3 class DomainTest < Test::Unit::TestCase 3 class DomainTest < Test::Unit::TestCase
4 - fixtures :domains 4 + fixtures :domains, :virtual_communities, :profiles
5 5
6 # Replace this with your real tests. 6 # Replace this with your real tests.
7 def test_domain_name_format 7 def test_domain_name_format
8 c = Domain.new 8 c = Domain.new
9 - c.valid? 9 + assert !c.valid?
10 assert c.errors.invalid?(:name) 10 assert c.errors.invalid?(:name)
11 11
12 c.name = 'bliblibli' 12 c.name = 'bliblibli'
13 - c.valid? 13 + assert !c.valid?
  14 + assert c.errors.invalid?(:name)
  15 +
  16 + c.name = 'EXAMPLE.NET'
  17 + assert !c.valid?
14 assert c.errors.invalid?(:name) 18 assert c.errors.invalid?(:name)
15 19
16 c.name = 'test.net' 20 c.name = 'test.net'
17 c.valid? 21 c.valid?
18 - assert ! c.errors.invalid?(:name) 22 + assert !c.errors.invalid?(:name)
19 end 23 end
20 24
21 def test_owner 25 def test_owner
@@ -25,4 +29,58 @@ class DomainTest &lt; Test::Unit::TestCase @@ -25,4 +29,58 @@ class DomainTest &lt; Test::Unit::TestCase
25 assert_kind_of VirtualCommunity, d.owner 29 assert_kind_of VirtualCommunity, d.owner
26 end 30 end
27 31
  32 + def test_get_domain_name
  33 + assert_equal 'example.net', Domain.extract_domain_name('www.example.net')
  34 + assert_equal 'example.net', Domain.extract_domain_name('WWW.EXAMPLE.NET')
  35 + end
  36 +
  37 + def test_name_cannot_have_www
  38 + d = Domain.new
  39 + d.name = 'www.example.net'
  40 + d.valid?
  41 + assert d.errors.invalid?(:name)
  42 +
  43 + d.name = 'example.net'
  44 + d.valid?
  45 + assert !d.errors.invalid?(:name)
  46 + end
  47 +
  48 + def test_find_by_name
  49 + Domain.delete_all
  50 + Domain.create(:name => 'example.net')
  51 + d1 = Domain.find_by_name('example.net')
  52 + d2 = Domain.find_by_name('www.example.net')
  53 + assert !d1.nil?
  54 + assert !d2.nil?
  55 + assert d1 == d2
  56 + end
  57 +
  58 + def test_unique_name
  59 + Domain.delete_all
  60 + assert Domain.create(:name => 'example.net')
  61 +
  62 + d = Domain.new(:name => 'example.net')
  63 + assert !d.valid?
  64 + assert d.errors.invalid?(:name)
  65 + end
  66 +
  67 + def test_virtual_community
  68 + # domain directly linked to VirtualCommunity
  69 + domain = Domain.find_by_name('colivre.net')
  70 + assert_kind_of VirtualCommunity, domain.owner
  71 + assert_kind_of VirtualCommunity, domain.virtual_community
  72 +
  73 + # domain linked to Profile
  74 + domain = Domain.find_by_name('johndoe.net')
  75 + assert_kind_of Profile, domain.owner
  76 + assert_kind_of VirtualCommunity, domain.virtual_community
  77 + end
  78 +
  79 + def test_profile
  80 + # domain linked to profile
  81 + assert_not_nil Domain.find_by_name('johndoe.net').profile
  82 + # domain linked to VirtualCommunity
  83 + assert_nil Domain.find_by_name('colivre.net').profile
  84 + end
  85 +
28 end 86 end
test/unit/profile_test.rb
1 require File.dirname(__FILE__) + '/../test_helper' 1 require File.dirname(__FILE__) + '/../test_helper'
2 2
3 class ProfileTest < Test::Unit::TestCase 3 class ProfileTest < Test::Unit::TestCase
4 - fixtures :profiles 4 + fixtures :profiles, :virtual_communities
5 5
6 def test_identifier_validation 6 def test_identifier_validation
7 p = Profile.new 7 p = Profile.new
@@ -29,4 +29,14 @@ class ProfileTest &lt; Test::Unit::TestCase @@ -29,4 +29,14 @@ class ProfileTest &lt; Test::Unit::TestCase
29 assert ! p.errors.invalid?(:identifier) 29 assert ! p.errors.invalid?(:identifier)
30 end 30 end
31 31
  32 + def test_has_domains
  33 + p = Profile.new
  34 + assert_kind_of Array, p.domains
  35 + end
  36 +
  37 + def test_belongs_to_virtual_community_and_has_default
  38 + p = Profile.new
  39 + assert_kind_of VirtualCommunity, p.virtual_community
  40 + end
  41 +
32 end 42 end
test/unit/virtual_community_test.rb
@@ -4,8 +4,22 @@ class VirtualCommunityTest &lt; Test::Unit::TestCase @@ -4,8 +4,22 @@ class VirtualCommunityTest &lt; Test::Unit::TestCase
4 fixtures :virtual_communities 4 fixtures :virtual_communities
5 5
6 def test_configuration 6 def test_configuration
7 - c = VirtualCommunity.new  
8 - assert_kind_of Hash, c.configuration 7 + vc = VirtualCommunity.new
  8 + assert_kind_of Hash, vc.configuration
  9 + end
  10 +
  11 + def test_exists_default_and_it_is_unique
  12 + VirtualCommunity.delete_all
  13 + vc = VirtualCommunity.new(:name => 'Test Community')
  14 + vc.is_default = true
  15 + assert vc.save
  16 +
  17 + vc2 = VirtualCommunity.new(:name => 'Another Test Community')
  18 + vc2.is_default = true
  19 + assert !vc2.valid?
  20 + assert vc2.errors.invalid?(:is_default)
  21 +
  22 + assert_equal vc, VirtualCommunity.default
9 end 23 end
10 24
11 end 25 end