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