locomotive_cms 0.0.2.4 → 0.0.2.5
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.
- data/Gemfile +1 -0
- data/app/models/theme_asset.rb +2 -11
- data/app/uploaders/theme_asset_uploader.rb +0 -10
- data/app/views/admin/custom_fields/_index.html.haml +2 -2
- data/app/views/admin/shared/_head.html.haml +2 -2
- data/app/views/admin/shared/menu/_contents.html.haml +2 -2
- data/app/views/layouts/admin/login.html.haml +1 -1
- data/config/environments/development.rb +1 -2
- data/config/locales/admin_ui_en.yml +2 -0
- data/lib/generators/locomotive/install/templates/locomotive.rb +14 -0
- data/lib/locomotive.rb +15 -1
- data/lib/locomotive/configuration.rb +3 -2
- data/lib/locomotive/heroku.rb +59 -0
- data/lib/locomotive/heroku/custom_domain.rb +52 -0
- data/lib/locomotive/logger.rb +11 -0
- data/lib/locomotive/regexps.rb +1 -1
- data/lib/locomotive/render.rb +0 -1
- data/lib/locomotive/routing/site_dispatcher.rb +1 -1
- data/public/javascripts/admin/custom_fields.js +11 -10
- data/public/javascripts/admin/utils.js +5 -0
- data/public/stylesheets/admin/application.css +2 -2
- data/spec/lib/locomotive/heroku_spec.rb +149 -0
- data/spec/models/site_spec.rb +6 -2
- data/spec/spec_helper.rb +1 -0
- data/spec/support/locomotive.rb +1 -0
- metadata +19 -3
data/Gemfile
CHANGED
@@ -20,6 +20,7 @@ gem "mimetype-fu", :require => "mimetype_fu"
|
|
20
20
|
gem "formtastic-rails3", :require => "formtastic"
|
21
21
|
gem "carrierwave-rails3", :require => "carrierwave"
|
22
22
|
gem "actionmailer-with-request", :require => 'actionmailer_with_request'
|
23
|
+
gem "heroku"
|
23
24
|
|
24
25
|
# Development environment
|
25
26
|
group :development do
|
data/app/models/theme_asset.rb
CHANGED
@@ -41,7 +41,7 @@ class ThemeAsset
|
|
41
41
|
|
42
42
|
def plain_text
|
43
43
|
@plain_text ||= (if self.stylesheet? || self.javascript?
|
44
|
-
|
44
|
+
self.source.read
|
45
45
|
else
|
46
46
|
nil
|
47
47
|
end)
|
@@ -63,19 +63,10 @@ class ThemeAsset
|
|
63
63
|
|
64
64
|
self.source = CarrierWave::SanitizedFile.new({
|
65
65
|
:tempfile => StringIO.new(self.plain_text),
|
66
|
-
:filename => self.
|
66
|
+
:filename => "#{self.slug}.#{self.stylesheet? ? 'css' : 'js'}"
|
67
67
|
})
|
68
68
|
end
|
69
69
|
|
70
|
-
def filename
|
71
|
-
if not self.image?
|
72
|
-
# TODO: fix that for handling not image / stylesheets / javascripts assets
|
73
|
-
"#{self.slug}.#{self.stylesheet? ? 'css' : 'js'}"
|
74
|
-
else
|
75
|
-
"#{self.slug}#{File.extname(self.source.file.original_filename)}"
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
70
|
def to_liquid
|
80
71
|
{ :url => self.source.url }.merge(self.attributes)
|
81
72
|
end
|
@@ -29,14 +29,4 @@ class ThemeAssetUploader < AssetUploader
|
|
29
29
|
%w(jpg jpeg gif png css js)
|
30
30
|
end
|
31
31
|
|
32
|
-
def filename
|
33
|
-
if model.slug.present?
|
34
|
-
model.filename
|
35
|
-
else
|
36
|
-
extension = File.extname(original_filename)
|
37
|
-
basename = File.basename(original_filename, extension).slugify(:underscore => true)
|
38
|
-
"#{basename}#{extension}"
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
32
|
end
|
@@ -5,7 +5,7 @@
|
|
5
5
|
= f.foldable_inputs :name => :custom_fields, :class => 'editable-list fields' do
|
6
6
|
- ordered_custom_fields.each do |field|
|
7
7
|
= f.fields_for collection_name.to_sym, field, :child_index => field._index do |g|
|
8
|
-
%li{ :class => "item added #{'error' unless field.errors.empty?}"}
|
8
|
+
%li{ :class => "item added #{'new' if f.object.new_record?} #{'error' unless field.errors.empty?}"}
|
9
9
|
%span.handle
|
10
10
|
= image_tag 'admin/form/icons/drag.png'
|
11
11
|
|
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
= g.hidden_field :hint, :class => 'hint'
|
17
17
|
|
18
|
-
= g.text_field :label
|
18
|
+
= g.text_field :label, :class => 'label'
|
19
19
|
|
20
20
|
—
|
21
21
|
|
@@ -8,9 +8,9 @@
|
|
8
8
|
/ [if IE]
|
9
9
|
= stylesheet_link_tag 'admin/blueprint/ie', :media => 'screen'
|
10
10
|
|
11
|
-
= stylesheet_link_tag 'admin/layout', 'admin/plugins/toggle', 'admin/menu', 'admin/buttons', 'admin/formtastic', 'admin/formtastic_changes', 'admin/application', :media => 'screen'
|
11
|
+
= stylesheet_link_tag 'admin/layout', 'admin/plugins/toggle', 'admin/menu', 'admin/buttons', 'admin/formtastic', 'admin/formtastic_changes', 'admin/application', :media => 'screen', :cache => Rails.env.production? && !Locomotive.heroku?
|
12
12
|
|
13
|
-
= javascript_include_tag 'admin/jquery', 'admin/jquery.ui', 'admin/rails', 'admin/utils', 'admin/plugins/toggle', 'admin/plugins/growl', 'admin/plugins/cookie', 'admin/application'
|
13
|
+
= javascript_include_tag 'admin/jquery', 'admin/jquery.ui', 'admin/rails', 'admin/utils', 'admin/plugins/toggle', 'admin/plugins/growl', 'admin/plugins/cookie', 'admin/application', :cache => Rails.env.production? && !Locomotive.heroku?
|
14
14
|
|
15
15
|
%script{ :type => 'text/javascript' }
|
16
16
|
= find_and_preserve(growl_message)
|
@@ -7,7 +7,7 @@
|
|
7
7
|
%ul
|
8
8
|
- current_site.pages.latest_updated.each do |page|
|
9
9
|
%li
|
10
|
-
= link_to truncate(page.title, :length =>
|
10
|
+
= link_to truncate(page.title, :length => 30), edit_admin_page_url(page)
|
11
11
|
%span= time_ago_in_words(page.updated_at)
|
12
12
|
|
13
13
|
- current_site.content_types.each do |content_type|
|
@@ -20,7 +20,7 @@
|
|
20
20
|
%ul
|
21
21
|
- content_type.contents.latest_updated.each do |content|
|
22
22
|
%li
|
23
|
-
= link_to truncate(content.send(content_type.highlighted_field_name), :length =>
|
23
|
+
= link_to truncate(content.send(content_type.highlighted_field_name), :length => 30), edit_admin_content_path(content_type.slug, content)
|
24
24
|
%span= time_ago_in_words(content.updated_at)
|
25
25
|
|
26
26
|
.action
|
@@ -4,7 +4,7 @@
|
|
4
4
|
%head
|
5
5
|
%title= escape_once("#{Locomotive.config.name} — #{current_site.name}")
|
6
6
|
|
7
|
-
= stylesheet_link_tag 'admin/blueprint/screen', 'admin/login', :media => 'screen'
|
7
|
+
= stylesheet_link_tag 'admin/blueprint/screen', 'admin/login', :media => 'screen', :cache => Rails.env.production? && !Locomotive.config.heroku
|
8
8
|
/ [if IE]
|
9
9
|
= stylesheet_link_tag('admin/blueprint/ie', :media => 'screen')
|
10
10
|
|
@@ -9,4 +9,18 @@ Locomotive.configure do |config|
|
|
9
9
|
|
10
10
|
# tell if logs are enabled. Useful for debug purpose.
|
11
11
|
config.enable_logs = true
|
12
|
+
|
13
|
+
# tell if the application is hosted on Heroku.
|
14
|
+
# Locomotive uses heroku api to add / remove domains.
|
15
|
+
# there are 2 ways of passing heroku credentials to Locomotive
|
16
|
+
# - from ENV variables: HEROKU_LOGIN & HEROKU_PASSWORD
|
17
|
+
# - from this file
|
18
|
+
#
|
19
|
+
# Notes:
|
20
|
+
# - IMPORTANT: behaviours related to this option will only be applied in production
|
21
|
+
# - credentials coming from this file take precedence over ENV variables
|
22
|
+
#
|
23
|
+
# Ex:
|
24
|
+
# config.heroku = { :name => '<my heroku app name>', :login => 'john@doe.net', :password => 'easy' }
|
25
|
+
config.heroku = false
|
12
26
|
end
|
data/lib/locomotive.rb
CHANGED
@@ -1,12 +1,16 @@
|
|
1
1
|
# require 'locomotive/patches'
|
2
2
|
require 'locomotive/configuration'
|
3
|
+
require 'locomotive/logger'
|
3
4
|
require 'locomotive/liquid'
|
4
5
|
require 'locomotive/mongoid'
|
6
|
+
require 'locomotive/heroku'
|
5
7
|
|
6
8
|
require 'mongo_session_store/mongoid'
|
7
9
|
|
8
10
|
module Locomotive
|
9
11
|
|
12
|
+
include Locomotive::Heroku
|
13
|
+
|
10
14
|
class << self
|
11
15
|
attr_accessor :config
|
12
16
|
|
@@ -26,12 +30,22 @@ module Locomotive
|
|
26
30
|
def self.after_configure
|
27
31
|
raise '[Error] Locomotive needs a default domain name' if Locomotive.config.default_domain.blank?
|
28
32
|
|
29
|
-
ActionMailer::Base.default_url_options[:host] =
|
33
|
+
ActionMailer::Base.default_url_options[:host] = self.config.default_domain + (Rails.env.development? ? ':3000' : '')
|
30
34
|
|
35
|
+
# cookies stored in mongodb
|
31
36
|
Rails.application.config.session_store :mongoid_store, {
|
32
37
|
:key => Locomotive.config.cookie_key,
|
33
38
|
:domain => ".#{Locomotive.config.default_domain}"
|
34
39
|
}
|
40
|
+
|
41
|
+
# Heroku support
|
42
|
+
self.enable_heroku if self.heroku?
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.logger(message)
|
46
|
+
if Locomotive.config.enable_logs == true
|
47
|
+
Rails.logger.info(message)
|
48
|
+
end
|
35
49
|
end
|
36
50
|
|
37
51
|
end
|
@@ -3,13 +3,14 @@ module Locomotive
|
|
3
3
|
|
4
4
|
@@defaults = {
|
5
5
|
:name => 'LocomotiveApp',
|
6
|
-
:default_domain => '
|
6
|
+
:default_domain => 'example.com',
|
7
7
|
:reserved_subdomains => %w{www admin email blog webmail mail support help site sites},
|
8
8
|
# :forbidden_paths => %w{layouts snippets stylesheets javascripts assets admin system api},
|
9
9
|
:reserved_slugs => %w{stylesheets javascripts assets admin images api pages},
|
10
10
|
:locales => %w{en fr},
|
11
11
|
:cookie_key => '_locomotive_session',
|
12
|
-
:enable_logs => false
|
12
|
+
:enable_logs => false,
|
13
|
+
:heroku => false
|
13
14
|
}
|
14
15
|
|
15
16
|
cattr_accessor :settings
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'heroku'
|
2
|
+
|
3
|
+
module Locomotive
|
4
|
+
module Heroku
|
5
|
+
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
class << self
|
10
|
+
attr_accessor :heroku_connection
|
11
|
+
attr_accessor :heroku_domains
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
|
17
|
+
def heroku?
|
18
|
+
!self.config.heroku.nil? && self.config.heroku.respond_to?(:[])
|
19
|
+
end
|
20
|
+
|
21
|
+
def enable_heroku
|
22
|
+
raise 'Heroku application name is mandatory' if self.config.heroku[:name].blank?
|
23
|
+
|
24
|
+
self.open_heroku_connection
|
25
|
+
self.enhance_site_model
|
26
|
+
|
27
|
+
# "cache" domains for better performance
|
28
|
+
self.heroku_domains = self.heroku_connection.list_domains(self.config.heroku[:name]).collect { |h| h[:domain] }
|
29
|
+
end
|
30
|
+
|
31
|
+
def open_heroku_connection
|
32
|
+
login = self.config.heroku[:login] || ENV['HEROKU_LOGIN']
|
33
|
+
password = self.config.heroku[:password] || ENV['HEROKU_PASSWORD']
|
34
|
+
|
35
|
+
self.heroku_connection = ::Heroku::Client.new(login, password)
|
36
|
+
end
|
37
|
+
|
38
|
+
def enhance_site_model
|
39
|
+
Site.send :include, Locomotive::Heroku::CustomDomain
|
40
|
+
end
|
41
|
+
|
42
|
+
# manage domains
|
43
|
+
|
44
|
+
def add_heroku_domain(name)
|
45
|
+
Locomotive.logger "[add heroku domain] #{name}"
|
46
|
+
self.heroku_connection.add_domain(self.config.heroku[:name], name)
|
47
|
+
self.heroku_domains << name
|
48
|
+
end
|
49
|
+
|
50
|
+
def remove_heroku_domain(name)
|
51
|
+
Locomotive.logger "[remove heroku domain] #{name}"
|
52
|
+
self.heroku_connection.remove_domain(self.config.heroku[:name], name)
|
53
|
+
self.heroku_domains.delete(name)
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Heroku
|
3
|
+
module CustomDomain
|
4
|
+
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
included do
|
8
|
+
|
9
|
+
after_save :add_heroku_domains
|
10
|
+
after_destroy :remove_heroku_domains
|
11
|
+
|
12
|
+
alias_method_chain :add_subdomain_to_domains, :heroku
|
13
|
+
end
|
14
|
+
|
15
|
+
module InstanceMethods
|
16
|
+
|
17
|
+
protected
|
18
|
+
|
19
|
+
def add_subdomain_to_domains_with_heroku
|
20
|
+
unless self.domains_change.nil?
|
21
|
+
full_subdomain = "#{self.subdomain}.#{Locomotive.config.default_domain}"
|
22
|
+
@heroku_domains_change = {
|
23
|
+
:added => self.domains_change.last - self.domains_change.first - [full_subdomain],
|
24
|
+
:removed => self.domains_change.first - self.domains_change.last - [full_subdomain]
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
add_subdomain_to_domains_without_heroku
|
29
|
+
end
|
30
|
+
|
31
|
+
def add_heroku_domains
|
32
|
+
return if @heroku_domains_change.nil?
|
33
|
+
|
34
|
+
@heroku_domains_change[:added].each do |name|
|
35
|
+
Locomotive.add_heroku_domain(name)
|
36
|
+
end
|
37
|
+
@heroku_domains_change[:removed].each do |name|
|
38
|
+
Locomotive.remove_heroku_domain(name)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def remove_heroku_domains
|
43
|
+
self.domains_without_subdomain.each do |name|
|
44
|
+
Locomotive.remove_heroku_domain(name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/locomotive/regexps.rb
CHANGED
data/lib/locomotive/render.rb
CHANGED
@@ -36,7 +36,6 @@ module Locomotive
|
|
36
36
|
assigns = {
|
37
37
|
'site' => current_site,
|
38
38
|
'asset_collections' => Locomotive::Liquid::Drops::AssetCollections.new(current_site),
|
39
|
-
# 'theme_assets' => Locomotive::Liquid::Drops::ThemeAssets.new(current_site),
|
40
39
|
'stylesheets' => Locomotive::Liquid::Drops::Stylesheets.new(current_site),
|
41
40
|
'javascripts' => Locomotive::Liquid::Drops::Javascripts.new(current_site),
|
42
41
|
'contents' => Locomotive::Liquid::Drops::Contents.new(current_site),
|
@@ -19,7 +19,7 @@ module Locomotive
|
|
19
19
|
protected
|
20
20
|
|
21
21
|
def fetch_site
|
22
|
-
logger
|
22
|
+
Locomotive.logger "[fetch site] host = #{request.host} / #{request.env['HTTP_HOST']}"
|
23
23
|
@current_site ||= Site.match_domain(request.host).first
|
24
24
|
end
|
25
25
|
|
@@ -44,6 +44,10 @@ $(document).ready(function() {
|
|
44
44
|
|
45
45
|
$('fieldset.fields li.template button').click(function() {
|
46
46
|
var lastRow = $(this).parents('li.template');
|
47
|
+
|
48
|
+
var label = lastRow.find('input.label').val().trim();
|
49
|
+
if (label == '' || label == defaultValue) return false;
|
50
|
+
|
47
51
|
var newRow = lastRow.clone(true).removeClass('template').addClass('added new').insertBefore(lastRow);
|
48
52
|
|
49
53
|
var dateFragment = '[' + new Date().getTime() + ']';
|
@@ -51,10 +55,6 @@ $(document).ready(function() {
|
|
51
55
|
$(this).attr('name', $(this).attr('name').replace('[-1]', dateFragment));
|
52
56
|
});
|
53
57
|
|
54
|
-
// should copy the value of the select box
|
55
|
-
var input = newRow.find('input.label');
|
56
|
-
if (lastRow.find('input.label').val() == '') input.val("undefined");
|
57
|
-
|
58
58
|
var select = newRow.find('select')
|
59
59
|
.val(lastRow.find('select').val())
|
60
60
|
.change(function() { selectOnChange(select); })
|
@@ -73,9 +73,8 @@ $(document).ready(function() {
|
|
73
73
|
select.show();
|
74
74
|
});
|
75
75
|
|
76
|
-
// then reset the form
|
77
|
-
lastRow.find('input').val(defaultValue).addClass('void');
|
78
|
-
lastRow.find('select').val('input');
|
76
|
+
// then "reset" the form
|
77
|
+
lastRow.find('input.label').val(defaultValue).addClass('void');
|
79
78
|
|
80
79
|
// warn the sortable widget about the new row
|
81
80
|
$("fieldset.fields ol").sortable('refresh');
|
@@ -124,7 +123,7 @@ $(document).ready(function() {
|
|
124
123
|
e.stopPropagation();
|
125
124
|
});
|
126
125
|
|
127
|
-
var alias = link.parent().prevAll('.alias').val();
|
126
|
+
var alias = link.parent().prevAll('.alias').val().trim();
|
128
127
|
if (alias == '') alias = makeSlug(link.parent().prevAll('.label').val());
|
129
128
|
$('#fancybox-wrap #custom_fields_field__alias').val(alias);
|
130
129
|
|
@@ -132,8 +131,10 @@ $(document).ready(function() {
|
|
132
131
|
$('#fancybox-wrap #custom_fields_field_hint').val(hint);
|
133
132
|
},
|
134
133
|
onCleanup: function() {
|
135
|
-
|
136
|
-
link.parent().prevAll('.
|
134
|
+
var alias = $('#fancybox-wrap #custom_fields_field__alias').val().trim();
|
135
|
+
if (alias != '') link.parent().prevAll('.alias').val(alias);
|
136
|
+
var hint = $('#fancybox-wrap #custom_fields_field_hint').val().trim();
|
137
|
+
if (hint != '') link.parent().prevAll('.hint').val(hint);
|
137
138
|
}
|
138
139
|
})
|
139
140
|
});
|
@@ -1,4 +1,5 @@
|
|
1
1
|
function makeSlug(val, sep) { // code largely inspired by http://www.thewebsitetailor.com/jquery-slug-plugin/
|
2
|
+
if (typeof val == 'undefined') return('');
|
2
3
|
if (typeof sep == 'undefined') sep = '_';
|
3
4
|
var alphaNumRegexp = new RegExp('[^a-zA-Z0-9\\' + sep + ']', 'g');
|
4
5
|
var avoidDuplicateRegexp = new RegExp('[\\' + sep + ']{2,}', 'g');
|
@@ -7,3 +8,7 @@ function makeSlug(val, sep) { // code largely inspired by http://www.thewebsitet
|
|
7
8
|
val = val.replace(avoidDuplicateRegexp, sep);
|
8
9
|
return val.toLowerCase();
|
9
10
|
}
|
11
|
+
|
12
|
+
String.prototype.trim = function() {
|
13
|
+
return this.replace(/^\s+/g, '').replace(/\s+$/g, '');
|
14
|
+
}
|
@@ -121,7 +121,7 @@ ul.assets li.asset h4 { margin: 0px; height: 30px; }
|
|
121
121
|
|
122
122
|
ul.assets li.asset h4 a {
|
123
123
|
position: relative;
|
124
|
-
top:
|
124
|
+
top: 6px;
|
125
125
|
left: 12px;
|
126
126
|
font-weight: bold;
|
127
127
|
font-size: 0.6em;
|
@@ -149,7 +149,7 @@ ul.assets li.asset div.image div.inside {
|
|
149
149
|
|
150
150
|
ul.assets li.asset div.actions {
|
151
151
|
position: absolute;
|
152
|
-
top:
|
152
|
+
top: 7px;
|
153
153
|
right: 12px;
|
154
154
|
}
|
155
155
|
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Heroku support' do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
::Heroku::Client.any_instance.stubs(:post).returns(true)
|
7
|
+
::Heroku::Client.any_instance.stubs(:delete).returns(true)
|
8
|
+
end
|
9
|
+
|
10
|
+
context '#loaded' do
|
11
|
+
|
12
|
+
it 'has method to enable heroku' do
|
13
|
+
Locomotive.respond_to?(:enable_heroku).should be_true
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'tells heroku is disabled' do
|
17
|
+
Locomotive.heroku?.should be_false
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'does not add instance methods to Site' do
|
21
|
+
Site.instance_methods.include?(:add_heroku_domains).should be_false
|
22
|
+
Site.instance_methods.include?(:remove_heroku_domains).should be_false
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
context '#disabled' do
|
28
|
+
|
29
|
+
before(:each) do
|
30
|
+
Locomotive.configure do |config|
|
31
|
+
config.heroku = false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'has a nil connection' do
|
36
|
+
Locomotive.heroku_connection.should be_nil
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'tells heroku is disabled' do
|
40
|
+
Locomotive.heroku?.should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'does not add methods to Site' do
|
44
|
+
Site.instance_methods.include?(:add_heroku_domains).should be_false
|
45
|
+
Site.instance_methods.include?(:remove_heroku_domains).should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
context '#enabled' do
|
51
|
+
|
52
|
+
it 'tells heroku is disabled' do
|
53
|
+
configure_locomotive_with_heroku
|
54
|
+
Locomotive.heroku?.should be_true
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'raises an exception if no app name is given' do
|
58
|
+
lambda {
|
59
|
+
configure_locomotive_with_heroku(:name => nil)
|
60
|
+
}.should raise_error
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'dealing with heroku connection' do
|
64
|
+
|
65
|
+
it 'opens a heroku connection with provided credentials' do
|
66
|
+
configure_locomotive_with_heroku
|
67
|
+
Locomotive.heroku_connection.user.should == 'john@doe.net'
|
68
|
+
Locomotive.heroku_connection.password.should == 'easyone'
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'opens a heroku connection with env credentials' do
|
72
|
+
ENV['HEROKU_LOGIN'] = 'john@doe.net'; ENV['HEROKU_PASSWORD'] = 'easyone'
|
73
|
+
Locomotive.configure { |config| config.heroku = true }
|
74
|
+
Locomotive.heroku_connection.user.should == 'john@doe.net'
|
75
|
+
Locomotive.heroku_connection.password.should == 'easyone'
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
context 'enhancing site' do
|
81
|
+
|
82
|
+
before(:each) do
|
83
|
+
configure_locomotive_with_heroku
|
84
|
+
(@site = Factory.build(:site)).stubs(:valid?).returns(true)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'calls add_heroku_domains after saving a site' do
|
88
|
+
@site.expects(:add_heroku_domains)
|
89
|
+
@site.save
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'calls remove_heroku_domains after saving a site' do
|
93
|
+
@site.expects(:remove_heroku_domains)
|
94
|
+
@site.destroy
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'adding domain' do
|
98
|
+
|
99
|
+
it 'does not add new domain if no delta' do
|
100
|
+
Locomotive.heroku_connection.expects(:add_domain).never
|
101
|
+
@site.save
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'adds a new domain if new one' do
|
105
|
+
@site.domains = ['www.acme.fr']
|
106
|
+
Locomotive.heroku_connection.expects(:add_domain).with('locomotive', 'www.acme.fr')
|
107
|
+
@site.save
|
108
|
+
Locomotive.heroku_domains.should include('www.acme.fr')
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context 'removing domain' do
|
113
|
+
|
114
|
+
it 'does not remove domain if no delta' do
|
115
|
+
Locomotive.heroku_connection.expects(:remove_domain).never
|
116
|
+
@site.destroy
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'removes domains if we destroy a site' do
|
120
|
+
@site.stubs(:domains_without_subdomain).returns(['www.acme.com'])
|
121
|
+
Locomotive.heroku_connection.expects(:remove_domain).with('locomotive', 'www.acme.com')
|
122
|
+
@site.destroy
|
123
|
+
Locomotive.heroku_domains.should_not include('www.acme.com')
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'removes domain if removed' do
|
127
|
+
@site.domains = ['www.acme.fr']; @site.save
|
128
|
+
@site.domains = ['www.acme.com']
|
129
|
+
Locomotive.heroku_connection.expects(:remove_domain).with('locomotive', 'www.acme.fr')
|
130
|
+
@site.save
|
131
|
+
Locomotive.heroku_domains.should_not include('www.acme.fr')
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
def configure_locomotive_with_heroku(options = {}, domains = nil)
|
141
|
+
::Heroku::Client.any_instance.stubs(:list_domains).with('locomotive').returns(domains || [
|
142
|
+
{ :domain => "www.acme.com" }, { :domain => "example.com" }, { :domain => "www.example.com" }
|
143
|
+
])
|
144
|
+
Locomotive.configure do |config|
|
145
|
+
config.heroku = { :name => 'locomotive', :login => 'john@doe.net', :password => 'easyone' }.merge(options)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
data/spec/models/site_spec.rb
CHANGED
@@ -2,6 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Site do
|
4
4
|
|
5
|
+
before(:each) do
|
6
|
+
Locomotive.stubs(:add_heroku_domain).returns(true)
|
7
|
+
end
|
8
|
+
|
5
9
|
it 'should have a valid factory' do
|
6
10
|
Factory.build(:site).should be_valid
|
7
11
|
end
|
@@ -20,13 +24,13 @@ describe Site do
|
|
20
24
|
site.errors[:subdomain].should == ["can't be blank"]
|
21
25
|
end
|
22
26
|
|
23
|
-
%w{test
|
27
|
+
%w{test test42}.each do |subdomain|
|
24
28
|
it "should accept subdomain like '#{subdomain}'" do
|
25
29
|
Factory.build(:site, :subdomain => subdomain).should be_valid
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
29
|
-
['-', '_test', 'test_', 't est', '42', '42test'].each do |subdomain|
|
33
|
+
['-', '_test', 'test_', 't est', '42', '42test', 'foo_bar'].each do |subdomain|
|
30
34
|
it "should not accept subdomain like '#{subdomain}'" do
|
31
35
|
(site = Factory.build(:site, :subdomain => subdomain)).should_not be_valid
|
32
36
|
site.errors[:subdomain].should == ['is invalid']
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/locomotive.rb
CHANGED
metadata
CHANGED
@@ -6,8 +6,8 @@ version: !ruby/object:Gem::Version
|
|
6
6
|
- 0
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.0.2.
|
9
|
+
- 5
|
10
|
+
version: 0.0.2.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Didier Lafforgue
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-06-
|
18
|
+
date: 2010-06-14 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -241,6 +241,18 @@ dependencies:
|
|
241
241
|
version: "0"
|
242
242
|
requirement: *id017
|
243
243
|
prerelease: false
|
244
|
+
- !ruby/object:Gem::Dependency
|
245
|
+
type: :runtime
|
246
|
+
name: heroku
|
247
|
+
version_requirements: &id018 !ruby/object:Gem::Requirement
|
248
|
+
requirements:
|
249
|
+
- - ">="
|
250
|
+
- !ruby/object:Gem::Version
|
251
|
+
segments:
|
252
|
+
- 0
|
253
|
+
version: "0"
|
254
|
+
requirement: *id018
|
255
|
+
prerelease: false
|
244
256
|
description: a brand new CMS system with super sexy UI and cool features (alpha version for now)
|
245
257
|
email:
|
246
258
|
- didier@nocoffee.fr
|
@@ -397,6 +409,8 @@ files:
|
|
397
409
|
- lib/locomotive/configuration.rb
|
398
410
|
- lib/locomotive/devise/sessions_controller.rb
|
399
411
|
- lib/locomotive/engine.rb
|
412
|
+
- lib/locomotive/heroku.rb
|
413
|
+
- lib/locomotive/heroku/custom_domain.rb
|
400
414
|
- lib/locomotive/liquid.rb
|
401
415
|
- lib/locomotive/liquid/db_file_system.rb
|
402
416
|
- lib/locomotive/liquid/drops/asset_collections.rb
|
@@ -414,6 +428,7 @@ files:
|
|
414
428
|
- lib/locomotive/liquid/tags/paginate.rb
|
415
429
|
- lib/locomotive/liquid/tags/snippet.rb
|
416
430
|
- lib/locomotive/liquid/tags/with_scope.rb
|
431
|
+
- lib/locomotive/logger.rb
|
417
432
|
- lib/locomotive/mongoid.rb
|
418
433
|
- lib/locomotive/mongoid/document.rb
|
419
434
|
- lib/locomotive/mongoid/model_extensions.rb
|
@@ -891,6 +906,7 @@ specification_version: 3
|
|
891
906
|
summary: Locomotive cms engine
|
892
907
|
test_files:
|
893
908
|
- spec/factories.rb
|
909
|
+
- spec/lib/locomotive/heroku_spec.rb
|
894
910
|
- spec/lib/locomotive/liquid/filters/html_spec.rb
|
895
911
|
- spec/lib/locomotive/liquid/filters/misc_spec.rb
|
896
912
|
- spec/lib/locomotive/liquid/tags/paginate_spec.rb
|