trusty-multi-site-extension 1.0.0

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 (62) hide show
  1. data/README.markdown +116 -0
  2. data/Rakefile +120 -0
  3. data/app/assets/images/admin/move_higher.png +0 -0
  4. data/app/assets/images/admin/move_lower.png +0 -0
  5. data/app/assets/images/admin/move_to_bottom.png +0 -0
  6. data/app/assets/images/admin/move_to_top.png +0 -0
  7. data/app/assets/images/admin/remove.png +0 -0
  8. data/app/assets/stylesheets/admin/multi_site.scss +121 -0
  9. data/app/assets/stylesheets/admin/site_chooser.scss +0 -0
  10. data/app/controllers/admin/sites_controller.rb +14 -0
  11. data/app/helpers/scoped_helper.rb +19 -0
  12. data/app/helpers/sites_helper.rb +10 -0
  13. data/app/models/site.rb +86 -0
  14. data/app/views/admin/layouts/_choose_site.html.haml +8 -0
  15. data/app/views/admin/layouts/_site_chooser.html.haml +2 -0
  16. data/app/views/admin/sites/_form.haml +43 -0
  17. data/app/views/admin/sites/edit.haml +7 -0
  18. data/app/views/admin/sites/index.haml +43 -0
  19. data/app/views/admin/sites/new.haml +7 -0
  20. data/app/views/admin/snippets/_choose_site.html.haml +6 -0
  21. data/app/views/admin/users/_choose_site.html.haml +8 -0
  22. data/app/views/site/not_configured.html.haml +7 -0
  23. data/config/initializers/radiant_config.rb +5 -0
  24. data/config/routes.rb +13 -0
  25. data/db/migrate/001_create_sites.rb +13 -0
  26. data/db/migrate/002_add_order_to_sites.rb +9 -0
  27. data/db/migrate/003_add_base_domain_to_sites.rb +9 -0
  28. data/db/migrate/004_add_admin_fields_to_sites.rb +17 -0
  29. data/db/migrate/005_add_sites.rb +13 -0
  30. data/db/migrate/006_remove_user_login_index.rb +8 -0
  31. data/db/migrate/20090810145840_site_abbreviation.rb +9 -0
  32. data/db/migrate/201411031415046078_recreate_non_unique_index_on_snippets_name.rb +11 -0
  33. data/lib/multi_site/admin_ui.rb +46 -0
  34. data/lib/multi_site/application_controller_extensions.rb +40 -0
  35. data/lib/multi_site/application_controller_filter_extensions.rb +21 -0
  36. data/lib/multi_site/engine.rb +5 -0
  37. data/lib/multi_site/page_extensions.rb +43 -0
  38. data/lib/multi_site/pages_controller_extensions.rb +48 -0
  39. data/lib/multi_site/resource_controller_extensions.rb +41 -0
  40. data/lib/multi_site/route_extensions.rb +21 -0
  41. data/lib/multi_site/route_set_extensions.rb +16 -0
  42. data/lib/multi_site/scoped_model.rb +145 -0
  43. data/lib/multi_site/scoped_validation.rb +32 -0
  44. data/lib/multi_site/site_chooser_helper.rb +14 -0
  45. data/lib/multi_site/site_controller_extensions.rb +12 -0
  46. data/lib/tasks/multi_site_extension_tasks.rake +28 -0
  47. data/lib/tasks/scoped_admin_extension_tasks.rake +28 -0
  48. data/lib/trusty-multi-site-extension.rb +1 -0
  49. data/multi_site_extension.rb +66 -0
  50. data/spec/controllers/extended_site_controller_spec.rb +61 -0
  51. data/spec/datasets/site_pages_dataset.rb +13 -0
  52. data/spec/datasets/sites_dataset.rb +10 -0
  53. data/spec/functional/multi_site_routing_spec.rb +37 -0
  54. data/spec/lib/multi_site/admin_ui_spec.rb +35 -0
  55. data/spec/lib/multi_site/scoped_model_spec.rb +182 -0
  56. data/spec/matchers/route_matcher.rb +38 -0
  57. data/spec/models/extended_page_spec.rb +48 -0
  58. data/spec/models/site_spec.rb +83 -0
  59. data/spec/spec.opts +6 -0
  60. data/spec/spec_helper.rb +36 -0
  61. data/trusty-multi-site-extension.gemspec +28 -0
  62. metadata +164 -0
@@ -0,0 +1,66 @@
1
+ require_dependency 'application_controller'
2
+
3
+ class MultiSiteExtension < TrustyCms::Extension
4
+ version "1.0.0"
5
+ description %{ Enables virtual sites to be created with associated domain names.
6
+ Also scopes the sitemap view to any given page (or the root of an
7
+ individual site) and allows model classes to be scoped by site. }
8
+ url "http://trustarts.org/"
9
+
10
+
11
+ def activate
12
+ # ActionController::Routing modules are required rather than sent as includes
13
+ # because the routing persists between dev. requests and is not compatible
14
+ # with multiple alias_method_chain calls.
15
+
16
+ # likewise for ScopedValidation, which is a pre-emptive hack that shouldn't run more than once.
17
+
18
+
19
+ # Model extensions
20
+ ActiveRecord::Base.send :include, MultiSite::ScopedModel
21
+ Page.send :include, MultiSite::PageExtensions
22
+
23
+ # Controller extensions
24
+ ApplicationController.send :include, MultiSite::ApplicationControllerExtensions
25
+ Admin::ResourceController.send :include, MultiSite::ApplicationControllerExtensions
26
+ ApplicationController.send :include, MultiSite::ApplicationControllerFilterExtensions
27
+ #ActionController::Base.send :include, MultiSite::ApplicationControllerExtensions
28
+ SiteController.send :include, MultiSite::SiteControllerExtensions
29
+ Admin::ResourceController.send :include, MultiSite::ResourceControllerExtensions
30
+ Admin::PagesController.send :include, MultiSite::PagesControllerExtensions
31
+ Admin::ResourceController.send :helper, MultiSite::SiteChooserHelper
32
+ Admin::PagesController.send :helper, MultiSite::SiteChooserHelper
33
+ admin.layouts.index.add(:top, "site_chooser")
34
+ admin.pages.index.add(:top, "admin/layouts/site_chooser")
35
+ admin.snippets.index.add(:top, "admin/layouts/site_chooser")
36
+ Layout.send :is_site_scoped
37
+ Snippet.send :is_site_scoped
38
+ User.send :is_site_scoped, :shareable => true
39
+ ApplicationHelper.send :include, ScopedHelper
40
+
41
+ unless admin.users.edit.form && admin.users.edit.form.include?('choose_site')
42
+ admin.users.edit.add :form, "choose_site", :after => "edit_roles"
43
+ admin.layouts.edit.add :form, "choose_site", :before => "edit_timestamp"
44
+ admin.snippets.edit.add :form, "choose_site", :before => "edit_filter" unless admin.snippets.edit.form.include?("choose_site")
45
+ end
46
+
47
+
48
+ unless defined? admin.site
49
+ TrustyCms::AdminUI.send :include, MultiSite::AdminUI
50
+ admin.site = TrustyCms::AdminUI.load_default_site_regions
51
+ end
52
+
53
+ if respond_to?(:tab)
54
+ tab("Settings") do
55
+ add_item "Sites", "/admin/sites", :after => "Extensions", :visibility => [:admin]
56
+ end
57
+ else
58
+ admin.tabs.add "Sites", "/admin/sites", :visibility => [:admin]
59
+ end
60
+ end
61
+
62
+ def deactivate
63
+ end
64
+ end
65
+
66
+ class ActiveRecord::SiteNotFound < Exception; end
@@ -0,0 +1,61 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe SiteController do
4
+ dataset :sites
5
+
6
+ before do
7
+ # I don't know why we're not getting the site routes
8
+ # possibly because of the routing tests?
9
+ # but without them, controller tests fail
10
+ ActionController::Routing::Routes.draw do |map|
11
+ map.connect '*url', :controller => 'site', :action => 'show_page'
12
+ end
13
+ end
14
+
15
+ describe "with a request that matches no site" do
16
+ before do
17
+ Page.current_site = nil
18
+ @host = 'nosite.domain.com'
19
+ controller.request.stub!(:host).and_return(@host)
20
+ end
21
+
22
+ it "should have chosen the catchall site" do
23
+ Page.should_receive(:current_site=).with(sites(:default)).at_least(:once)
24
+ get :show_page, :url => '/'
25
+ end
26
+ end
27
+
28
+ describe "with a request that matches a site" do
29
+ before do
30
+ Page.current_site = nil
31
+ @host = 'yoursite.domain.com'
32
+ controller.request.stub!(:host).and_return(@host)
33
+ end
34
+
35
+ it "should have chosen the matching site" do
36
+ Page.should_not_receive(:current_site=).with(sites(:default))
37
+ Page.should_receive(:current_site=).with(sites(:yoursite)).at_least(:once)
38
+ get :show_page, :url => '/yourpage'
39
+ end
40
+
41
+ it "should return a page from the present site" do
42
+ get :show_page, :url => '/yourpage'
43
+ response.should be_success
44
+ response.body.should == "This is your other page body."
45
+ end
46
+
47
+ describe "but for a page from another site" do
48
+ it "should return 404" do
49
+ get :show_page, :url => '/mypage'
50
+ response.should be_missing
51
+ end
52
+ end
53
+
54
+ describe "but for a page that doesn't exist" do
55
+ it "should still return 404" do
56
+ get :show_page, :url => '/notanyonespage'
57
+ response.should be_missing
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,13 @@
1
+ class SitePagesDataset < Dataset::Base
2
+ uses :home_page
3
+
4
+ def load
5
+ create_page "Myhomepage", :body => 'This is my page', :slug => '/' do
6
+ create_page "Myotherpage", :body => 'This is my other page', :slug => 'mypage'
7
+ end
8
+ create_page "Yourhomepage", :body => 'This is your home page', :slug => '/' do
9
+ create_page "Yourotherpage", :body => 'This is your other page', :slug => 'yourpage'
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,10 @@
1
+ class SitesDataset < Dataset::Base
2
+ uses :site_pages
3
+
4
+ def load
5
+ create_record Site, :mysite, :name => 'My Site', :domain => 'mysite.domain.com', :base_domain => 'mysite.domain.com', :position => 1, :homepage_id => page_id(:myhomepage)
6
+ create_record Site, :yoursite, :name => 'Your Site', :domain => '^yoursite', :base_domain => 'yoursite.test.com', :position => 2, :homepage_id => page_id(:yourhomepage)
7
+ create_record Site, :default, :name => 'Default', :base_domain => 'digitalpulp\.com', :position => 3, :homepage_id => page_id(:home)
8
+ create_record Site, :testing, :name => 'Test host', :domain => '^test\.', :base_domain => 'test.host', :position => 6
9
+ end
10
+ end
@@ -0,0 +1,37 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ TestController = Class.new(ApplicationController)
4
+
5
+ describe TestController, "for MultiSite routing" do
6
+ dataset :sites
7
+
8
+ before(:all) do
9
+ ActionController::Routing::Routes.clear!
10
+ ActionController::Routing::Routes.draw do |map|
11
+ map.connect '/single', :controller => 'test', :action => "index", :conditions => { :site => 'My Site' }
12
+ map.connect '/multi', :controller => 'test', :action => "index", :conditions => { :site => ['My Site', 'Your Site'] }
13
+ end
14
+ end
15
+
16
+ describe "with single site" do
17
+ it "should recognize routing" do
18
+ {:controller => 'test', :action => 'index'}.should recognize_request("http://mysite.domain.com/single")
19
+ end
20
+
21
+ it "should not recognize an undefined route" do
22
+ {:controller => 'test', :action => 'index'}.should_not recognize_request("http://yoursite.domain.com/single")
23
+ end
24
+ end
25
+
26
+ describe "with multiple sites" do
27
+ it "should recognize routing" do
28
+ {:controller => 'test', :action => "index"}.should recognize_request("http://mysite.domain.com/multi")
29
+ {:controller => 'test', :action => "index"}.should recognize_request("http://yoursite.domain.com/multi")
30
+ end
31
+
32
+ it "should not recognize an undefined route" do
33
+ {:controller => 'test', :action => "index"}.should_not recognize_request("http://digitalpulp.com/multi")
34
+ end
35
+ end
36
+
37
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe "AdminUI extensions for multi_site" do
4
+ before :each do
5
+ @admin = Radiant::AdminUI.new
6
+ @admin.site = Radiant::AdminUI.load_default_site_regions
7
+ end
8
+
9
+ it "should be included into Radiant::AdminUI" do
10
+ Radiant::AdminUI.included_modules.should include(MultiSite::AdminUI)
11
+ end
12
+
13
+ it "should define a collection of Region Sets for sites" do
14
+ @admin.should respond_to('site')
15
+ @admin.should respond_to('sites')
16
+ @admin.send('site').should_not be_nil
17
+ @admin.send('site').should be_kind_of(OpenStruct)
18
+ end
19
+
20
+ describe "should define default regions" do
21
+ %w{new edit remove index}.each do |action|
22
+
23
+ describe "for '#{action}'" do
24
+ before do
25
+ @site = @admin.site
26
+ @site.send(action).should_not be_nil
27
+ end
28
+
29
+ it "as a RegionSet" do
30
+ @site.send(action).should be_kind_of(Radiant::AdminUI::RegionSet)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,182 @@
1
+ require File.dirname(__FILE__) + "/../../spec_helper"
2
+
3
+ describe 'extended AR::Base' do
4
+ it "should respond to is_site_scoped" do
5
+ ActiveRecord::Base.respond_to?(:is_site_scoped).should be_true
6
+ end
7
+ end
8
+
9
+
10
+ # I need to change this to use an arbitrary model. at the moment these tests fail unless scoped_admin is installed, which is no help
11
+
12
+
13
+ # describe "scoped, unshareable model", :type => :model do
14
+ # dataset :sites
15
+ # dataset :users
16
+ #
17
+ # before do
18
+ # Page.stub!(:current_site).and_return(sites(:mysite))
19
+ # UserActionObserver.stub!(:current_user).and_return(users(:admin))
20
+ # Snippet.stub!(:site_id).and_return(site_id(:mysite))
21
+ # Snippet.send :is_site_scoped
22
+ # end
23
+ #
24
+ # it "should report itself site_scoped" do
25
+ # Snippet.is_site_scoped?.should be_true
26
+ # end
27
+ #
28
+ # it "should not report itself shareable" do
29
+ # Snippet.is_shareable?.should_not be_true
30
+ # end
31
+ #
32
+ # it "should have a site association" do
33
+ # Snippet.reflect_on_association(:site).should_not be_nil
34
+ # end
35
+ #
36
+ # it "should respond to current_site" do
37
+ # Snippet.respond_to?(:current_site).should be_true
38
+ # end
39
+ #
40
+ # it "should not respond to current_site=" do
41
+ # Snippet.respond_to?(:current_site=).should be_false
42
+ # end
43
+ #
44
+ # it "should return the correct current site" do
45
+ # Snippet.send(:current_site).should == sites(:mysite)
46
+ # end
47
+ #
48
+ # describe "when instantiated" do
49
+ # before do
50
+ # @in_my_site = Snippet.new(:name => 'test snippet in mysite')
51
+ # end
52
+ #
53
+ # it "should not yet have a site" do
54
+ # @in_my_site.site.should be_nil
55
+ # end
56
+ #
57
+ # it "should accept a site" do
58
+ # @in_my_site.site = sites(:mysite)
59
+ # @in_my_site.site.should == sites(:mysite)
60
+ # end
61
+ # end
62
+ #
63
+ # describe "when validated" do
64
+ # before do
65
+ # @in_my_site = Snippet.new(:name => 'test_snippet_in_mysite')
66
+ # @in_my_site.valid?
67
+ # end
68
+ #
69
+ # it "should have been given the current site" do
70
+ # @in_my_site.site.should_not be_nil
71
+ # @in_my_site.site.should == sites(:mysite)
72
+ # end
73
+ #
74
+ # describe "with site-scope" do
75
+ # before do
76
+ # @existing = Snippet.create!(:name => 'testy', :site_id => site_id(:mysite))
77
+ # end
78
+ # it "should be invalid if its name is already in use on this site" do
79
+ # snippet = Snippet.new(:name => 'testy')
80
+ # snippet.valid?.should_not be_true
81
+ # snippet.errors.should_not be_nil
82
+ # snippet.errors.on(:name).should_not be_nil
83
+ # end
84
+ #
85
+ # it "should be valid even though its name is already in use on another site" do
86
+ # snippet = Snippet.new(:name => 'testy', :site_id => site_id(:yoursite) )
87
+ # snippet.valid?.should be_true
88
+ # end
89
+ # end
90
+ # end
91
+ #
92
+ # describe "on retrieval" do
93
+ # before do
94
+ # 20.times { |i| @mine = Snippet.create!(:name => "snippet#{i}", :site_id => site_id(:mysite)) }
95
+ # 20.times { |i| @yours = Snippet.create!(:name => "snippet#{i+20}", :site_id => site_id(:yoursite)) }
96
+ # end
97
+ #
98
+ # it "should find a snippet from the current site" do
99
+ # lambda {@snippet = Snippet.find(@mine.id)}.should_not raise_error(ActiveRecord::RecordNotFound)
100
+ # @snippet.should_not be_nil
101
+ # @snippet.site.should == sites(:mysite)
102
+ # end
103
+ #
104
+ # it "should find_by_name a snippet from the current site" do
105
+ # lambda {@snippet = Snippet.find_by_name('snippet10')}.should_not raise_error(ActiveRecord::RecordNotFound)
106
+ # @snippet.should_not be_nil
107
+ # @snippet.site.should == sites(:mysite)
108
+ # end
109
+ #
110
+ # it "should not find a snippet from another site" do
111
+ # lambda {@snippet = Snippet.find(@yours.id)}.should raise_error(ActiveRecord::RecordNotFound)
112
+ # end
113
+ #
114
+ # it "should not find_by_name a snippet from another site" do
115
+ # @snippet = Snippet.find_by_name('snippet30').should be_nil
116
+ # end
117
+ #
118
+ # it "should count only the snippets from this site" do
119
+ # Snippet.count(:all).should == 20
120
+ # end
121
+ #
122
+ # end
123
+ # end
124
+ #
125
+ #
126
+ #
127
+ # describe "scoped, shareable model", :type => :model do
128
+ # dataset :sites
129
+ # dataset :users
130
+ #
131
+ # before do
132
+ # User.stub!(:site_id).and_return(site_id(:mysite))
133
+ # User.stub!(:site_id=)
134
+ # User.send :is_site_scoped, :shareable => true
135
+ # Page.current_site = sites(:mysite)
136
+ # end
137
+ #
138
+ # describe "on instantiation with no site" do
139
+ # before do
140
+ # @user = User.new(:name => 'test user', :login => 'test', :password => 'password', :email => 'test@spanner.org', :password_confirmation => 'password' )
141
+ # @otheruser = User.new(:name => 'other user', :site => sites(:yoursite), :login => 'other', :password => 'password', :email => 'other@spanner.org', :password_confirmation => 'password' )
142
+ # end
143
+ #
144
+ # it "should validate without a site" do
145
+ # @user.valid?.should be_true
146
+ # @user.site.should be_nil
147
+ # end
148
+ #
149
+ # it "should validate with a site" do
150
+ # @otheruser.valid?.should be_true
151
+ # @otheruser.site.should_not be_nil
152
+ # end
153
+ # end
154
+ #
155
+ # describe "on retrieval" do
156
+ # before do
157
+ # @user = User.create(:name => 'shared user', :login => 'shared', :password => 'password', :email => 'test@spanner.org', :password_confirmation => 'password' )
158
+ # @localuser = User.create(:name => 'local user', :site => sites(:mysite), :login => 'ocal', :password => 'password', :email => 'local@spanner.org', :password_confirmation => 'password' )
159
+ # @otheruser = User.create(:name => 'other user', :site => sites(:yoursite), :login => 'other', :password => 'password', :email => 'other@spanner.org', :password_confirmation => 'password' )
160
+ # end
161
+ #
162
+ # it "should find a user with no site" do
163
+ # lambda {User.find(@user.id)}.should_not raise_error(ActiveRecord::RecordNotFound)
164
+ # end
165
+ #
166
+ # it "should find a user from the current site" do
167
+ # lambda {User.find(@localuser.id)}.should_not raise_error(ActiveRecord::RecordNotFound)
168
+ # end
169
+ #
170
+ # it "should not find a user from another site" do
171
+ # lambda {User.find(@otheruser.id)}.should raise_error(ActiveRecord::RecordNotFound)
172
+ # end
173
+ #
174
+ # it "should count the users from this site or with no site" do
175
+ # # users_dataset creates 5 users with no site. we just made one shared and one local: total 7
176
+ # User.count(:all).should == 7
177
+ # end
178
+ # end
179
+ #
180
+ #
181
+ #
182
+ #end
@@ -0,0 +1,38 @@
1
+ module Spec
2
+ module Rails
3
+ module Matchers
4
+
5
+ class Route
6
+ def initialize(url)
7
+ uri = URI.parse(url)
8
+ @request = ActionController::TestRequest.new
9
+ @request.env["HTTPS"] = uri.scheme == "https" ? "on" : nil
10
+ @request.host = uri.host
11
+ @request.request_uri = uri.path.empty? ? "/" : uri.path
12
+ end
13
+
14
+ def matches?(options)
15
+ @options = options
16
+ begin
17
+ ActionController::Routing::Routes.recognize(@request) && @options == @request.symbolized_path_parameters
18
+ rescue # recognize raises an error
19
+ false
20
+ end
21
+ end
22
+
23
+ def failure_message
24
+ "expected #{@request.request_uri} to be recognized as #{@options.inspect}"
25
+ end
26
+
27
+ def negative_failure_message
28
+ "expected #{@request.request_uri} to not be recognized as #{@options.inspect}"
29
+ end
30
+ end
31
+
32
+ def recognize_request(url)
33
+ Route.new(url)
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Page do
4
+ dataset :sites
5
+
6
+ before do
7
+ @page = pages(:home)
8
+ end
9
+
10
+ describe "#url" do
11
+ it "should alias default" do
12
+ @page.should respond_to(:url_with_sites)
13
+ @page.should respond_to(:url_without_sites)
14
+ end
15
+
16
+ it "should override slug" do
17
+ @page.url.should eql('/')
18
+ @page.slug = "some-slug"
19
+ @page.url.should eql('/')
20
+ end
21
+ end
22
+
23
+ describe ".find_by_url" do
24
+ it "should default to the catchall site" do
25
+ Page.current_site = nil
26
+ Page.find_by_url("/").should == pages(:home)
27
+ end
28
+
29
+ it "should find site-scoped pages" do
30
+ Page.current_site = sites(:mysite)
31
+ Page.find_by_url("/mypage").should == pages(:myotherpage)
32
+ end
33
+
34
+ it "should not find pages outside the site" do
35
+ Page.current_site = sites(:mysite)
36
+ Page.find_by_url("/yourotherpage").should be_nil
37
+ end
38
+ end
39
+
40
+ describe "#destroy" do
41
+ it "should nullify homepage_id" do
42
+ sites(:mysite).homepage_id.should_not be_nil
43
+ pages(:home).destroy
44
+ sites(:mysite).reload.homepage_id.should be_nil
45
+ end
46
+ end
47
+
48
+ end
@@ -0,0 +1,83 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Site do
4
+ dataset :sites
5
+
6
+ before do
7
+ @site = Site.new :name => "Test Site", :domain => "test", :homepage_id => 1, :base_domain => "test.host", :homepage_id => page_id(:home)
8
+ end
9
+
10
+ it "should require a name" do
11
+ @site.name = nil
12
+ @site.should_not be_valid
13
+ @site.errors.on(:name).should_not be_empty
14
+ end
15
+
16
+ it "should require a base domain" do
17
+ @site.base_domain = nil
18
+ @site.should_not be_valid
19
+ assert_not_nil @site.errors.on(:base_domain)
20
+ end
21
+
22
+ it "should require unique domain" do
23
+ @site.domain = sites(:default).domain
24
+ @site.should_not be_valid
25
+ @site.errors.on(:domain).should_not be_empty
26
+ end
27
+
28
+ it "should have an associated homepage" do
29
+ @site.should respond_to(:homepage)
30
+ @site.homepage.should eql(pages(:home))
31
+ end
32
+
33
+ it "should create a homepage on create" do
34
+ @site.homepage_id = nil
35
+ @site.save.should eql(true)
36
+ @site.homepage.should_not be_nil
37
+ @site.homepage.should be_valid
38
+ @site.homepage.parts.each { |part| part.should be_valid }
39
+ @site.homepage.should_not be_new_record
40
+ end
41
+
42
+ it "should respect default page status" do
43
+ Radiant::Config['defaults.page.status'] = :published
44
+ site = Site.new :name => "Test Site", :domain => "test", :base_domain => "test.host"
45
+ site.save
46
+ site.homepage.should be_published
47
+ end
48
+
49
+ it "should respect default page parts" do
50
+ Radiant::Config['defaults.page.parts'] = 'body,footnotes,other'
51
+ site = Site.new :name => "Test Site", :domain => "test", :base_domain => "test.host"
52
+ site.save
53
+ site.homepage.parts.size.should == 3
54
+ %w(body footnotes other).each do |part|
55
+ site.homepage.part(part).should be_kind_of(PagePart)
56
+ end
57
+ end
58
+
59
+ it "should find site for hostname" do
60
+ sites(:mysite).should eql(Site.find_for_host("mysite.domain.com"))
61
+ sites(:yoursite).should eql(Site.find_for_host("yoursite.com"))
62
+ sites(:yoursite).should eql(Site.find_for_host("yoursite.unknown.com"))
63
+ sites(:default).should eql(Site.find_for_host("unknown.com"))
64
+ end
65
+
66
+ it "should generate site url from path" do
67
+ sites(:mysite).url.should eql("http://mysite.domain.com/")
68
+ sites(:mysite).url("/about").should eql("http://mysite.domain.com/about")
69
+ end
70
+
71
+ it "should generate dev site url from path" do
72
+ sites(:mysite).dev_url.should eql("http://dev.mysite.domain.com/")
73
+ sites(:mysite).dev_url("/about").should eql("http://dev.mysite.domain.com/about")
74
+ end
75
+
76
+ describe "#save" do
77
+ it "should reload routes" do
78
+ ActionController::Routing::Routes.should_receive(:reload)
79
+ @site.save
80
+ end
81
+ end
82
+
83
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format progress
3
+ --format html:spec/spec_report.html
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,36 @@
1
+ unless defined? RADIANT_ROOT
2
+ ENV["RAILS_ENV"] = "test"
3
+ case
4
+ when ENV["RADIANT_ENV_FILE"]
5
+ require ENV["RADIANT_ENV_FILE"]
6
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
7
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
8
+ else
9
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
10
+ end
11
+ end
12
+ require "#{RADIANT_ROOT}/spec/spec_helper"
13
+
14
+ Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
15
+
16
+ if File.directory?(File.dirname(__FILE__) + "/matchers")
17
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
18
+ end
19
+
20
+ Spec::Runner.configure do |config|
21
+ # config.use_transactional_fixtures = true
22
+ # config.use_instantiated_fixtures = false
23
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
24
+
25
+ # You can declare fixtures for each behaviour like this:
26
+ # describe "...." do
27
+ # fixtures :table_a, :table_b
28
+ #
29
+ # Alternatively, if you prefer to declare them only once, you can
30
+ # do so here, like so ...
31
+ #
32
+ # config.global_fixtures = :table_a, :table_b
33
+ #
34
+ # If you declare global fixtures, be aware that they will be declared
35
+ # for all of your examples, even those that don't use them.
36
+ end
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "trusty-multi-site-extension"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "trusty-multi-site-extension"
7
+ s.version = "1.0.0"
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
+ s.authors = ["Eric Sipple"]
10
+ s.date = %q{2014-10-07}
11
+ s.description = %q{Extends Trusty CMS Layouts to support multiple sites, defined by domain}
12
+ s.email = %q{sipple@trustarts.org}
13
+ s.homepage = %q{https://github.com/pgharts/trusty-multi-site-extension}
14
+ s.summary = %q{Extends Trusty CMS Layouts to support multiple sites, defined by domain}
15
+
16
+ ignores = if File.exist?('.gitignore')
17
+ File.read('.gitignore').split("\n").inject([]) {|a,p| a + Dir[p] }
18
+ else
19
+ []
20
+ end
21
+ s.files = Dir['**/*'] - ignores
22
+ s.test_files = Dir['test/**/*','spec/**/*','features/**/*'] - ignores
23
+ # s.executables = Dir['bin/*'] - ignores
24
+ s.require_paths = ["lib"]
25
+ s.add_dependency "acts_as_list", "0.4.0"
26
+ s.add_dependency "trusty-snippets-extension", "~> 1.0.0"
27
+ s.add_dependency "trusty-cms", "~> 1.0.1"
28
+ end