trusty-multi-site-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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