locomotivecms_steam 1.0.0.rc1 → 1.0.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c15327d7b834e6a45dc9c631bf3f7aca7320d2e0
4
- data.tar.gz: 7480937c0e40dee146c4b10684671f0da1bb638c
3
+ metadata.gz: 7867012e1ff99777a991748f000e8984ce4d9b14
4
+ data.tar.gz: d03ab3751750b477ad705af2735e886bab54f9b4
5
5
  SHA512:
6
- metadata.gz: cf0538f565ffd72f18d96ae008189df3256639ba5124c260a76cdf24e5654968525acfeee2cb57c190a80b6edd3abb99b3a58928b5de9231e1f7b695958b1d57
7
- data.tar.gz: d60744e27708a5af594454722bcbe13da873de4fd3c2f61624259529620710c830ae16449eb70a5f4b5c5fba7974531fb490bb3d2d17ee03fb309e38a3668f7b
6
+ metadata.gz: 008f097e630b8f223df81f751cc75060ae8722649fe393ff0f5f33682737f2886f91b704a8ca4e9d50f4c3bb896e9de82cd86ae4a59b91a3d904b9c9de59e79b
7
+ data.tar.gz: 9f564651bddec6e4d96db8e5220509c24fcbddf4f2f2037f87b831e36c1064b7a6c701a3cb6081b4b0c2d618f190b8f4409f3c7cde0225f221e1ba52bb590166
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- locomotivecms_steam (1.0.0.rc1)
4
+ locomotivecms_steam (1.0.0.rc2)
5
5
  RedCloth (~> 4.2.9)
6
6
  chronic (~> 0.10.2)
7
7
  coffee-script (~> 2.4.1)
@@ -26,7 +26,7 @@ en:
26
26
  paginate: "Syntax Error in 'paginate' - Valid syntax: paginate <collection> by <number>"
27
27
  session_assign: "Syntax Error in 'session_assign' - Valid syntax: session_assign [var] = [source]"
28
28
  messages:
29
- blank: "can't not be blank"
29
+ blank: "can't be blank"
30
30
  unique: "must be unique"
31
31
 
32
32
  pagination:
@@ -80,7 +80,7 @@ module Locomotive::Steam
80
80
  def set_fullpath_for(page, locale)
81
81
  page._fullpath ||= page.attributes.delete(:_fullpath)
82
82
 
83
- slug = fullpath = page.slug[locale].try(page.templatized? ? :to_s : :dasherize)
83
+ slug = fullpath = page.slug[locale].try(:to_s)
84
84
 
85
85
  return if slug.blank?
86
86
 
@@ -60,7 +60,11 @@ module Locomotive
60
60
  def each(slug, &block)
61
61
  position = 0
62
62
  _load(File.join(path, "#{slug}.yml")).each do |element|
63
- label, attributes = element.keys.first, element.values.first
63
+ label, attributes = if element.respond_to?(:keys)
64
+ [element.keys.first, element.values.first]
65
+ else
66
+ [element, {}]
67
+ end
64
68
  yield(label, attributes, position)
65
69
  position += 1
66
70
  end
@@ -85,6 +85,9 @@ module Locomotive::Steam
85
85
  _attributes.inject({}) do |hash, name|
86
86
  hash[name.to_s] = send(name)
87
87
  hash
88
+ end.tap do |hash|
89
+ # errors?
90
+ hash['errors'] = self.errors.to_hash.stringify_keys unless self.errors.empty?
88
91
  end
89
92
  end
90
93
 
@@ -6,11 +6,14 @@ module Locomotive::Steam
6
6
 
7
7
  def initialize(attributes = {})
8
8
  super({
9
- cache_enabled: false,
10
- prefix_default_locale: false,
11
- updated_at: nil,
12
- content_version: nil,
13
- template_version: nil
9
+ cache_enabled: false,
10
+ prefix_default_locale: false,
11
+ updated_at: nil,
12
+ content_version: nil,
13
+ template_version: nil,
14
+ domains: [],
15
+ redirect_to_first_domain: false,
16
+ url_redirections: []
14
17
  }.merge(attributes))
15
18
  end
16
19
 
@@ -19,7 +19,7 @@ module Locomotive
19
19
 
20
20
  secret Locomotive::Steam.configuration.image_resizer_secret
21
21
 
22
- url_format '/images/dynamic/:job/:basename.:ext'
22
+ url_format '/steam/dynamic/:job/:sha/:basename.:ext'
23
23
 
24
24
  fetch_file_whitelist /public/
25
25
 
@@ -4,7 +4,7 @@ module Locomotive::Steam
4
4
  module Helpers
5
5
 
6
6
  def html?
7
- ['text/html', 'application/x-www-form-urlencoded'].include?(self.request.media_type) &&
7
+ ['text/html', 'application/x-www-form-urlencoded', 'multipart/form-data'].include?(self.request.media_type) &&
8
8
  !self.request.xhr? &&
9
9
  !self.json?
10
10
  end
@@ -15,6 +15,8 @@ module Locomotive::Steam
15
15
 
16
16
  # log anyway
17
17
  log_site(site)
18
+
19
+ redirect_to_first_domain_if_enabled(site)
18
20
  end
19
21
 
20
22
  private
@@ -38,6 +40,25 @@ module Locomotive::Steam
38
40
  end
39
41
  end
40
42
 
43
+ def redirect_to_first_domain_if_enabled(site)
44
+ if redirect_to_first_domain?(site)
45
+ klass = request.scheme == 'https' ? URI::HTTPS : URI::HTTP
46
+ redirect_to klass.build(
47
+ host: site.domains.first,
48
+ port: [80, 443].include?(request.port) ? nil : request.port,
49
+ path: request.path,
50
+ query: request.query_string.present? ? request.query_string : nil).to_s
51
+ end
52
+ end
53
+
54
+ def redirect_to_first_domain?(site)
55
+ # the site parameter can be an instance of Locomotive::Steam::Services::Defer and
56
+ # so comparing just site may not be reliable.
57
+ !env['steam.is_default_host'] &&
58
+ site.try(:redirect_to_first_domain) &&
59
+ site.domains.first != request.host
60
+ end
61
+
41
62
  def log_site(site)
42
63
  if site.nil?
43
64
  msg = "Unable to find a site, url asked: #{request.url} ".colorize(color: :light_white, background: :red)
@@ -0,0 +1,31 @@
1
+ module Locomotive::Steam
2
+ module Middlewares
3
+
4
+ # If an old URL has been found among the site url_redirections hash,
5
+ # perform a 310 redirection to the new URL.
6
+ # It is highly useful when the site existed before but was ran by another system.
7
+ #
8
+ # See the specs (spec/unit/middlewares/url_redirection_spec.rb) for more details.
9
+ #
10
+ class UrlRedirection < ThreadSafe
11
+
12
+ include Helpers
13
+
14
+ def _call
15
+ if url = redirect_url
16
+ redirect_to url
17
+ end
18
+ end
19
+
20
+ protected
21
+
22
+ def redirect_url
23
+ return false if site.url_redirections.nil? || site.url_redirections.size == 0
24
+
25
+ site.url_redirections.to_h[request.env['locomotive.path'] || request.fullpath]
26
+ end
27
+
28
+ end
29
+ end
30
+
31
+ end
@@ -22,7 +22,7 @@ module Locomotive
22
22
 
23
23
  attr_accessor :messages
24
24
 
25
- def_delegators :@messages, :[], :clear, :empty?, :each, :size
25
+ def_delegators :@messages, :[], :clear, :empty?, :each, :size, :to_hash
26
26
 
27
27
  alias_method :blank?, :empty?
28
28
 
@@ -40,6 +40,8 @@ module Locomotive::Steam
40
40
  }
41
41
  end
42
42
 
43
+ use Dragonfly::Middleware, :steam
44
+
43
45
  use Rack::Lint
44
46
  use Rack::Session::Moneta, configuration.moneta
45
47
 
@@ -54,6 +56,7 @@ module Locomotive::Steam
54
56
  Middlewares::DefaultEnv,
55
57
  Middlewares::Site,
56
58
  Middlewares::Logging,
59
+ Middlewares::UrlRedirection,
57
60
  Middlewares::Robots,
58
61
  Middlewares::Timezone,
59
62
  Middlewares::EntrySubmission,
@@ -34,20 +34,7 @@ module Locomotive
34
34
  def to_json(entry)
35
35
  return nil if entry.nil?
36
36
 
37
- # default values
38
- hash = { _slug: entry._slug, content_type_slug: entry.content_type_slug }
39
-
40
- # dynamic attributes
41
- entry.content_type.fields.all.each do |field|
42
- next if %w(belongs_to has_many many_to_many).include?(field.type.to_s)
43
-
44
- hash[field.name] = entry.send(field.name)
45
- end
46
-
47
- # errors
48
- hash[:errors] = entry.errors.messages unless entry.errors.empty?
49
-
50
- hash.to_json
37
+ entry.to_json
51
38
  end
52
39
 
53
40
  private
@@ -29,7 +29,7 @@ module Locomotive
29
29
  resizer.fetch_url(url_or_path)
30
30
  else
31
31
  path = url_or_path.sub(/(\?.*)$/, '')
32
- resizer.fetch_file(File.join(asset_path || '', 'public', path))
32
+ resizer.fetch_file(File.join(asset_path || '', path))
33
33
  end
34
34
  end
35
35
 
@@ -3,6 +3,6 @@
3
3
  # 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0
4
4
  module Locomotive
5
5
  module Steam
6
- VERSION = '1.0.0.rc1'
6
+ VERSION = '1.0.0.rc2'
7
7
  end
8
8
  end
@@ -49,9 +49,9 @@ describe 'ContactForm' do
49
49
  subject { entry['errors'] }
50
50
 
51
51
  it 'lists all the errors' do
52
- expect(subject['name']).to eq ["can't not be blank"]
53
- expect(subject['email']).to eq ["can't not be blank"]
54
- expect(subject['email']).to eq ["can't not be blank"]
52
+ expect(subject['name']).to eq ["can't be blank"]
53
+ expect(subject['email']).to eq ["can't be blank"]
54
+ expect(subject['email']).to eq ["can't be blank"]
55
55
  end
56
56
 
57
57
  end
@@ -79,7 +79,7 @@ describe 'ContactForm' do
79
79
  end
80
80
 
81
81
  it 'displays errors' do
82
- expect(response.body.to_s).to include "can't not be blank"
82
+ expect(response.body.to_s).to include "can't be blank"
83
83
  end
84
84
 
85
85
  context 'redirects outside the site' do
@@ -130,7 +130,7 @@ describe 'ContactForm' do
130
130
  end
131
131
 
132
132
  it 'displays errors' do
133
- expect(response.body.to_s).to include "can't not be blank"
133
+ expect(response.body.to_s).to include "can't be blank"
134
134
  end
135
135
 
136
136
  end
@@ -26,7 +26,7 @@ describe Locomotive::Steam::ContentEntry do
26
26
 
27
27
  let(:attributes) { {} }
28
28
  it { is_expected.to eq false }
29
- it { subject; expect(content_entry.errors[:title]).to eq(["can't not be blank"]) }
29
+ it { subject; expect(content_entry.errors[:title]).to eq(["can't be blank"]) }
30
30
  it { subject; expect(content_entry.errors.empty?).to eq false }
31
31
 
32
32
  end
@@ -27,7 +27,7 @@ describe Locomotive::Steam::Liquid::Filters::Resize do
27
27
 
28
28
  let(:geometry) { '30x40#' }
29
29
 
30
- it { is_expected.to match /images\/dynamic\/.*\/240px-Metropolitan_railway_steam_locomotive_2781022036.png/ }
30
+ it { is_expected.to match /\/steam\/dynamic\/.*\/240px-Metropolitan_railway_steam_locomotive_2781022036.png/ }
31
31
 
32
32
  end
33
33
 
@@ -12,10 +12,12 @@ describe Locomotive::Steam::Middlewares::Site do
12
12
  let(:url) { 'http://models.example.com' }
13
13
  let(:app) { ->(env) { [200, env, 'app'] } }
14
14
  let(:middleware) { Locomotive::Steam::Middlewares::Site.new(app) }
15
+ let(:is_default_host) { nil }
15
16
 
16
17
  subject do
17
18
  env = env_for(url, 'steam.services' => services)
18
- env['steam.request'] = Rack::Request.new(env)
19
+ env['steam.request'] = Rack::Request.new(env)
20
+ env['steam.is_default_host'] = is_default_host
19
21
  code, env = middleware.call(env)
20
22
  [code, env['Location']]
21
23
  end
@@ -40,4 +42,38 @@ describe Locomotive::Steam::Middlewares::Site do
40
42
 
41
43
  end
42
44
 
45
+ describe 'redirection to the first domain' do
46
+
47
+ let(:redirect_to_first_domain) { false }
48
+ let(:url) { 'http://acme.com' }
49
+ let(:site) { instance_double('SiteWithDomains', name: 'Acme', domains: ['www.acme.com', 'acme.com'], redirect_to_first_domain: redirect_to_first_domain) }
50
+
51
+ before { expect(services).to receive(:current_site).and_return(site) }
52
+
53
+ it { is_expected.to eq [200, nil] }
54
+
55
+ describe 'option enabled' do
56
+
57
+ let(:redirect_to_first_domain) { true }
58
+
59
+ it { is_expected.to eq [301, 'http://www.acme.com/'] }
60
+
61
+ context 'first domain requested' do
62
+
63
+ let(:url) { 'http://www.acme.com' }
64
+ it { is_expected.to eq [200, nil] }
65
+
66
+ end
67
+
68
+ context 'requesting the default host' do
69
+
70
+ let(:is_default_host) { true }
71
+ it { is_expected.to eq [200, nil] }
72
+
73
+ end
74
+
75
+ end
76
+
77
+ end
78
+
43
79
  end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+
3
+ require_relative '../../../lib/locomotive/steam/middlewares/thread_safe'
4
+ require_relative '../../../lib/locomotive/steam/middlewares/helpers'
5
+ require_relative '../../../lib/locomotive/steam/middlewares/url_redirection'
6
+
7
+ describe Locomotive::Steam::Middlewares::UrlRedirection do
8
+
9
+ let(:redirections) { [] }
10
+ let(:site) { instance_double('Site', url_redirections: redirections) }
11
+ let(:url) { 'http://models.example.com' }
12
+ let(:locomotive_path) { nil }
13
+ let(:app) { ->(env) { [200, env, 'app'] } }
14
+ let(:middleware) { described_class.new(app) }
15
+
16
+ subject do
17
+ env = env_for(url, 'steam.site' => site)
18
+ env['steam.request'] = Rack::Request.new(env)
19
+ env['locomotive.path'] = locomotive_path
20
+ code, env = middleware.call(env)
21
+ [code, env['Location']]
22
+ end
23
+
24
+ describe 'no redirections' do
25
+
26
+ it { is_expected.to eq [200, nil] }
27
+
28
+ end
29
+
30
+ describe 'redirections' do
31
+
32
+ let(:redirections) { [['/foo.php', '/bar']] }
33
+
34
+ it { is_expected.to eq [200, nil] }
35
+
36
+ describe 'use first the locomotive.path env variable' do
37
+
38
+ let(:locomotive_path) { '/foo.php' }
39
+ it { is_expected.to eq [301, '/bar'] }
40
+
41
+ end
42
+
43
+ describe 'requesting the old url' do
44
+
45
+ let(:url) { 'http://models.example.com/foo.php' }
46
+ it { is_expected.to eq [301, '/bar'] }
47
+
48
+ describe 'url with a lot of dots' do
49
+
50
+ let(:redirections) { [['/content.HOME.HOME.WELCOME.DEU.GER.html', '/bar'], ['/hello', '/world']] }
51
+ let(:url) { 'http://models.example.com/content.HOME.HOME.WELCOME.DEU.GER.html' }
52
+
53
+ it { is_expected.to eq [301, '/bar'] }
54
+
55
+ end
56
+
57
+ describe 'url with a query string' do
58
+
59
+ let(:url) { 'http://models.example.com/foo.php?a=1' }
60
+
61
+ it { is_expected.to eq [200, nil] }
62
+
63
+ describe 'exact matching' do
64
+
65
+ let(:redirections) { { '/foo.php?a=1' => '/bar' } }
66
+ it { is_expected.to eq [301, '/bar'] }
67
+
68
+ end
69
+
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+ end
@@ -48,19 +48,20 @@ describe Locomotive::Steam::EntrySubmissionService do
48
48
 
49
49
  context 'existing content entry' do
50
50
 
51
- let(:errors) { {} }
52
- let(:fields) { [instance_double('TitleField', name: :title, type: :string)] }
53
- let(:type) { instance_double('Articles') }
54
- let(:entry) { instance_double('DecoratedEntry', _slug: 'hello-world', title: 'Hello world', content_type: type, content_type_slug: :articles, errors: errors) }
51
+ let(:field) { instance_double('TitleField', name: :title, type: :string) }
52
+ let(:fields) { [field] }
53
+ let(:type) { instance_double('Articles', slug: 'articles', label_field_name: :title, fields_by_name: { title: field }, persisted_field_names: [:title]) }
54
+ let(:entry) { Locomotive::Steam::ContentEntry.new(_slug: 'hello-world', title: 'Hello world', content_type: type) }
55
55
 
56
56
  before { allow(type).to receive(:fields).and_return(instance_double('FieldRepository', all: fields)) }
57
57
 
58
- it { is_expected.to eq '{"_slug":"hello-world","content_type_slug":"articles","title":"Hello world"}' }
58
+ it { is_expected.to match %r{{"_id":null,"_slug":"hello-world","_label":"Hello world","_visible":true,"_position":0,"content_type_slug":"articles","created_at":"[^\"]+","updated_at":"[^\"]+","title":"Hello world"}} }
59
59
 
60
60
  context 'with errors' do
61
61
 
62
- let(:errors) { instance_double('Errors', empty?: false, messages: { title: ["can't be blank"] }) }
63
- it { is_expected.to eq '{"_slug":"hello-world","content_type_slug":"articles","title":"Hello world","errors":{"title":["can\'t be blank"]}}' }
62
+ before { entry.errors.add(:title, "can't be blank") }
63
+
64
+ it { is_expected.to match %r{,\"errors\":\{\"title\":\[\"can't be blank\"\]\}} }
64
65
 
65
66
  end
66
67
 
@@ -31,33 +31,33 @@ describe Locomotive::Steam::ImageResizerService do
31
31
  it { is_expected.to eq nil }
32
32
  end
33
33
 
34
- it { is_expected.to match /images\/dynamic\/.*\/240px-Metropolitan_railway_steam_locomotive_2781022036.png/ }
34
+ it { is_expected.to match /\/steam\/dynamic\/.*\/240px-Metropolitan_railway_steam_locomotive_2781022036.png/ }
35
35
 
36
36
  describe 'a local asset' do
37
37
 
38
38
  let(:input) { '/sites/42/theme/images/banner.png' }
39
- it { is_expected.to match /images\/dynamic\/.*\/banner.png/ }
39
+ it { is_expected.to match /\/steam\/dynamic\/.*\/banner.png/ }
40
40
 
41
41
  end
42
42
 
43
43
  describe 'a hash' do
44
44
 
45
45
  let(:input) { { 'url' => '/sites/42/theme/images/banner.png' } }
46
- it { is_expected.to match /images\/dynamic\/.*\/banner.png/ }
46
+ it { is_expected.to match /\/steam\/dynamic\/.*\/banner.png/ }
47
47
 
48
48
  end
49
49
 
50
50
  describe 'an object responding to the url method (Carrierwave uploaded file)' do
51
51
 
52
52
  let(:input) { instance_double('UploadedFile', url: '/sites/42/theme/acme.png') }
53
- it { is_expected.to match /images\/dynamic\/.*\/acme.png/ }
53
+ it { is_expected.to match /\/steam\/dynamic\/.*\/acme.png/ }
54
54
 
55
55
  end
56
56
 
57
57
  describe 'an url with a timestamp' do
58
58
 
59
59
  let(:input) { '/sites/42/theme/images/banner.png?24e29997bcb00e97d8252cdd29d14e2d' }
60
- it { is_expected.to match /images\/dynamic\/.*\/banner.png\?sha=[a-z0-9]+/ }
60
+ it { is_expected.to match /\/steam\/dynamic\/.*\/[a-z0-9]+\/banner.png/ }
61
61
 
62
62
  end
63
63
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: locomotivecms_steam
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.rc1
4
+ version: 1.0.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Didier Lafforgue
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2015-10-14 00:00:00.000000000 Z
14
+ date: 2015-10-26 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -508,6 +508,7 @@ files:
508
508
  - lib/locomotive/steam/middlewares/templatized_page.rb
509
509
  - lib/locomotive/steam/middlewares/thread_safe.rb
510
510
  - lib/locomotive/steam/middlewares/timezone.rb
511
+ - lib/locomotive/steam/middlewares/url_redirection.rb
511
512
  - lib/locomotive/steam/models.rb
512
513
  - lib/locomotive/steam/models/associations/belongs_to.rb
513
514
  - lib/locomotive/steam/models/associations/embedded.rb
@@ -745,6 +746,7 @@ files:
745
746
  - spec/unit/middlewares/renderer_spec.rb
746
747
  - spec/unit/middlewares/site_spec.rb
747
748
  - spec/unit/middlewares/stack_proxy_spec.rb
749
+ - spec/unit/middlewares/url_redirection_spec.rb
748
750
  - spec/unit/models/concerns/to_json_spec.rb
749
751
  - spec/unit/models/i18n_field_spec.rb
750
752
  - spec/unit/models/mapper_spec.rb
@@ -983,6 +985,7 @@ test_files:
983
985
  - spec/unit/middlewares/renderer_spec.rb
984
986
  - spec/unit/middlewares/site_spec.rb
985
987
  - spec/unit/middlewares/stack_proxy_spec.rb
988
+ - spec/unit/middlewares/url_redirection_spec.rb
986
989
  - spec/unit/models/concerns/to_json_spec.rb
987
990
  - spec/unit/models/i18n_field_spec.rb
988
991
  - spec/unit/models/mapper_spec.rb