locomotivecms_steam 1.3.0.rc2 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +5 -5
  3. data/Gemfile.lock +84 -82
  4. data/config/locales/de.yml +7 -5
  5. data/config/locales/el.yml +154 -0
  6. data/config/locales/en.yml +6 -1
  7. data/config/locales/es.yml +7 -1
  8. data/config/locales/et.yml +4 -0
  9. data/config/locales/fr.yml +6 -1
  10. data/config/locales/it.yml +7 -1
  11. data/config/locales/nb.yml +5 -1
  12. data/config/locales/nl.yml +8 -0
  13. data/config/locales/pl.yml +8 -0
  14. data/config/locales/pt-BR.yml +6 -0
  15. data/config/locales/ru.yml +9 -1
  16. data/lib/locomotive/steam/adapters/filesystem/sanitizers/content_entry.rb +1 -1
  17. data/lib/locomotive/steam/decorators/template_decorator.rb +1 -1
  18. data/lib/locomotive/steam/entities/content_entry.rb +4 -0
  19. data/lib/locomotive/steam/entities/content_type.rb +4 -0
  20. data/lib/locomotive/steam/entities/site.rb +2 -1
  21. data/lib/locomotive/steam/liquid/drops/content_entry.rb +1 -1
  22. data/lib/locomotive/steam/liquid/drops/site.rb +1 -1
  23. data/lib/locomotive/steam/middlewares/auth.rb +29 -3
  24. data/lib/locomotive/steam/models/concerns/validation.rb +7 -8
  25. data/lib/locomotive/steam/models/i18n_field.rb +4 -2
  26. data/lib/locomotive/steam/repositories/content_entry_repository.rb +9 -1
  27. data/lib/locomotive/steam/services.rb +1 -1
  28. data/lib/locomotive/steam/services/asset_host_service.rb +21 -17
  29. data/lib/locomotive/steam/services/auth_service.rb +93 -9
  30. data/lib/locomotive/steam/services/content_entry_service.rb +4 -1
  31. data/lib/locomotive/steam/version.rb +1 -1
  32. data/locomotivecms_steam.gemspec +10 -10
  33. data/spec/fixtures/default/app/content_types/accounts.yml +2 -1
  34. data/spec/fixtures/default/app/content_types/songs.yml +2 -2
  35. data/spec/fixtures/default/app/views/pages/account/sign_up.liquid +52 -0
  36. data/spec/fixtures/default/config/translations.yml +4 -0
  37. data/spec/fixtures/default/data/accounts.yml +1 -1
  38. data/spec/fixtures/default/data/songs.yml +1 -0
  39. data/spec/fixtures/mongodb/locomotive_accounts.bson +0 -0
  40. data/spec/fixtures/mongodb/locomotive_accounts.metadata.json +1 -1
  41. data/spec/fixtures/mongodb/locomotive_activities.bson +0 -0
  42. data/spec/fixtures/mongodb/locomotive_activities.metadata.json +1 -1
  43. data/spec/fixtures/mongodb/locomotive_content_assets.bson +0 -0
  44. data/spec/fixtures/mongodb/locomotive_content_assets.metadata.json +1 -1
  45. data/spec/fixtures/mongodb/locomotive_content_entries.bson +0 -0
  46. data/spec/fixtures/mongodb/locomotive_content_entries.metadata.json +1 -1
  47. data/spec/fixtures/mongodb/locomotive_content_types.bson +0 -0
  48. data/spec/fixtures/mongodb/locomotive_content_types.metadata.json +1 -1
  49. data/spec/fixtures/mongodb/locomotive_pages.bson +0 -0
  50. data/spec/fixtures/mongodb/locomotive_pages.metadata.json +1 -1
  51. data/spec/fixtures/mongodb/locomotive_sites.bson +0 -0
  52. data/spec/fixtures/mongodb/locomotive_sites.metadata.json +1 -1
  53. data/spec/fixtures/mongodb/locomotive_snippets.bson +0 -0
  54. data/spec/fixtures/mongodb/locomotive_snippets.metadata.json +1 -1
  55. data/spec/fixtures/mongodb/locomotive_theme_assets.bson +0 -0
  56. data/spec/fixtures/mongodb/locomotive_theme_assets.metadata.json +1 -1
  57. data/spec/fixtures/mongodb/locomotive_translations.bson +0 -0
  58. data/spec/fixtures/mongodb/locomotive_translations.metadata.json +1 -1
  59. data/spec/integration/repositories/content_entry_repository_spec.rb +1 -1
  60. data/spec/integration/repositories/page_repository_spec.rb +2 -2
  61. data/spec/integration/repositories/theme_asset_repository_spec.rb +1 -1
  62. data/spec/integration/repositories/translation_repository_spec.rb +1 -1
  63. data/spec/integration/server/assets_spec.rb +1 -1
  64. data/spec/integration/server/auth_spec.rb +70 -0
  65. data/spec/integration/services/content_entry_service_spec.rb +1 -1
  66. data/spec/support/helpers.rb +1 -1
  67. data/spec/unit/adapters/filesystem/yaml_loaders/content_entry_spec.rb +1 -1
  68. data/spec/unit/adapters/filesystem/yaml_loaders/page_spec.rb +7 -7
  69. data/spec/unit/adapters/filesystem/yaml_loaders/translation_spec.rb +1 -1
  70. data/spec/unit/entities/content_entry_spec.rb +9 -0
  71. data/spec/unit/entities/content_type_spec.rb +7 -0
  72. data/spec/unit/entities/site_spec.rb +15 -0
  73. data/spec/unit/liquid/drops/content_entry_spec.rb +41 -2
  74. data/spec/unit/liquid/drops/site_spec.rb +2 -1
  75. data/spec/unit/liquid/filters/html_spec.rb +58 -1
  76. data/spec/unit/models/i18n_field_spec.rb +8 -0
  77. data/spec/unit/repositories/content_entry_repository_spec.rb +13 -0
  78. data/spec/unit/services/asset_host_service_spec.rb +27 -3
  79. data/spec/unit/services/auth_service_spec.rb +134 -8
  80. data/spec/unit/services/content_entry_service_spec.rb +1 -1
  81. metadata +27 -24
@@ -45,7 +45,7 @@ describe Locomotive::Steam::ContentEntryService do
45
45
 
46
46
  let(:site_id) { mongodb_site_id }
47
47
  let(:adapter) { Locomotive::Steam::MongoDBAdapter.new(database: 'steam_test', hosts: ['127.0.0.1:27017']) }
48
- let(:entry_id) { BSON::ObjectId.from_string('5829ffa087f6435971756881') }
48
+ let(:entry_id) { BSON::ObjectId.from_string('5943b4dd87f6430cf23b814d') }
49
49
 
50
50
  describe '#create' do
51
51
  subject { service.create('messages', { name: 'John', email: 'john@doe.net', message: 'Hello world!' }) }
@@ -4,7 +4,7 @@ module Spec
4
4
  module Helpers
5
5
 
6
6
  def mongodb_site_id
7
- BSON::ObjectId.from_string('5829ff6487f64359474164a1')
7
+ BSON::ObjectId.from_string('5943b49287f6430cadd748a3')
8
8
  end
9
9
 
10
10
  def reset!
@@ -84,7 +84,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
84
84
  end
85
85
 
86
86
  it 'stores the size of the file in multiple locales' do
87
- expect(subject[1][:cover_size]).to eq('en' => 14768, 'fr' => 165883)
87
+ expect(subject[1][:cover_size]).to eq('en' => 14768, 'fr' => 165883, 'nb' => 165883)
88
88
  end
89
89
 
90
90
 
@@ -15,14 +15,14 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::Page do
15
15
  subject { loader.load(scope).sort { |a, b| a[:_fullpath] <=> b[:_fullpath] } }
16
16
 
17
17
  it 'tests various stuff' do
18
- expect(subject.size).to eq 33
18
+ expect(subject.size).to eq 34
19
19
  expect(subject.first[:title]).to eq(en: 'Page not found', fr: 'Page non trouvée')
20
- expect(subject[22][:is_layout]).to eq true
21
- expect(subject[22][:listed]).to eq false
22
- expect(subject[22][:published]).to eq false
23
- expect(subject[23][:slug]).to eq(en: 'music', fr: 'notre-musique')
24
- expect(subject[24][:_fullpath]).to eq 'songs'
25
- expect(subject[24][:template_path]).to eq(en: false)
20
+ expect(subject[23][:is_layout]).to eq true
21
+ expect(subject[23][:listed]).to eq false
22
+ expect(subject[23][:published]).to eq false
23
+ expect(subject[24][:slug]).to eq(en: 'music', fr: 'notre-musique')
24
+ expect(subject[25][:_fullpath]).to eq 'songs'
25
+ expect(subject[25][:template_path]).to eq(en: false)
26
26
  end
27
27
 
28
28
  end
@@ -15,7 +15,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::Translation do
15
15
  subject { loader.load(scope) }
16
16
 
17
17
  it 'tests various stuff' do
18
- expect(subject.size).to eq 7
18
+ expect(subject.size).to eq 8
19
19
  expect(subject.first[:key]).to eq('powered_by')
20
20
  expect(subject.first[:values]).to eq({ 'en' => 'Powered by', 'fr' => 'Propulsé par' })
21
21
  end
@@ -116,6 +116,15 @@ describe Locomotive::Steam::ContentEntry do
116
116
 
117
117
  it { expect(subject['picture']['url']).to eq '/assets/foo.png' }
118
118
 
119
+ context 'includes a non dynamic attribute' do
120
+
121
+ it "doesn't add it to the output" do
122
+ content_entry['author'] = 'John Doe'
123
+ expect(subject['author']).to eq nil
124
+ end
125
+
126
+ end
127
+
119
128
  end
120
129
 
121
130
  describe 'dynamic attributes' do
@@ -30,6 +30,13 @@ describe Locomotive::Steam::ContentType do
30
30
 
31
31
  end
32
32
 
33
+ describe '#field_label_of' do
34
+
35
+ subject { content_type.field_label_of(:title) }
36
+ it { is_expected.to eq 'title' }
37
+
38
+ end
39
+
33
40
  describe '#localized_names' do
34
41
 
35
42
  subject { content_type.localized_names }
@@ -98,4 +98,19 @@ describe Locomotive::Steam::Site do
98
98
 
99
99
  end
100
100
 
101
+ describe '#asset_host' do
102
+
103
+ subject { site.asset_host }
104
+
105
+ it { is_expected.to eq nil }
106
+
107
+ context 'not blank' do
108
+
109
+ let(:attributes) { { asset_host: 'http://asset.dev' } }
110
+ it { is_expected.to eq 'http://asset.dev' }
111
+
112
+ end
113
+
114
+ end
115
+
101
116
  end
@@ -106,6 +106,45 @@ describe Locomotive::Steam::Liquid::Drops::ContentEntry do
106
106
 
107
107
  end
108
108
 
109
+ describe '#to_hash' do
110
+
111
+ describe 'belong_to content type' do
112
+
113
+ let(:entry) { instance_double('Article', _id: 42, localized_attributes: {}, content_type: type, title: 'Hello world', _label: 'Hello world', _slug: 'hello-world', _translated: false, seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description', created_at: 0, updated_at: 1, author: author) }
114
+ let(:type) { instance_double('Type', fields_by_name: { title: instance_double('StringField', type: :string ), author: instance_double('Author', type: :belongs_to), picture: instance_double('FileField', type: :file), category: instance_double('SelectField', type: :select) }) }
115
+ let(:author) { instance_double('Author', _slug: 'john-doe', localized_attributes: {}) }
116
+ let(:picture_field) { Locomotive::Steam::ContentEntry::FileField.new('foo.png', 'http://assets.dev', 0, 42) }
117
+
118
+ before do
119
+ allow(entry).to receive(:category).and_return('Test')
120
+ end
121
+
122
+ subject { drop.to_hash.stringify_keys }
123
+
124
+ context 'corresponding hash value for id is not nil' do
125
+
126
+ before do
127
+ allow(entry).to receive(:to_hash).and_return({ '_id' => 1, 'title' => 'Hello world', 'picture' => picture_field, 'category_id' => 42, 'author_id' => 64 })
128
+ end
129
+
130
+ it { is_expected.to eq('id' => 1, '_id' => 1, 'title' => 'Hello world', 'picture' => 'http://assets.dev/foo.png?42', 'picture_url' => 'http://assets.dev/foo.png?42', 'category_id' => 42, 'category' => 'Test', 'author_id' => 64, 'author' => 'john-doe') }
131
+
132
+ end
133
+
134
+ context 'corresponding hash value for id is nil' do
135
+
136
+ before do
137
+ allow(entry).to receive(:to_hash).and_return({ '_id' => 1, 'title' => 'Hello world', 'picture' => picture_field, 'category_id' => 42 })
138
+ end
139
+
140
+ it { is_expected.to eq('id' => 1, '_id' => 1, 'title' => 'Hello world', 'picture' => 'http://assets.dev/foo.png?42', 'picture_url' => 'http://assets.dev/foo.png?42', 'category_id' => 42, 'category' => 'Test') }
141
+
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
109
148
  describe '#as_json' do
110
149
 
111
150
  let(:entry) { instance_double('Article', _id: 42, localized_attributes: {}, content_type: type, title: 'Hello world', _label: 'Hello world', _slug: 'hello-world', _translated: false, seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description', created_at: 0, updated_at: 1, author: author, authors: authors) }
@@ -115,13 +154,13 @@ describe Locomotive::Steam::Liquid::Drops::ContentEntry do
115
154
  let(:picture_field) { Locomotive::Steam::ContentEntry::FileField.new('foo.png', 'http://assets.dev', 0, 42) }
116
155
 
117
156
  before do
118
- allow(entry).to receive(:to_hash).and_return({ '_id' => 1, 'title' => 'Hello world', 'picture' => picture_field, 'category_id' => 42 })
157
+ allow(entry).to receive(:to_hash).and_return({ '_id' => 1, 'title' => 'Hello world', 'picture' => picture_field, 'category_id' => 42, 'author_id' => 64 })
119
158
  allow(entry).to receive(:category).and_return('Test')
120
159
  end
121
160
 
122
161
  subject { drop.as_json }
123
162
 
124
- it { is_expected.to eq('id' => 1, '_id' => 1, 'title' => 'Hello world', 'picture' => 'http://assets.dev/foo.png?42', 'picture_url' => 'http://assets.dev/foo.png?42', 'category_id' => 42, 'category' => 'Test', 'author' => 'john-doe', 'authors' => ['john-doe']) }
163
+ it { is_expected.to eq('id' => 1, '_id' => 1, 'title' => 'Hello world', 'picture' => 'http://assets.dev/foo.png?42', 'picture_url' => 'http://assets.dev/foo.png?42', 'category_id' => 42, 'category' => 'Test', 'author_id' => 64, 'author' => 'john-doe', 'authors' => ['john-doe']) }
125
164
 
126
165
  end
127
166
 
@@ -4,7 +4,7 @@ describe Locomotive::Steam::Liquid::Drops::Site do
4
4
 
5
5
  let(:services) { Locomotive::Steam::Services.build_instance }
6
6
  let(:context) { ::Liquid::Context.new({}, {}, { services: services }) }
7
- let(:site) { instance_double('Site', name: 'Locomotive', domains: ['acme.org'], seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description', localized_attributes: {}) }
7
+ let(:site) { instance_double('Site', name: 'Locomotive', domains: ['acme.org'], seo_title: 'seo title', meta_keywords: 'keywords', meta_description: 'description', localized_attributes: {}, asset_host: 'http://asset.dev') }
8
8
  let(:drop) { described_class.new(site).tap { |d| d.context = context } }
9
9
 
10
10
  subject { drop }
@@ -15,6 +15,7 @@ describe Locomotive::Steam::Liquid::Drops::Site do
15
15
  expect(subject.meta_keywords).to eq 'keywords'
16
16
  expect(subject.meta_description).to eq 'description'
17
17
  expect(subject.domains).to eq ['acme.org']
18
+ expect(subject.asset_host).to eq 'http://asset.dev'
18
19
  end
19
20
 
20
21
  describe '#index' do
@@ -5,7 +5,8 @@ describe Locomotive::Steam::Liquid::Filters::Html do
5
5
  include Locomotive::Steam::Liquid::Filters::Base
6
6
  include Locomotive::Steam::Liquid::Filters::Html
7
7
 
8
- let(:site) { instance_double('Site', _id: 42)}
8
+ let(:asset_host) { nil }
9
+ let(:site) { instance_double('Site', _id: 42, asset_host: asset_host) }
9
10
  let(:services) { Locomotive::Steam::Services.build_instance }
10
11
  let(:context) { instance_double('Context', registers: { services: services }) }
11
12
 
@@ -205,6 +206,10 @@ describe Locomotive::Steam::Liquid::Filters::Html do
205
206
  expect(javascript_tag('https://cdn.example.com/trash/main.js', ['defer:defer'])).to eq(result)
206
207
  end
207
208
 
209
+ it 'returns an image url for a given theme file without parameters' do
210
+ expect(theme_image_url('foo.jpg')).to eq "/sites/42/theme/images/foo.jpg"
211
+ end
212
+
208
213
  it 'returns an image tag for a given theme file without parameters' do
209
214
  expect(theme_image_tag('foo.jpg')).to eq "<img src=\"/sites/42/theme/images/foo.jpg\" >"
210
215
  end
@@ -245,6 +250,58 @@ describe Locomotive::Steam::Liquid::Filters::Html do
245
250
  }.strip)
246
251
  end
247
252
 
253
+ context 'asset_host' do
254
+ let(:asset_host) { 'http://asset.dev' }
255
+
256
+ it 'returns an url for a stylesheet file with respect to URL-parameters' do
257
+ result = "http://asset.dev/sites/42/theme/stylesheets/main.css?v=42"
258
+ expect(stylesheet_url('main.css?v=42')).to eq(result)
259
+ expect(stylesheet_url('main?v=42')).to eq(result)
260
+ end
261
+
262
+ it 'returns a link tag for a stylesheet file' do
263
+ result = "<link href=\"http://asset.dev/sites/42/theme/stylesheets/main.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
264
+ expect(stylesheet_tag('main.css')).to eq(result)
265
+ expect(stylesheet_tag('main')).to eq(result)
266
+ expect(stylesheet_tag(nil)).to eq('')
267
+ end
268
+
269
+ it 'returns a link tag for a stylesheet file with folder' do
270
+ result = "<link href=\"http://asset.dev/sites/42/theme/stylesheets/trash/main.css\" media=\"screen\" rel=\"stylesheet\" type=\"text/css\" />"
271
+ expect(stylesheet_tag('trash/main.css')).to eq(result)
272
+ end
273
+
274
+ it 'returns an url for a javascript file with respect to URL-parameters' do
275
+ expect(javascript_url('main.js?v=42')).to eq "http://asset.dev/sites/42/theme/javascripts/main.js?v=42"
276
+ end
277
+
278
+ it 'returns a script tag for a javascript file' do
279
+ result = %{<script src="http://asset.dev/sites/42/theme/javascripts/main.js" type="text/javascript" ></script>}
280
+ expect(javascript_tag('main.js')).to eq(result)
281
+ expect(javascript_tag('main')).to eq(result)
282
+ expect(javascript_tag(nil)).to eq('')
283
+ end
284
+
285
+ it 'returns a script tag for a javascript file with folder' do
286
+ result = %{<script src="http://asset.dev/sites/42/theme/javascripts/trash/main.js" type="text/javascript" ></script>}
287
+ expect(javascript_tag('trash/main.js')).to eq(result)
288
+ expect(javascript_tag('trash/main')).to eq(result)
289
+ end
290
+
291
+ it 'returns an image url for a given theme file without parameters' do
292
+ expect(theme_image_url('foo.jpg')).to eq "http://asset.dev/sites/42/theme/images/foo.jpg"
293
+ end
294
+
295
+ it 'returns an image tag for a given theme file without parameters' do
296
+ expect(theme_image_tag('foo.jpg')).to eq "<img src=\"http://asset.dev/sites/42/theme/images/foo.jpg\" >"
297
+ end
298
+
299
+ it 'returns an image tag for a given theme file with size' do
300
+ expect(theme_image_tag('foo.jpg', 'width:100', 'height:100')).to eq("<img src=\"http://asset.dev/sites/42/theme/images/foo.jpg\" height=\"100\" width=\"100\" >")
301
+ end
302
+
303
+ end
304
+
248
305
  class EngineThemeAsset < Locomotive::Steam::ThemeAssetRepository
249
306
  def url_for(path)
250
307
  ['', 'sites', site._id.to_s, 'theme', path].join('/')
@@ -20,6 +20,14 @@ describe Locomotive::Steam::Models::I18nField do
20
20
 
21
21
  end
22
22
 
23
+ context 'with a single value' do
24
+
25
+ let(:translations) { 'Hello world' }
26
+
27
+ it { is_expected.to eq false }
28
+
29
+ end
30
+
23
31
  end
24
32
 
25
33
  describe '#dup' do
@@ -39,6 +39,19 @@ describe Locomotive::Steam::ContentEntryRepository do
39
39
 
40
40
  end
41
41
 
42
+ describe 'including also the not visible entries' do
43
+
44
+ let(:entries) { [
45
+ { content_type_id: 1, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' },
46
+ { content_type_id: 1, _position: 1, _label: 'Update #2 [HIDDEN]', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General', _visible: false }
47
+ ] }
48
+
49
+ let(:conditions) { { _visible: nil } }
50
+
51
+ it { expect(subject.size).to eq 2 }
52
+
53
+ end
54
+
42
55
  end
43
56
 
44
57
  describe '#build' do
@@ -91,9 +91,9 @@ describe Locomotive::Steam::AssetHostService do
91
91
 
92
92
  describe 'the host is a block' do
93
93
 
94
- let(:request) { instance_double('Request', ssl: true) }
95
- let(:site) { instance_double('Site', cdn: true) }
96
- let(:host) { ->(request, site) { site.cdn ? "http#{request.ssl ? 's' : ''}://assets.locomotivecms.com" : nil } }
94
+ let(:request) { instance_double('Request', ssl: true) }
95
+ let(:site) { instance_double('Site', cdn: true) }
96
+ let(:host) { ->(request, site) { site.cdn ? "http#{request.ssl ? 's' : ''}://assets.locomotivecms.com" : nil } }
97
97
 
98
98
  it { is_expected.to eq 'https://assets.locomotivecms.com/sites/42/assets/1/banner.png' }
99
99
 
@@ -113,4 +113,28 @@ describe Locomotive::Steam::AssetHostService do
113
113
 
114
114
  end
115
115
 
116
+ describe 'the site has an asset host' do
117
+
118
+ let(:site) { instance_double('Site', asset_host: 'asset.dev') }
119
+ let(:host) { 'http://assets.locomotivecms.com' }
120
+
121
+ it { is_expected.to eq 'https://asset.dev/sites/42/assets/1/banner.png' }
122
+
123
+ context 'with the protocol' do
124
+
125
+ let(:site) { instance_double('Site', asset_host: 'http://asset.dev') }
126
+ it { is_expected.to eq 'http://asset.dev/sites/42/assets/1/banner.png' }
127
+
128
+ end
129
+
130
+ context 'with an empty string' do
131
+
132
+ let(:site) { instance_double('Site', asset_host: '') }
133
+ it { is_expected.to eq 'http://assets.locomotivecms.com/sites/42/assets/1/banner.png' }
134
+
135
+ end
136
+
137
+
138
+ end
139
+
116
140
  end
@@ -2,9 +2,11 @@ require 'spec_helper'
2
2
 
3
3
  describe Locomotive::Steam::AuthService do
4
4
 
5
- let(:entries) { instance_double('ContentService') }
6
- let(:emails) { instance_double('EmailService') }
7
- let(:service) { described_class.new(entries, emails) }
5
+ let(:site) { instance_double('CurrentSite') }
6
+ let(:entries) { instance_double('ContentService', locale: 'en') }
7
+ let(:emails) { instance_double('EmailService') }
8
+ let(:service) { described_class.new(site, entries, emails) }
9
+ let(:liquid_context) { {} }
8
10
 
9
11
  let(:default_auth_options) { {
10
12
  type: 'accounts',
@@ -22,9 +24,130 @@ describe Locomotive::Steam::AuthService do
22
24
 
23
25
  let(:auth_options) { instance_double('AuthOptions', default_auth_options) }
24
26
 
27
+ describe '#sign_up' do
28
+
29
+ let(:errors) { [] }
30
+ let(:entry_attributes) { { fullname: 'Chris Cornell', band: 'Soundgarden', email: 'chris@soundgarden.band', password: 'easyone', password_confirmation: 'easyone' } }
31
+ let(:entry) { instance_double('Account', errors: errors) }
32
+ let(:email_disabled) { false }
33
+ let(:default_auth_options) { {
34
+ type: 'accounts',
35
+ id_field: 'email',
36
+ id: 'chris@soundgarden.band',
37
+ password_field: 'password',
38
+ from: 'no-reply@acme.org',
39
+ subject: 'Your account has been created',
40
+ email_handle: 'account-created',
41
+ smtp: {},
42
+ disable_email: email_disabled,
43
+ entry: entry_attributes
44
+ } }
45
+
46
+ subject { service.sign_up(auth_options, liquid_context) }
47
+
48
+ context 'the entry has errors' do
49
+
50
+ let(:errors) { [:invalid_password] }
51
+
52
+ it 'returns invalid_entry and the entry' do
53
+ expect(entries).to receive(:create).with('accounts', {
54
+ fullname: 'Chris Cornell',
55
+ band: 'Soundgarden',
56
+ email: 'chris@soundgarden.band',
57
+ password: 'easyone',
58
+ password_confirmation: 'easyone'
59
+ }).and_return(entry)
60
+ is_expected.to eq [:invalid_entry, entry]
61
+ end
62
+
63
+ end
64
+
65
+ it "returns both :created and the entry if it was able to create it (+ send email)" do
66
+ expect(entries).to receive(:create).with('accounts', {
67
+ fullname: 'Chris Cornell',
68
+ band: 'Soundgarden',
69
+ email: 'chris@soundgarden.band',
70
+ password: 'easyone',
71
+ password_confirmation: 'easyone'
72
+ }).and_return(entry)
73
+ expect(emails).to receive(:send_email).with({
74
+ from: 'no-reply@acme.org',
75
+ to: 'chris@soundgarden.band',
76
+ subject: 'Your account has been created',
77
+ page_handle: 'account-created',
78
+ smtp: {} }, liquid_context)
79
+ is_expected.to eq [:entry_created, entry]
80
+ end
81
+
82
+ context 'email is disabled' do
83
+
84
+ let(:email_disabled) { true }
85
+
86
+ it "doesn't send a notification email" do
87
+ allow(entries).to receive(:create).and_return(entry)
88
+ expect(emails).to_not receive(:send_email)
89
+ is_expected.to eq [:entry_created, entry]
90
+ end
91
+
92
+ end
93
+
94
+ describe Locomotive::Steam::AuthService::ContentEntryAuth do
95
+
96
+ let(:repository) { instance_double('FieldRepository', all: nil, required: []) }
97
+ let(:type) { instance_double('ContentType', slug: 'accounts', label_field_name: :title, fields: repository, fields_by_name: {}) }
98
+ let(:attributes) { { password: 'easyone', password_confirmation: 'easyone' } }
99
+ let(:content_entry) { Locomotive::Steam::ContentEntry.new(attributes).tap { |e| e.content_type = type } }
100
+
101
+ before { content_entry.extend(described_class) }
102
+
103
+ describe '#valid?' do
104
+
105
+ before { content_entry[:_password_field] = 'password' }
106
+
107
+ subject { content_entry.valid? }
108
+
109
+ it { is_expected.to eq true }
110
+
111
+ it 'encrypts the password since there is no error' do
112
+ expect(BCrypt::Password).to receive(:create).with('easyone').and_return('42a')
113
+ subject
114
+ expect(content_entry[:password_hash]).to eq '42a'
115
+ expect(content_entry.attributes[:password]).to eq nil
116
+ expect(content_entry.attributes[:password_confirmation]).to eq nil
117
+ end
118
+
119
+ context 'the password is less than 6 characters' do
120
+
121
+ let(:attributes) { { password: 'easy', password_confirmation: 'easy' } }
122
+
123
+ it 'returns false' do
124
+ is_expected.to eq false
125
+ expect(content_entry.errors[:password]).to eq(['is too short (minimum is 6 characters)'])
126
+ end
127
+
128
+ end
129
+
130
+ context "the password doesn't match the confirmation" do
131
+
132
+ let(:type) { instance_double('ContentType', slug: 'accounts', label_field_name: :title, fields: repository, fields_by_name: {}, field_label_of: 'password') }
133
+ let(:attributes) { { password: 'easyone', password_confirmation: 'oneeasy' } }
134
+
135
+ it 'returns false' do
136
+ is_expected.to eq false
137
+ expect(content_entry.errors[:password_confirmation]).to eq(["doesn't match password"])
138
+ end
139
+
140
+ end
141
+
142
+ end
143
+
144
+ end
145
+
146
+ end
147
+
25
148
  describe '#sign_in' do
26
149
 
27
- subject { service.sign_in(auth_options) }
150
+ subject { service.sign_in(auth_options, nil) }
28
151
 
29
152
  it 'returns :wrong_credentials if no entry matches the email' do
30
153
  expect(entries).to receive(:all).with('accounts', { 'email' => 'john@doe.net' }).and_return([])
@@ -37,6 +160,13 @@ describe Locomotive::Steam::AuthService do
37
160
  is_expected.to eq :wrong_credentials
38
161
  end
39
162
 
163
+
164
+ it "returns :wrong_credentials if the password is empty" do
165
+ entry = instance_double('Account', password: nil)
166
+ expect(entries).to receive(:all).with('accounts', { 'email' => 'john@doe.net' }).and_return([entry])
167
+ is_expected.to eq :wrong_credentials
168
+ end
169
+
40
170
  it "returns both :signed_in and the entry if the password matches the entry's password" do
41
171
  entry = build_account('easyone')
42
172
  expect(entries).to receive(:all).with('accounts', { 'email' => 'john@doe.net' }).and_return([entry])
@@ -47,8 +177,6 @@ describe Locomotive::Steam::AuthService do
47
177
 
48
178
  describe '#forgot_password' do
49
179
 
50
- let(:liquid_context) { {} }
51
-
52
180
  subject { service.forgot_password(auth_options, liquid_context) }
53
181
 
54
182
  it 'returns :wrong_email if no entry matches the email' do
@@ -57,7 +185,6 @@ describe Locomotive::Steam::AuthService do
57
185
  end
58
186
 
59
187
  it 'sends the instructions by email if an entry matches the email' do
60
- allow(SecureRandom).to receive(:hex).and_return('42a')
61
188
  entry = build_account('easyone', '42a')
62
189
  expect(entries).to receive(:all).with('accounts', { 'email' => 'john@doe.net' }).and_return([entry])
63
190
  expect(entries).to receive(:update_decorated_entry)
@@ -77,7 +204,6 @@ describe Locomotive::Steam::AuthService do
77
204
  let(:auth_options) { instance_double('AuthOptions', _auth_options) }
78
205
 
79
206
  it 'also sends the instructions by email with a default email template' do
80
- allow(SecureRandom).to receive(:hex).and_return('42a')
81
207
  entry = build_account('easyone', '42a')
82
208
  expect(entries).to receive(:all).with('accounts', { 'email' => 'john@doe.net' }).and_return([entry])
83
209
  expect(entries).to receive(:update_decorated_entry)