locomotivecms_steam 1.2.1 → 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (117) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -1
  3. data/Gemfile +3 -2
  4. data/Gemfile.lock +57 -50
  5. data/LICENSE +1 -1
  6. data/README.md +1 -1
  7. data/config/locales/nl.yml +2 -2
  8. data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_entry.rb +8 -0
  9. data/lib/locomotive/steam/adapters/memory/condition.rb +1 -1
  10. data/lib/locomotive/steam/configuration.rb +1 -1
  11. data/lib/locomotive/steam/decorators/template_decorator.rb +1 -1
  12. data/lib/locomotive/steam/entities/content_entry.rb +17 -0
  13. data/lib/locomotive/steam/entities/content_type.rb +1 -0
  14. data/lib/locomotive/steam/entities/content_type_field.rb +1 -0
  15. data/lib/locomotive/steam/entities/editable_element.rb +4 -0
  16. data/lib/locomotive/steam/errors.rb +35 -5
  17. data/lib/locomotive/steam/initializers/sprockets.rb +6 -80
  18. data/lib/locomotive/steam/liquid/drops/page.rb +9 -2
  19. data/lib/locomotive/steam/liquid/filters/date.rb +109 -0
  20. data/lib/locomotive/steam/liquid/tags/action.rb +6 -1
  21. data/lib/locomotive/steam/liquid/tags/authorize.rb +65 -0
  22. data/lib/locomotive/steam/liquid/tags/snippet.rb +10 -2
  23. data/lib/locomotive/steam/liquid/template.rb +3 -1
  24. data/lib/locomotive/steam/middlewares/auth.rb +187 -0
  25. data/lib/locomotive/steam/middlewares/redirection.rb +24 -0
  26. data/lib/locomotive/steam/middlewares/renderer.rb +20 -3
  27. data/lib/locomotive/steam/middlewares/sitemap.rb +3 -1
  28. data/lib/locomotive/steam/middlewares/templatized_page.rb +1 -6
  29. data/lib/locomotive/steam/middlewares/thread_safe.rb +19 -0
  30. data/lib/locomotive/steam/middlewares/url_redirection.rb +14 -1
  31. data/lib/locomotive/steam/repositories.rb +5 -1
  32. data/lib/locomotive/steam/repositories/content_entry_repository.rb +1 -1
  33. data/lib/locomotive/steam/repositories/content_type_field_repository.rb +4 -0
  34. data/lib/locomotive/steam/server.rb +2 -0
  35. data/lib/locomotive/steam/services.rb +9 -1
  36. data/lib/locomotive/steam/services/action_service.rb +26 -7
  37. data/lib/locomotive/steam/services/asset_host_service.rb +6 -1
  38. data/lib/locomotive/steam/services/auth_service.rb +105 -0
  39. data/lib/locomotive/steam/services/content_entry_service.rb +14 -0
  40. data/lib/locomotive/steam/services/external_api_service.rb +59 -25
  41. data/lib/locomotive/steam/services/liquid_parser_service.rb +5 -1
  42. data/lib/locomotive/steam/services/page_redirection_service.rb +29 -0
  43. data/lib/locomotive/steam/version.rb +1 -1
  44. data/locomotivecms_steam.gemspec +18 -16
  45. data/spec/fixtures/default/app/content_types/accounts.yml +59 -0
  46. data/spec/fixtures/default/app/content_types/songs.yml +2 -1
  47. data/spec/fixtures/default/app/views/pages/about_us/john_doe.fr.liquid.haml +5 -1
  48. data/spec/fixtures/default/app/views/pages/about_us/john_doe.liquid.haml +1 -1
  49. data/spec/fixtures/default/app/views/pages/account/forgot_password.liquid +39 -0
  50. data/spec/fixtures/default/app/views/pages/account/me.liquid +15 -0
  51. data/spec/fixtures/default/app/views/pages/account/reset_password.liquid +42 -0
  52. data/spec/fixtures/default/app/views/pages/account/sign_in.liquid +49 -0
  53. data/spec/fixtures/default/app/views/pages/all.liquid.haml +1 -1
  54. data/spec/fixtures/default/app/views/pages/emails/reset_password.liquid +15 -0
  55. data/spec/fixtures/default/app/views/pages/songs/template.liquid.haml +1 -1
  56. data/spec/fixtures/default/config/metafields_schema.yml +10 -0
  57. data/spec/fixtures/default/config/site.yml +5 -0
  58. data/spec/fixtures/default/config/translations.yml +25 -1
  59. data/spec/fixtures/default/data/accounts.yml +15 -0
  60. data/spec/fixtures/mongodb/locomotive_accounts.bson +0 -0
  61. data/spec/fixtures/mongodb/locomotive_accounts.metadata.json +1 -1
  62. data/spec/fixtures/mongodb/locomotive_activities.bson +0 -0
  63. data/spec/fixtures/mongodb/locomotive_activities.metadata.json +1 -1
  64. data/spec/fixtures/mongodb/locomotive_content_assets.bson +0 -0
  65. data/spec/fixtures/mongodb/locomotive_content_assets.metadata.json +1 -1
  66. data/spec/fixtures/mongodb/locomotive_content_entries.bson +0 -0
  67. data/spec/fixtures/mongodb/locomotive_content_entries.metadata.json +1 -1
  68. data/spec/fixtures/mongodb/locomotive_content_types.bson +0 -0
  69. data/spec/fixtures/mongodb/locomotive_content_types.metadata.json +1 -1
  70. data/spec/fixtures/mongodb/locomotive_pages.bson +0 -0
  71. data/spec/fixtures/mongodb/locomotive_pages.metadata.json +1 -1
  72. data/spec/fixtures/mongodb/locomotive_sites.bson +0 -0
  73. data/spec/fixtures/mongodb/locomotive_sites.metadata.json +1 -1
  74. data/spec/fixtures/mongodb/locomotive_snippets.bson +0 -0
  75. data/spec/fixtures/mongodb/locomotive_snippets.metadata.json +1 -1
  76. data/spec/fixtures/mongodb/locomotive_theme_assets.bson +0 -0
  77. data/spec/fixtures/mongodb/locomotive_theme_assets.metadata.json +1 -1
  78. data/spec/fixtures/mongodb/locomotive_translations.bson +0 -0
  79. data/spec/fixtures/mongodb/locomotive_translations.metadata.json +1 -1
  80. data/spec/integration/repositories/content_entry_repository_spec.rb +1 -1
  81. data/spec/integration/repositories/content_type_repository_spec.rb +1 -1
  82. data/spec/integration/repositories/page_repository_spec.rb +3 -3
  83. data/spec/integration/repositories/theme_asset_repository_spec.rb +1 -1
  84. data/spec/integration/repositories/translation_repository_spec.rb +1 -1
  85. data/spec/integration/server/auth_spec.rb +196 -0
  86. data/spec/integration/server/basic_spec.rb +18 -0
  87. data/spec/integration/server/nav_spec.rb +1 -1
  88. data/spec/integration/server/sitemap_spec.rb +1 -1
  89. data/spec/integration/services/content_entry_service_spec.rb +1 -1
  90. data/spec/integration/services/external_api_service_spec.rb +9 -0
  91. data/spec/support/helpers.rb +1 -1
  92. data/spec/unit/adapters/filesystem/yaml_loaders/content_entry_spec.rb +17 -5
  93. data/spec/unit/adapters/filesystem/yaml_loaders/content_type_spec.rb +4 -4
  94. data/spec/unit/adapters/filesystem/yaml_loaders/page_spec.rb +7 -7
  95. data/spec/unit/adapters/filesystem/yaml_loaders/site_spec.rb +1 -1
  96. data/spec/unit/adapters/filesystem/yaml_loaders/translation_spec.rb +1 -1
  97. data/spec/unit/entities/content_entry_spec.rb +10 -0
  98. data/spec/unit/errors_spec.rb +2 -2
  99. data/spec/unit/initializers/sprockets_spec.rb +0 -14
  100. data/spec/unit/liquid/drops/page_spec.rb +3 -2
  101. data/spec/unit/liquid/filters/date_spec.rb +219 -0
  102. data/spec/unit/liquid/tags/action_spec.rb +9 -0
  103. data/spec/unit/liquid/tags/authorize_spec.rb +51 -0
  104. data/spec/unit/liquid/tags/link_to_spec.rb +1 -1
  105. data/spec/unit/liquid/tags/paginate_spec.rb +1 -1
  106. data/spec/unit/liquid/tags/snippet_spec.rb +10 -0
  107. data/spec/unit/middlewares/auth_spec.rb +31 -0
  108. data/spec/unit/middlewares/redirection_spec.rb +37 -0
  109. data/spec/unit/middlewares/url_redirection_spec.rb +20 -1
  110. data/spec/unit/services/action_service_spec.rb +57 -1
  111. data/spec/unit/services/asset_host_service_spec.rb +15 -0
  112. data/spec/unit/services/auth_service_spec.rb +156 -0
  113. data/spec/unit/services/external_api_service_spec.rb +22 -0
  114. data/spec/unit/services/page_redirection_service_spec.rb +49 -0
  115. metadata +96 -40
  116. data/CHANGELOG.md +0 -29
  117. data/spec/fixtures/mongodb/system.indexes.bson +0 -0
@@ -30,7 +30,7 @@ describe Locomotive::Steam::Server do
30
30
  end
31
31
 
32
32
  it 'lists all the pages from the site liquid drop' do
33
- is_expected.to include('<!-- TEST -->About Us - Music - Store - Contact Us - Events - Basic page - A sample contest - Various uses of the with_scope tag - Grunge leaders - Tags - Unlisted pages - Archives - All the pages - Layouts - Songs<!-- TEST -->')
33
+ is_expected.to include('<!-- TEST -->A sample contest - About Us - Account - All the pages - Archives - Basic page - Contact Us - Emails - Events - Grunge leaders - Layouts - Music - Songs - Store - Tags - Unlisted pages - Various uses of the with_scope tag<!-- TEST -->')
34
34
  end
35
35
 
36
36
  describe 'with wrapper' do
@@ -21,7 +21,7 @@ describe Locomotive::Steam::Server do
21
21
 
22
22
  it 'checks if it looks valid' do
23
23
  expect(Nokogiri::XML(subject).errors.empty?).to eq true
24
- expect(subject.scan(/<url>/).size).to eq 40
24
+ expect(subject.scan(/<url>/).size).to eq 27
25
25
  expect(subject).to match("<loc>http://example.org/songs/song-number-2/band</loc>")
26
26
  expect(subject).to match((<<-EOF
27
27
  <url>
@@ -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('5610310b87f6431588000029') }
48
+ let(:entry_id) { BSON::ObjectId.from_string('5829ffa087f6435971756881') }
49
49
 
50
50
  describe '#create' do
51
51
  subject { service.create('messages', { name: 'John', email: 'john@doe.net', message: 'Hello world!' }) }
@@ -15,6 +15,15 @@ describe Locomotive::Steam::ExternalAPIService do
15
15
 
16
16
  it { expect(subject.size).to_not eq 0 }
17
17
 
18
+ context 'returns the status too' do
19
+
20
+ subject { service.consume(url, options, true) }
21
+
22
+ it { expect(subject[:status]).to eq 200 }
23
+ it { expect(subject[:data].size).to_not eq 0 }
24
+
25
+ end
26
+
18
27
  end
19
28
 
20
29
  end
@@ -4,7 +4,7 @@ module Spec
4
4
  module Helpers
5
5
 
6
6
  def mongodb_site_id
7
- BSON::ObjectId.from_string('561030e287f6431555000006')
7
+ BSON::ObjectId.from_string('5829ff6487f64359474164a1')
8
8
  end
9
9
 
10
10
  def reset!
@@ -6,7 +6,7 @@ require_relative '../../../../../lib/locomotive/steam/adapters/filesystem/yaml_l
6
6
  describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
7
7
 
8
8
  let(:site_path) { default_fixture_site_path }
9
- let(:content_type) { instance_double('Bands', _id: 42, slug: 'bands', association_fields: [], select_fields: [], file_fields: []) }
9
+ let(:content_type) { instance_double('Bands', _id: 42, slug: 'bands', association_fields: [], select_fields: [], file_fields: [], password_fields: []) }
10
10
  let(:scope) { instance_double('Scope', locale: :en, context: { content_type: content_type }) }
11
11
  let(:loader) { described_class.new(site_path) }
12
12
 
@@ -23,7 +23,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
23
23
  context 'a content type with a belongs_to field' do
24
24
 
25
25
  let(:field) { instance_double('Field', name: 'band', type: :belongs_to) }
26
- let(:content_type) { instance_double('Songs', slug: 'songs', association_fields: [field], select_fields: [], file_fields: []) }
26
+ let(:content_type) { instance_double('Songs', slug: 'songs', association_fields: [field], select_fields: [], file_fields: [], password_fields: []) }
27
27
 
28
28
  it 'adds a new attribute for the foreign key' do
29
29
  expect(subject.first[:band_id]).to eq 'pearl-jam'
@@ -36,7 +36,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
36
36
  context 'a content type with a select field' do
37
37
 
38
38
  let(:field) { instance_double('Field', name: 'kind', type: :select) }
39
- let(:content_type) { instance_double('Bands', slug: 'bands', select_fields: [field], association_fields: [], file_fields: []) }
39
+ let(:content_type) { instance_double('Bands', slug: 'bands', select_fields: [field], association_fields: [], file_fields: [], password_fields: []) }
40
40
 
41
41
  it 'adds a new attribute for the foreign key' do
42
42
  expect(subject.first[:kind_id]).to eq 'grunge'
@@ -45,12 +45,24 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
45
45
 
46
46
  end
47
47
 
48
+ context 'a content type with a password field' do
49
+
50
+ let(:field) { instance_double('Field', name: 'password', type: :password) }
51
+ let(:content_type) { instance_double('Accounts', slug: 'accounts', select_fields: [], association_fields: [], file_fields: [], password_fields: [field]) }
52
+
53
+ it 'adds a new attribute for the hashed password' do
54
+ expect(subject.first[:password_hash]).not_to eq 'easyone'
55
+ expect(subject.first[:password]).to eq nil
56
+ end
57
+
58
+ end
59
+
48
60
  context 'a content type with a localized field' do
49
61
 
50
62
  let(:options_scope) { instance_double('Scope', :locale= => true) }
51
63
  let(:options) { instance_double('SelectOptionsRepository', scope: options_scope) }
52
64
  let(:field) { instance_double('Field', name: 'category', type: :select, localized: true, select_options: options) }
53
- let(:content_type) { instance_double('Updates', slug: 'updates', select_fields: [field], association_fields: [], file_fields: []) }
65
+ let(:content_type) { instance_double('Updates', slug: 'updates', select_fields: [field], association_fields: [], file_fields: [], password_fields: []) }
54
66
 
55
67
  it 'adds a new localized attribute for the foreign key' do
56
68
  option = instance_double('Option', _id: 'General')
@@ -65,7 +77,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentEntry do
65
77
  context 'a content type with a file field' do
66
78
 
67
79
  let(:field) { instance_double('Field', name: 'cover', type: :file) }
68
- let(:content_type) { instance_double('Songs', slug: 'songs', select_fields: [], association_fields: [], file_fields: [field]) }
80
+ let(:content_type) { instance_double('Songs', slug: 'songs', select_fields: [], association_fields: [], file_fields: [field], password_fields: []) }
69
81
 
70
82
  it 'stores the size of the file' do
71
83
  expect(subject.first[:cover_size]).to eq('default' => 14768)
@@ -15,10 +15,10 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentType do
15
15
  subject { loader.load(scope).sort { |a, b| a[:slug] <=> b[:slug] } }
16
16
 
17
17
  it 'tests various stuff' do
18
- expect(subject.size).to eq 5
19
- expect(subject.first[:slug]).to eq('bands')
20
- expect(subject.first[:entries_custom_fields].size).to eq 5
21
- expect(subject.first[:entries_custom_fields].first[:position]).to eq 0
18
+ expect(subject.size).to eq 6
19
+ expect(subject[1][:slug]).to eq('bands')
20
+ expect(subject[1][:entries_custom_fields].size).to eq 5
21
+ expect(subject[1][:entries_custom_fields].first[:position]).to eq 0
22
22
  end
23
23
 
24
24
  end
@@ -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 26
18
+ expect(subject.size).to eq 33
19
19
  expect(subject.first[:title]).to eq(en: 'Page not found', fr: 'Page non trouvée')
20
- expect(subject[15][:is_layout]).to eq true
21
- expect(subject[15][:listed]).to eq false
22
- expect(subject[15][:published]).to eq false
23
- expect(subject[16][:slug]).to eq(en: 'music', fr: 'notre-musique')
24
- expect(subject[17][:_fullpath]).to eq 'songs'
25
- expect(subject[17][:template_path]).to eq(en: false)
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)
26
26
  end
27
27
 
28
28
  end
@@ -19,7 +19,7 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::Site do
19
19
  subject { loader.load(nil).first[:metafields_schema] }
20
20
 
21
21
  it 'loads the full schema' do
22
- expect(subject.count).to eq 3
22
+ expect(subject.count).to eq 4
23
23
  end
24
24
 
25
25
  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 1
18
+ expect(subject.size).to eq 7
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
@@ -228,6 +228,16 @@ describe Locomotive::Steam::ContentEntry do
228
228
  it { is_expected.to eq({ en: 'Category #1', fr: 'Categorie #1' }) }
229
229
  end
230
230
 
231
+ context 'a json' do
232
+ let(:field_type) { :json }
233
+ let(:value) { '{"foo":42}' }
234
+ it { is_expected.to eq({ 'foo' => 42 }) }
235
+ context 'localized' do
236
+ let(:value) { build_i18n_field(en: { 'foo' => 42 }, fr: '[1, 2, 3]') }
237
+ it { expect(subject.translations).to eq('en' => { 'foo' => 42 }, 'fr' => [1, 2, 3]) }
238
+ end
239
+ end
240
+
231
241
  end
232
242
 
233
243
  def build_i18n_field(translations = {})
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Locomotive::Steam::RenderError do
3
+ describe Locomotive::Steam::ParsingRenderingError do
4
4
 
5
5
  let(:message) { 'Wrong syntax' }
6
6
  let(:file) { 'template.liquid.haml' }
@@ -13,7 +13,7 @@ describe Locomotive::Steam::RenderError do
13
13
 
14
14
  subject { error.code_lines }
15
15
 
16
- it { is_expected.to eq [[5, 'f'], [6, 'g'], [7, 'h'], [8, 'i'], [9, 'j'], [10, 'k'], [11, 'l'], [12, 'm'], [13, 'n'], [14, 'o'], [15, 'p']] }
16
+ it { is_expected.to eq [[5, 'e'], [6, 'f'], [7, 'g'], [8, 'h'], [9, 'i'], [10, 'j'], [11, 'k'], [12, 'l'], [13, 'm'], [14, 'n'], [15, 'o']] }
17
17
 
18
18
  end
19
19
 
@@ -8,20 +8,6 @@ describe Locomotive::Steam::SprocketsEnvironment do
8
8
  let(:options) { { minify: true } }
9
9
  let(:env) { described_class.new(root, options) }
10
10
 
11
- describe '#install_yui_compressor' do
12
-
13
- context 'java not installed' do
14
-
15
- before { allow(env).to receive(:is_java_installed?).and_return(false) }
16
-
17
- subject { env.send(:install_yui_compressor, options) }
18
-
19
- it { is_expected.to eq(false) }
20
-
21
- end
22
-
23
- end
24
-
25
11
  describe '#install_autoprefixer' do
26
12
 
27
13
  let(:options) { { minify: false } }
@@ -46,13 +46,14 @@ describe Locomotive::Steam::Liquid::Drops::Page do
46
46
 
47
47
  describe '#breadcrumbs' do
48
48
 
49
- let(:ancestors) { [instance_double('ParentPage', to_liquid: { 'title' => 'Parent' })] }
49
+ let(:ancestors) { [instance_double('ParentPage', to_liquid: { 'title' => 'Parent' }), page] }
50
50
 
51
51
  before do
52
+ expect(page).to receive(:to_liquid).and_return(drop)
52
53
  allow(services.repositories.page).to receive(:ancestors_of).with(page).and_return(ancestors)
53
54
  end
54
55
 
55
- it { expect(subject.breadcrumbs).to eq([{ 'title' => 'Parent' }]) }
56
+ it { expect(subject.breadcrumbs.map { |p| p['title'] }).to eq(['Parent', 'Index']) }
56
57
 
57
58
  end
58
59
 
@@ -157,4 +157,223 @@ describe Locomotive::Steam::Liquid::Filters::Date do
157
157
 
158
158
  end
159
159
 
160
+ describe '#end_of_year' do
161
+
162
+ let(:input) { date }
163
+ subject { end_of_year(input) }
164
+
165
+ describe 'with a date' do
166
+ it { is_expected.to eq Date.parse('2007/12/31') }
167
+ end
168
+
169
+ describe 'with a datetime' do
170
+ let(:input) { date_time }
171
+ it { is_expected.to eq Time.zone.parse('2007/12/31 23:59:59.999999999') }
172
+ end
173
+
174
+ describe 'with a string' do
175
+ let(:input) { '2007/06/29' }
176
+ it { is_expected.to eq Time.zone.parse('2007/12/31 23:59:59.999999999') }
177
+ end
178
+
179
+ describe 'with a bad input' do
180
+ let(:input) { 'not a date' }
181
+ it { is_expected.to eq '' }
182
+ end
183
+ end
184
+
185
+ describe '#beginning_of_year' do
186
+
187
+ let(:input) { date }
188
+ subject { beginning_of_year(input) }
189
+
190
+ describe 'with a date' do
191
+ it { is_expected.to eq Date.parse('2007/01/01') }
192
+ end
193
+
194
+ describe 'with a datetime' do
195
+ let(:input) { date_time }
196
+ it { is_expected.to eq Time.zone.parse('2007/01/01 00:00:00.000000000') }
197
+ end
198
+
199
+ describe 'with a string' do
200
+ let(:input) { '2007/06/29' }
201
+ it { is_expected.to eq Time.zone.parse('2007/01/01 00:00:00.000000000') }
202
+ end
203
+
204
+ describe 'with a bad input' do
205
+ let(:input) { 'not a date' }
206
+ it { is_expected.to eq '' }
207
+ end
208
+ end
209
+
210
+ describe '#end_of_month' do
211
+
212
+ let(:input) { date }
213
+ subject { end_of_month(input) }
214
+
215
+ describe 'with a date' do
216
+ it { is_expected.to eq Date.parse('2007/06/30') }
217
+ end
218
+
219
+ describe 'with a datetime' do
220
+ let(:input) { date_time }
221
+ it { is_expected.to eq Time.zone.parse('2007/06/30 23:59:59.999999999') }
222
+ end
223
+
224
+ describe 'with a string' do
225
+ let(:input) { '2007/06/29' }
226
+ it { is_expected.to eq Time.zone.parse('2007/06/30 23:59:59.999999999') }
227
+ end
228
+
229
+ describe 'with a bad input' do
230
+ let(:input) { 'not a date' }
231
+ it { is_expected.to eq '' }
232
+ end
233
+ end
234
+
235
+ describe '#beginning_of_month' do
236
+
237
+ let(:input) { date }
238
+ subject { beginning_of_month(input) }
239
+
240
+ describe 'with a date' do
241
+ it { is_expected.to eq Date.parse('2007/06/01') }
242
+ end
243
+
244
+ describe 'with a datetime' do
245
+ let(:input) { date_time }
246
+ it { is_expected.to eq Time.zone.parse('2007/06/01 00:00:00.000000000') }
247
+ end
248
+
249
+ describe 'with a string' do
250
+ let(:input) { '2007/06/29' }
251
+ it { is_expected.to eq Time.zone.parse('2007/06/01 00:00:00.000000000') }
252
+ end
253
+
254
+ describe 'with a bad input' do
255
+ let(:input) { 'not a date' }
256
+ it { is_expected.to eq '' }
257
+ end
258
+ end
259
+
260
+ describe '#end_of_week' do
261
+
262
+ let(:input) { date }
263
+ subject { end_of_week(input) }
264
+
265
+ describe 'with a date' do
266
+ it { is_expected.to eq Date.parse('2007/07/01') }
267
+ end
268
+
269
+ describe 'with a datetime' do
270
+ let(:input) { date_time }
271
+ it { is_expected.to eq Time.zone.parse('2007/07/01 23:59:59.999999999') }
272
+ end
273
+
274
+ describe 'with a string' do
275
+ let(:input) { '2007/06/29' }
276
+ it { is_expected.to eq Time.zone.parse('2007/07/01 23:59:59.999999999') }
277
+ end
278
+
279
+ describe 'with a bad input' do
280
+ let(:input) { 'not a date' }
281
+ it { is_expected.to eq '' }
282
+ end
283
+ end
284
+
285
+ describe '#beginning_of_week' do
286
+
287
+ let(:input) { date }
288
+ subject { beginning_of_week(input) }
289
+
290
+ describe 'with a date' do
291
+ it { is_expected.to eq Date.parse('2007/06/25') }
292
+ end
293
+
294
+ describe 'with a datetime' do
295
+ let(:input) { date_time }
296
+ it { is_expected.to eq Time.zone.parse('2007/06/25 00:00:00.000000000') }
297
+ end
298
+
299
+ describe 'with a string' do
300
+ let(:input) { '2007/06/29' }
301
+ it { is_expected.to eq Time.zone.parse('2007/06/25 00:00:00.000000000') }
302
+ end
303
+
304
+ describe 'with a bad input' do
305
+ let(:input) { 'not a date' }
306
+ it { is_expected.to eq '' }
307
+ end
308
+ end
309
+
310
+ describe '#end_of_day' do
311
+
312
+ let(:input) { date }
313
+ subject { end_of_day(input) }
314
+
315
+ describe 'with a date' do
316
+ it { is_expected.to eq Time.zone.parse('2007/06/29 23:59:59.999999999') }
317
+ end
318
+
319
+ describe 'with a datetime' do
320
+ let(:input) { date_time }
321
+ it { is_expected.to eq Time.zone.parse('2007/06/29 23:59:59.999999999') }
322
+ end
323
+
324
+ describe 'with a string' do
325
+ let(:input) { '2007/06/29' }
326
+ it { is_expected.to eq Time.zone.parse('2007/06/29 23:59:59.999999999') }
327
+ end
328
+
329
+ describe 'with a bad input' do
330
+ let(:input) { 'not a date' }
331
+ it { is_expected.to eq '' }
332
+ end
333
+ end
334
+
335
+ describe '#beginning_of_day' do
336
+
337
+ let(:input) { date }
338
+ subject { beginning_of_day(input) }
339
+
340
+ describe 'with a date' do
341
+ it { is_expected.to eq Time.zone.parse('2007/06/29 00:00:00.000000000') }
342
+ end
343
+
344
+ describe 'with a datetime' do
345
+ let(:input) { date_time }
346
+ it { is_expected.to eq Time.zone.parse('2007/06/29 00:00:00.000000000') }
347
+ end
348
+
349
+ describe 'with a string' do
350
+ let(:input) { '2007/06/29' }
351
+ it { is_expected.to eq Time.zone.parse('2007/06/29 00:00:00.000000000') }
352
+ end
353
+
354
+ describe 'with a bad input' do
355
+ let(:input) { 'not a date' }
356
+ it { is_expected.to eq '' }
357
+ end
358
+ end
359
+
360
+ describe '#adjust_date' do
361
+
362
+ let(:input) { date }
363
+ let(:adjustment) { 1 }
364
+ let(:unit) { 'month' }
365
+ subject { adjust_date(input, adjustment, unit) }
366
+
367
+ it { is_expected.to eq Date.parse('2007/07/29') }
368
+
369
+ context 'unit is not a valid value (month, year, day, etc.)' do
370
+
371
+ let(:unit) { 'foo' }
372
+
373
+ it { is_expected.to eq Date.parse('2007/06/29') }
374
+
375
+ end
376
+
377
+ end
378
+
160
379
  end