alchemy_cms 3.0.4 → 3.1.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (210) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +4 -6
  3. data/Gemfile +4 -7
  4. data/README.md +207 -115
  5. data/alchemy_cms.gemspec +10 -9
  6. data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +2 -2
  7. data/app/assets/javascripts/alchemy/alchemy.image_cropper.js.coffee +2 -2
  8. data/app/assets/javascripts/alchemy/alchemy.js +6 -7
  9. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +1 -43
  10. data/app/assets/javascripts/alchemy/alchemy.uploader.js.coffee +1 -1
  11. data/app/assets/stylesheets/alchemy/_mixins.scss +2 -1
  12. data/app/assets/stylesheets/alchemy/buttons.scss +0 -5
  13. data/app/assets/stylesheets/alchemy/dialogs.scss +1 -0
  14. data/app/assets/stylesheets/alchemy/frame.scss +9 -12
  15. data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +11 -2
  16. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +9 -1
  17. data/app/controllers/alchemy/admin/attachments_controller.rb +2 -4
  18. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +34 -38
  19. data/app/controllers/alchemy/api/base_controller.rb +19 -0
  20. data/app/controllers/alchemy/api/contents_controller.rb +35 -0
  21. data/app/controllers/alchemy/api/elements_controller.rb +29 -0
  22. data/app/controllers/alchemy/api/pages_controller.rb +32 -0
  23. data/app/controllers/alchemy/contents_controller.rb +1 -0
  24. data/app/controllers/alchemy/elements_controller.rb +5 -2
  25. data/app/controllers/alchemy/pages_controller.rb +4 -1
  26. data/app/controllers/alchemy/pictures_controller.rb +4 -36
  27. data/app/helpers/alchemy/admin/essences_helper.rb +5 -2
  28. data/app/helpers/alchemy/essences_helper.rb +14 -1
  29. data/app/models/alchemy/content.rb +32 -4
  30. data/app/models/alchemy/element.rb +2 -16
  31. data/app/models/alchemy/element/presenters.rb +2 -2
  32. data/app/models/alchemy/essence_file.rb +5 -0
  33. data/app/models/alchemy/essence_picture.rb +12 -8
  34. data/app/models/alchemy/picture.rb +1 -74
  35. data/app/models/alchemy/picture/transformations.rb +249 -0
  36. data/app/serializers/alchemy/content_serializer.rb +3 -10
  37. data/app/serializers/alchemy/element_serializer.rb +6 -3
  38. data/app/serializers/alchemy/legacy_element_serializer.rb +17 -0
  39. data/app/views/alchemy/admin/dashboard/_sites.html.erb +14 -4
  40. data/app/views/alchemy/admin/essence_pictures/crop.html.erb +8 -5
  41. data/app/views/alchemy/admin/pages/edit.html.erb +9 -9
  42. data/app/views/alchemy/admin/pictures/info.html.erb +2 -3
  43. data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
  44. data/app/views/alchemy/essences/_essence_boolean_editor.html.erb +8 -7
  45. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +3 -3
  46. data/app/views/alchemy/essences/_essence_date_editor.html.erb +8 -2
  47. data/app/views/alchemy/essences/_essence_date_view.html.erb +10 -8
  48. data/app/views/alchemy/essences/_essence_file_editor.html.erb +48 -53
  49. data/app/views/alchemy/essences/_essence_file_view.html.erb +5 -5
  50. data/app/views/alchemy/essences/_essence_html_editor.html.erb +5 -4
  51. data/app/views/alchemy/essences/_essence_link_editor.html.erb +17 -15
  52. data/app/views/alchemy/essences/_essence_link_view.html.erb +11 -7
  53. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +4 -2
  54. data/app/views/alchemy/essences/_essence_picture_view.html.erb +4 -2
  55. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +5 -4
  56. data/app/views/alchemy/essences/_essence_select_editor.html.erb +22 -32
  57. data/app/views/alchemy/essences/_essence_text_view.html.erb +7 -6
  58. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +1 -1
  59. data/app/views/layouts/alchemy/admin.html.erb +5 -3
  60. data/config/initializers/inflections.rb +3 -0
  61. data/config/initializers/simple_form.rb +1 -1
  62. data/config/locales/alchemy.en.yml +0 -1
  63. data/config/routes.rb +14 -0
  64. data/lib/alchemy/capistrano.rb +71 -0
  65. data/lib/alchemy/engine.rb +0 -3
  66. data/lib/alchemy/essence.rb +1 -1
  67. data/lib/alchemy/permissions.rb +19 -5
  68. data/lib/alchemy/picture_attributes.rb +1 -1
  69. data/lib/alchemy/test_support/auth_helpers.rb +1 -1
  70. data/lib/alchemy/test_support/essence_shared_examples.rb +37 -22
  71. data/lib/alchemy/test_support/integration_helpers.rb +1 -1
  72. data/lib/alchemy/tinymce.rb +21 -4
  73. data/lib/alchemy/upgrader/three_point_one.rb +43 -0
  74. data/lib/alchemy/upgrader/three_point_zero.rb +13 -0
  75. data/lib/alchemy/version.rb +2 -1
  76. data/lib/rails/generators/alchemy/module/module_generator.rb +30 -0
  77. data/lib/rails/generators/alchemy/module/templates/ability.rb.tt +11 -0
  78. data/lib/rails/generators/alchemy/module/templates/controller.rb.tt +2 -0
  79. data/lib/rails/generators/alchemy/module/templates/module_config.rb.tt +15 -0
  80. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +0 -1
  81. data/lib/rails/templates/alchemy.rb +2 -2
  82. data/lib/tasks/alchemy/db.rake +7 -1
  83. data/spec/controllers/admin/attachments_controller_spec.rb +38 -38
  84. data/spec/controllers/admin/base_controller_spec.rb +18 -18
  85. data/spec/controllers/admin/clipboard_controller_spec.rb +23 -18
  86. data/spec/controllers/admin/contents_controller_spec.rb +33 -27
  87. data/spec/controllers/admin/dashboard_controller_spec.rb +14 -14
  88. data/spec/controllers/admin/elements_controller_spec.rb +125 -105
  89. data/spec/controllers/admin/essence_files_controller_spec.rb +6 -7
  90. data/spec/controllers/admin/essence_pictures_controller_spec.rb +52 -42
  91. data/spec/controllers/admin/languages_controller_spec.rb +3 -3
  92. data/spec/controllers/admin/pages_controller_spec.rb +81 -71
  93. data/spec/controllers/admin/pictures_controller_spec.rb +69 -72
  94. data/spec/controllers/admin/resources_controller_spec.rb +5 -5
  95. data/spec/controllers/admin/trash_controller_spec.rb +15 -12
  96. data/spec/controllers/alchemy/admin/tags_controller_spec.rb +8 -8
  97. data/spec/controllers/alchemy/api/contents_controller_spec.rb +73 -0
  98. data/spec/controllers/alchemy/api/elements_controller_spec.rb +69 -0
  99. data/spec/controllers/alchemy/api/pages_controller_spec.rb +86 -0
  100. data/spec/controllers/attachments_controller_spec.rb +8 -8
  101. data/spec/controllers/contents_controller_spec.rb +22 -0
  102. data/spec/controllers/elements_controller_spec.rb +10 -4
  103. data/spec/controllers/messages_controller_spec.rb +35 -34
  104. data/spec/controllers/pages_controller_spec.rb +37 -28
  105. data/spec/controllers/pictures_controller_spec.rb +90 -23
  106. data/spec/dummy/app/models/dummy_user.rb +0 -4
  107. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_editor.html.erb +11 -0
  108. data/spec/dummy/config/alchemy/elements.yml +22 -1
  109. data/spec/dummy/config/alchemy/page_layouts.yml +4 -0
  110. data/spec/dummy/config/application.rb +2 -1
  111. data/spec/dummy/config/environments/test.rb +3 -1
  112. data/spec/features/admin/dashboard_spec.rb +41 -6
  113. data/spec/features/admin/language_tree_feature_spec.rb +3 -3
  114. data/spec/features/admin/legacy_page_url_management_spec.rb +1 -1
  115. data/spec/features/admin/link_overlay_spec.rb +7 -7
  116. data/spec/features/admin/locale_select_feature_spec.rb +5 -2
  117. data/spec/features/admin/modules_integration_spec.rb +1 -1
  118. data/spec/features/admin/page_creation_feature_spec.rb +3 -2
  119. data/spec/features/admin/page_editing_feature_spec.rb +66 -79
  120. data/spec/features/admin/picture_library_integration_spec.rb +8 -8
  121. data/spec/features/admin/resources_integration_spec.rb +21 -21
  122. data/spec/features/admin/tinymce_feature_spec.rb +36 -0
  123. data/spec/features/navigation_spec.rb +1 -1
  124. data/spec/features/page_feature_spec.rb +34 -34
  125. data/spec/features/picture_security_spec.rb +4 -4
  126. data/spec/features/security_spec.rb +1 -1
  127. data/spec/features/translation_integration_spec.rb +7 -7
  128. data/spec/helpers/admin/base_helper_spec.rb +51 -49
  129. data/spec/helpers/admin/contents_helper_spec.rb +11 -11
  130. data/spec/helpers/admin/elements_helper_spec.rb +20 -17
  131. data/spec/helpers/admin/essences_helper_spec.rb +42 -11
  132. data/spec/helpers/admin/navigation_helper_spec.rb +64 -54
  133. data/spec/helpers/admin/pages_helper_spec.rb +10 -10
  134. data/spec/helpers/admin/tags_helper_spec.rb +16 -16
  135. data/spec/helpers/base_helper_spec.rb +11 -11
  136. data/spec/helpers/elements_block_helper_spec.rb +24 -24
  137. data/spec/helpers/elements_helper_spec.rb +46 -46
  138. data/spec/helpers/essences_helper_spec.rb +90 -17
  139. data/spec/helpers/pages_helper_spec.rb +53 -53
  140. data/spec/helpers/picture_url_helpers_spec.rb +6 -6
  141. data/spec/helpers/url_helper_spec.rb +32 -32
  142. data/spec/libraries/config_spec.rb +9 -9
  143. data/spec/libraries/controller_actions_spec.rb +14 -14
  144. data/spec/libraries/i18n_spec.rb +6 -6
  145. data/spec/libraries/kaminari/scoped_pagination_url_helper_spec.rb +4 -4
  146. data/spec/libraries/modules_spec.rb +4 -4
  147. data/spec/libraries/mount_point_spec.rb +13 -13
  148. data/spec/libraries/page_layout_spec.rb +24 -24
  149. data/spec/libraries/permissions_spec.rb +97 -80
  150. data/spec/libraries/resource_spec.rb +37 -37
  151. data/spec/libraries/resources_helper_spec.rb +19 -19
  152. data/spec/libraries/shell_spec.rb +17 -17
  153. data/spec/libraries/template_tracker_spec.rb +14 -14
  154. data/spec/libraries/tinymce_spec.rb +8 -8
  155. data/spec/libraries/userstamp_spec.rb +2 -2
  156. data/spec/mailers/messages_spec.rb +4 -4
  157. data/spec/models/attachment_spec.rb +86 -30
  158. data/spec/models/cell_spec.rb +10 -10
  159. data/spec/models/content_spec.rb +106 -46
  160. data/spec/models/element_spec.rb +94 -115
  161. data/spec/models/essence_date_spec.rb +1 -1
  162. data/spec/models/essence_file_spec.rb +4 -4
  163. data/spec/models/essence_picture_spec.rb +56 -25
  164. data/spec/models/essence_richtext_spec.rb +1 -1
  165. data/spec/models/essence_text_spec.rb +7 -7
  166. data/spec/models/language_spec.rb +12 -12
  167. data/spec/models/legacy_page_url_spec.rb +2 -2
  168. data/spec/models/message_spec.rb +12 -5
  169. data/spec/models/page_spec.rb +259 -235
  170. data/spec/models/picture_spec.rb +72 -166
  171. data/spec/models/site_spec.rb +41 -41
  172. data/spec/models/tag_spec.rb +7 -7
  173. data/spec/routing/api_routing_spec.rb +150 -0
  174. data/spec/routing/routing_spec.rb +28 -28
  175. data/spec/spec_helper.rb +6 -5
  176. data/spec/support/hint_examples.rb +5 -5
  177. data/spec/support/transformation_examples.rb +173 -0
  178. data/spec/tasks/helpers_spec.rb +29 -29
  179. data/spec/views/essences/essence_boolean_editor_spec.rb +32 -0
  180. data/spec/views/essences/essence_boolean_view_spec.rb +2 -2
  181. data/spec/views/essences/essence_date_view_spec.rb +1 -1
  182. data/spec/views/essences/essence_link_view_spec.rb +11 -0
  183. data/spec/views/essences/essence_picture_view_spec.rb +56 -11
  184. data/spec/views/essences/essence_richtext_view_spec.rb +12 -0
  185. data/spec/views/essences/essence_text_view_spec.rb +12 -0
  186. data/vendor/assets/javascripts/tinymce/langs/de.js +20 -2
  187. data/vendor/assets/javascripts/tinymce/langs/fr.js +14 -1
  188. data/vendor/assets/javascripts/tinymce/langs/nl.js +22 -4
  189. data/vendor/assets/javascripts/tinymce/plugins/anchor/plugin.min.js +1 -1
  190. data/vendor/assets/javascripts/tinymce/plugins/autoresize/plugin.min.js +1 -1
  191. data/vendor/assets/javascripts/tinymce/plugins/charmap/plugin.min.js +1 -1
  192. data/vendor/assets/javascripts/tinymce/plugins/code/plugin.min.js +1 -1
  193. data/vendor/assets/javascripts/tinymce/plugins/directionality/plugin.min.js +1 -1
  194. data/vendor/assets/javascripts/tinymce/plugins/fullscreen/plugin.min.js +1 -1
  195. data/vendor/assets/javascripts/tinymce/plugins/hr/plugin.min.js +1 -1
  196. data/vendor/assets/javascripts/tinymce/plugins/link/plugin.min.js +1 -1
  197. data/vendor/assets/javascripts/tinymce/plugins/paste/plugin.min.js +1 -1
  198. data/vendor/assets/javascripts/tinymce/plugins/tabfocus/plugin.min.js +1 -1
  199. data/vendor/assets/javascripts/tinymce/plugins/table/plugin.min.js +1 -1
  200. data/vendor/assets/javascripts/tinymce/themes/modern/theme.min.js +1 -1
  201. data/vendor/assets/javascripts/tinymce/tinymce.min.js +11 -10
  202. metadata +72 -42
  203. data/app/views/alchemy/messages/contact_form_mail.es.text.erb +0 -12
  204. data/config/locales/alchemy.es.yml +0 -958
  205. data/config/locales/alchemy.ru.yml +0 -837
  206. data/config/locales/simple_form.es.yml +0 -6
  207. data/config/locales/simple_form.ru.yml +0 -25
  208. data/lib/rails/generators/alchemy/scaffold/files/alchemy.es.yml +0 -31
  209. data/vendor/assets/javascripts/tinymce/langs/es.js +0 -197
  210. data/vendor/assets/javascripts/tinymce/langs/ru.js +0 -197
@@ -19,7 +19,7 @@ module Alchemy
19
19
  context "if date set" do
20
20
  it "should format the date by i18n" do
21
21
  essence.date = DateTime.now
22
- ::I18n.should_receive(:l).with(essence.date, format: :date)
22
+ expect(::I18n).to receive(:l).with(essence.date, format: :date)
23
23
  essence.preview_text
24
24
  end
25
25
  end
@@ -15,26 +15,26 @@ module Alchemy
15
15
  subject { essence.attachment_url }
16
16
 
17
17
  it "returns the download attachment url." do
18
- should match(/\/attachment\/#{attachment.id}\/download\/#{attachment.file_name}/)
18
+ is_expected.to match(/\/attachment\/#{attachment.id}\/download\/#{attachment.file_name}/)
19
19
  end
20
20
 
21
21
  context 'without attachment assigned' do
22
22
  let(:attachment) { nil }
23
23
 
24
- it { should be_nil }
24
+ it { is_expected.to be_nil }
25
25
  end
26
26
  end
27
27
 
28
28
  describe '#preview_text' do
29
29
 
30
30
  it "returns the attachment's name as preview text" do
31
- essence.preview_text.should == attachment.name
31
+ expect(essence.preview_text).to eq(attachment.name)
32
32
  end
33
33
 
34
34
  context "with no attachment assigned" do
35
35
  it "returns empty string" do
36
36
  essence.attachment = nil
37
- essence.preview_text.should == ''
37
+ expect(essence.preview_text).to eq('')
38
38
  end
39
39
  end
40
40
  end
@@ -7,24 +7,28 @@ module Alchemy
7
7
  let(:ingredient_value) { Picture.new }
8
8
  end
9
9
 
10
+ it_behaves_like "has image transformations" do
11
+ let(:picture) { build_stubbed(:essence_picture) }
12
+ end
13
+
10
14
  it "should not store negative values for crop values" do
11
15
  essence = EssencePicture.new(:crop_from => '-1x100', :crop_size => '-20x30')
12
16
  essence.save!
13
- essence.crop_from.should == "0x100"
14
- essence.crop_size.should == "0x30"
17
+ expect(essence.crop_from).to eq("0x100")
18
+ expect(essence.crop_size).to eq("0x30")
15
19
  end
16
20
 
17
21
  it "should not store float values for crop values" do
18
22
  essence = EssencePicture.new(:crop_from => '0.05x104.5', :crop_size => '99.5x203.4')
19
23
  essence.save!
20
- essence.crop_from.should == "0x105"
21
- essence.crop_size.should == "100x203"
24
+ expect(essence.crop_from).to eq("0x105")
25
+ expect(essence.crop_size).to eq("100x203")
22
26
  end
23
27
 
24
28
  it "should convert newlines in caption into <br/>s" do
25
29
  essence = EssencePicture.new(:caption => "hello\nkitty")
26
30
  essence.save!
27
- essence.caption.should == "hello<br/>kitty"
31
+ expect(essence.caption).to eq("hello<br/>kitty")
28
32
  end
29
33
 
30
34
  describe '#picture_url' do
@@ -35,24 +39,24 @@ module Alchemy
35
39
  let(:essence) { build_stubbed(:essence_picture, picture: picture) }
36
40
 
37
41
  it "returns the show picture url." do
38
- should match(/\/pictures\/#{picture.id}\/show\/#{picture.urlname}\.#{Config.get(:image_output_format)}/)
42
+ is_expected.to match(/\/pictures\/#{picture.id}\/show\/#{picture.urlname}\.#{Config.get(:image_output_format)}/)
39
43
  end
40
44
 
41
45
  it "includes the secure hash." do
42
- should match(/\?sh=\S+\z/)
46
+ is_expected.to match(/\?sh=\S+\z/)
43
47
  end
44
48
 
45
49
  context 'with size in the options' do
46
50
  let(:options) { {size: '200x300'} }
47
51
 
48
52
  it "includes the size in the url." do
49
- should match(/200x300/)
53
+ is_expected.to match(/200x300/)
50
54
  end
51
55
  end
52
56
 
53
57
  context 'with no format in the options' do
54
58
  it "includes the default image output format." do
55
- should match(/#{Config.get(:image_output_format)}/)
59
+ is_expected.to match(/#{Config.get(:image_output_format)}/)
56
60
  end
57
61
  end
58
62
 
@@ -60,24 +64,27 @@ module Alchemy
60
64
  let(:options) { {format: 'png'} }
61
65
 
62
66
  it "takes this as format." do
63
- should match(/png/)
67
+ is_expected.to match(/png/)
64
68
  end
65
69
  end
66
70
 
67
71
  context 'with crop sizes set' do
68
- before { essence.stub(crop_size: '200x200', crop_from: '10x10') }
72
+ before do
73
+ expect(essence).to receive(:crop_size).at_least(:once).and_return('200x200')
74
+ expect(essence).to receive(:crop_from).at_least(:once).and_return('10x10')
75
+ end
69
76
 
70
77
  it "includes the crop sizes in the url." do
71
- should match(/200x200/)
72
- should match(/10x10/)
78
+ is_expected.to match(/200x200/)
79
+ is_expected.to match(/10x10/)
73
80
  end
74
81
 
75
82
  context 'but with crop sizes in the options' do
76
83
  let(:options) { {crop_from: '30x30', crop_size: '75x75'} }
77
84
 
78
85
  it "includes these crop sizes instead." do
79
- should match(/30x30/)
80
- should match(/75x75/)
86
+ is_expected.to match(/30x30/)
87
+ is_expected.to match(/75x75/)
81
88
  end
82
89
  end
83
90
  end
@@ -86,8 +93,8 @@ module Alchemy
86
93
  let(:options) { {crop: true} }
87
94
 
88
95
  it 'converts the value into `crop`' do
89
- should match /crop/
90
- should_not match /true/
96
+ is_expected.to match /crop/
97
+ is_expected.not_to match /true/
91
98
  end
92
99
  end
93
100
 
@@ -95,7 +102,7 @@ module Alchemy
95
102
  let(:options) { {image_size: '100x100'} }
96
103
 
97
104
  it 'converts the key into `size`' do
98
- should match /100x100/
105
+ is_expected.to match /100x100/
99
106
  end
100
107
  end
101
108
 
@@ -103,14 +110,14 @@ module Alchemy
103
110
  let(:options) { {foo: 'baz'} }
104
111
 
105
112
  it 'it removes them from params' do
106
- should_not match /foo/
113
+ is_expected.not_to match /foo/
107
114
  end
108
115
  end
109
116
 
110
117
  context 'without picture assigned' do
111
118
  let(:picture) { nil }
112
119
 
113
- it { should be_nil }
120
+ it { is_expected.to be_nil }
114
121
  end
115
122
  end
116
123
 
@@ -121,14 +128,14 @@ module Alchemy
121
128
  let(:essence) { build_stubbed(:essence_picture, crop_from: '0x0', crop_size: '100x100') }
122
129
 
123
130
  it "returns a hash containing cropping coordinates" do
124
- should == {x1: 0, y1: 0, x2: 100, y2: 100}
131
+ is_expected.to eq({x1: 0, y1: 0, x2: 100, y2: 100})
125
132
  end
126
133
  end
127
134
 
128
135
  context 'with no crop values given' do
129
136
  let(:essence) { build_stubbed(:essence_picture) }
130
137
 
131
- it { should be_nil }
138
+ it { is_expected.to be_nil }
132
139
  end
133
140
  end
134
141
 
@@ -137,13 +144,37 @@ module Alchemy
137
144
  let(:essence) { EssencePicture.new }
138
145
 
139
146
  it "should return the pictures name as preview text" do
140
- essence.stub(:picture).and_return(picture)
141
- essence.preview_text.should == 'Cute Cat Kittens'
147
+ allow(essence).to receive(:picture).and_return(picture)
148
+ expect(essence.preview_text).to eq('Cute Cat Kittens')
142
149
  end
143
150
 
144
151
  context "with no picture assigned" do
145
152
  it "returns empty string" do
146
- essence.preview_text.should == ''
153
+ expect(essence.preview_text).to eq('')
154
+ end
155
+ end
156
+ end
157
+
158
+ describe '#serialized_ingredient' do
159
+ let(:content) { Content.new }
160
+ let(:picture) { mock_model(Picture, name: 'Cute Cat Kittens', urlname: 'cute-cat-kittens', security_token: 'kljhgfd')}
161
+ let(:essence) { EssencePicture.new(content: content, picture: picture) }
162
+
163
+ it "returns the url to render the picture" do
164
+ expect(essence.serialized_ingredient).to eq("/pictures/#{picture.id}/show/#{picture.urlname}.jpg?sh=#{picture.security_token}")
165
+ end
166
+
167
+ context 'with image settings given at content' do
168
+ before do
169
+ expect(content).to receive(:settings).and_return({size: '150x150', format: 'png', select_values: [1,2,3]})
170
+ end
171
+
172
+ it "returns the url with cropping and resizing options" do
173
+ expect(essence.serialized_ingredient).to eq("/pictures/#{picture.id}/show/150x150/#{picture.urlname}.png?sh=#{picture.security_token}")
174
+ end
175
+
176
+ it "rejects options that are not cropping and resizing options" do
177
+ expect(essence.serialized_ingredient).to_not match("select_values")
147
178
  end
148
179
  end
149
180
  end
@@ -11,7 +11,7 @@ module Alchemy
11
11
 
12
12
  it "should save a HTML tag free version of body column" do
13
13
  essence.save
14
- essence.stripped_body.should == "Hello!Welcome to Peters Petshop."
14
+ expect(essence.stripped_body).to eq("Hello!Welcome to Peters Petshop.")
15
15
  end
16
16
 
17
17
  end
@@ -17,23 +17,23 @@ module Alchemy
17
17
  end
18
18
 
19
19
  it "should return a preview text" do
20
- essence.preview_text.should == "#{ingredient_value}"
20
+ expect(essence.preview_text).to eq("#{ingredient_value}")
21
21
  end
22
22
 
23
23
  context "with given maxlength" do
24
24
  it "should return as much beginning characters as defined with maxlength" do
25
- essence.preview_text(2).should == "#{ingredient_value}"[0..1]
25
+ expect(essence.preview_text(2)).to eq("#{ingredient_value}"[0..1])
26
26
  end
27
27
  end
28
28
 
29
29
  context "with another preview_text_column defined" do
30
30
  before do
31
- essence.stub(:title).and_return('Title column')
32
- essence.stub(:preview_text_column).and_return(:title)
31
+ allow(essence).to receive(:title).and_return('Title column')
32
+ allow(essence).to receive(:preview_text_column).and_return(:title)
33
33
  end
34
34
 
35
35
  it "should use this column as preview text method" do
36
- essence.preview_text.should == 'Title column'
36
+ expect(essence.preview_text).to eq('Title column')
37
37
  end
38
38
  end
39
39
  end
@@ -65,7 +65,7 @@ module Alchemy
65
65
 
66
66
  context 'given a regex string' do
67
67
  before do
68
- essence.stub(:description).and_return({'validate' => [{'format' => /\Ahttps:\/\/[\S]+/}]})
68
+ allow(essence).to receive(:description).and_return({'validate' => [{'format' => /\Ahttps:\/\/[\S]+/}]})
69
69
  end
70
70
 
71
71
  context 'when ingredient string does not match the given regex' do
@@ -87,7 +87,7 @@ module Alchemy
87
87
 
88
88
  context 'given a key from the config`s format_matcher list' do
89
89
  before do
90
- essence.stub(:description).and_return({'validate' => [{'format' => 'email'}]})
90
+ allow(essence).to receive(:description).and_return({'validate' => [{'format' => 'email'}]})
91
91
  end
92
92
 
93
93
  context 'when ingredient string does not match the given format matcher' do
@@ -8,30 +8,30 @@ module Alchemy
8
8
  let(:page) { FactoryGirl.create(:page, language: language) }
9
9
 
10
10
  it "should return a label for code" do
11
- language.label(:code).should == 'kl'
11
+ expect(language.label(:code)).to eq('kl')
12
12
  end
13
13
 
14
14
  it "should return a label for name" do
15
- language.label(:name).should == 'Klingonian'
15
+ expect(language.label(:name)).to eq('Klingonian')
16
16
  end
17
17
 
18
18
  context "with language_code and empty country_code" do
19
19
  it "#code should return language locale only" do
20
20
  language.country_code = ''
21
- language.code.should == 'kl'
21
+ expect(language.code).to eq('kl')
22
22
  end
23
23
 
24
24
  context "adding a value for country code" do
25
25
  it "#code should return a joined locale" do
26
26
  language.country_code = 'cr'
27
- language.code.should == 'kl-cr'
27
+ expect(language.code).to eq('kl-cr')
28
28
  end
29
29
 
30
30
  it "should update all associated Pages with self.code as value for Page#language_code" do
31
31
  page = FactoryGirl.create(:page, language: language)
32
32
  language.country_code = 'cr'
33
33
  language.save
34
- page.reload; page.language_code.should == 'kl-cr'
34
+ page.reload; expect(page.language_code).to eq('kl-cr')
35
35
  end
36
36
  end
37
37
  end
@@ -42,7 +42,7 @@ module Alchemy
42
42
  language = FactoryGirl.create(:language, country_code: 'kl')
43
43
  language.country_code = ''
44
44
  language.save
45
- page.reload; page.language_code.should == "kl"
45
+ page.reload; expect(page.language_code).to eq("kl")
46
46
  end
47
47
  end
48
48
  end
@@ -57,7 +57,7 @@ module Alchemy
57
57
  default_language
58
58
  language.update_attributes(default: true)
59
59
  default_language.reload
60
- default_language.default.should be_false
60
+ expect(default_language.default).to be_falsey
61
61
  end
62
62
  end
63
63
  end
@@ -68,7 +68,7 @@ module Alchemy
68
68
  @other_page = FactoryGirl.create(:page, language: language)
69
69
  language.update_attributes(code: "fo")
70
70
  language.reload; page.reload; @other_page.reload
71
- [page.language_code, @other_page.language_code].should == [language.code, language.code]
71
+ expect([page.language_code, @other_page.language_code]).to eq([language.code, language.code])
72
72
  end
73
73
  end
74
74
 
@@ -78,7 +78,7 @@ module Alchemy
78
78
  @other_page = FactoryGirl.create(:page, language: language)
79
79
  language.update_attributes(public: false)
80
80
  language.reload; page.reload; @other_page.reload
81
- [page.public?, @other_page.public?].should == [false, false]
81
+ expect([page.public?, @other_page.public?]).to eq([false, false])
82
82
  end
83
83
  end
84
84
  end
@@ -86,7 +86,7 @@ module Alchemy
86
86
  describe '.find_by_code' do
87
87
  context "with only the language code given" do
88
88
  it "should find the language" do
89
- Language.find_by_code(language.code).should == language
89
+ expect(Language.find_by_code(language.code)).to eq(language)
90
90
  end
91
91
  end
92
92
  end
@@ -106,8 +106,8 @@ module Alchemy
106
106
  describe 'presence_of_default_language' do
107
107
  context 'if no default language would exist anymore' do
108
108
  before do
109
- Language.stub(:default).and_return(language)
110
- language.stub(:default_changed?).and_return(true)
109
+ allow(Language).to receive(:default).and_return(language)
110
+ allow(language).to receive(:default_changed?).and_return(true)
111
111
  end
112
112
 
113
113
  it "should add an error to the object" do
@@ -12,10 +12,10 @@ describe Alchemy::LegacyPageUrl do
12
12
  end
13
13
 
14
14
  it 'is only valid with correct urlname format' do
15
- valid_page_url.should be_valid
15
+ expect(valid_page_url).to be_valid
16
16
  end
17
17
 
18
18
  it 'is also valid with get parameters in urlname' do
19
- page_url_with_parameters.should be_valid
19
+ expect(page_url_with_parameters).to be_valid
20
20
  end
21
21
  end
@@ -9,7 +9,7 @@ module Alchemy
9
9
 
10
10
  describe '.config' do
11
11
  it "should return the mailer config" do
12
- Config.should_receive(:get).with(:mailer)
12
+ expect(Config).to receive(:get).with(:mailer)
13
13
  Message.config
14
14
  end
15
15
  end
@@ -25,21 +25,28 @@ module Alchemy
25
25
  context "all fields defined in mailer config" do
26
26
  it "adds errors on that fields" do
27
27
  Config.get(:mailer)['validate_fields'].each do |field|
28
- expect(message).to have(1).error_on(field)
28
+ expect(message).to_not be_valid
29
+ expect(message.errors[field].size).to eq(1)
29
30
  end
30
31
  end
31
32
  end
32
33
 
33
34
  context 'field containing email in its name' do
34
35
  context "when field has a value" do
36
+ before { message.email_of_my_boss = 'wrong email format' }
37
+
35
38
  it "adds error notice (is invalid) to the field" do
36
- message.email_of_my_boss = 'wrong email format'
37
- expect(message.errors_on(:email_of_my_boss)).to include("is invalid")
39
+ expect(message).to_not be_valid
40
+ expect(message.errors[:email_of_my_boss]).to include("is invalid")
38
41
  end
39
42
  end
43
+
40
44
  context "when field is blank" do
45
+ before { message.email_of_my_boss = '' }
46
+
41
47
  it "adds error notice (can't be blank) to the field" do
42
- expect(message.errors_on(:email_of_my_boss)).to include("can't be blank")
48
+ expect(message).to_not be_valid
49
+ expect(message.errors[:email_of_my_boss]).to include("can't be blank")
43
50
  end
44
51
  end
45
52
  end
@@ -27,20 +27,22 @@ module Alchemy
27
27
 
28
28
  it "it should be possible to save." do
29
29
  contentpage.urlname = "existing_twice"
30
- contentpage.should be_valid
30
+ expect(contentpage).to be_valid
31
31
  end
32
32
  end
33
33
 
34
34
  it "should validate the page_layout" do
35
35
  contentpage.page_layout = nil
36
- contentpage.should_not be_valid
37
- contentpage.should have(1).error_on(:page_layout)
36
+ expect(contentpage).not_to be_valid
37
+ contentpage.valid?
38
+ expect(contentpage.errors[:page_layout].size).to eq(1)
38
39
  end
39
40
 
40
41
  it "should validate the parent_id" do
41
42
  contentpage.parent_id = nil
42
- contentpage.should_not be_valid
43
- contentpage.should have(1).error_on(:parent_id)
43
+ expect(contentpage).not_to be_valid
44
+ contentpage.valid?
45
+ expect(contentpage.errors[:parent_id].size).to eq(1)
44
46
  end
45
47
 
46
48
  context 'with page having same urlname' do
@@ -48,7 +50,7 @@ module Alchemy
48
50
 
49
51
  it "should not be valid" do
50
52
  contentpage.urlname = 'existing_twice'
51
- contentpage.should_not be_valid
53
+ expect(contentpage).not_to be_valid
52
54
  end
53
55
  end
54
56
 
@@ -56,19 +58,19 @@ module Alchemy
56
58
  let(:other_parent) { FactoryGirl.create(:page, parent_id: Page.root.id) }
57
59
 
58
60
  before do
59
- Config.stub(:get).and_return(true)
61
+ allow(Config).to receive(:get).and_return(true)
60
62
  with_same_urlname
61
63
  end
62
64
 
63
65
  it "should only validate urlname dependent of parent" do
64
66
  contentpage.urlname = 'existing_twice'
65
67
  contentpage.parent_id = other_parent.id
66
- contentpage.should be_valid
68
+ expect(contentpage).to be_valid
67
69
  end
68
70
 
69
71
  it "should validate urlname dependent of parent" do
70
72
  contentpage.urlname = 'existing_twice'
71
- contentpage.should_not be_valid
73
+ expect(contentpage).not_to be_valid
72
74
  end
73
75
  end
74
76
  end
@@ -81,7 +83,7 @@ module Alchemy
81
83
  end
82
84
 
83
85
  it "should be valid" do
84
- rootpage.should be_valid
86
+ expect(rootpage).to be_valid
85
87
  end
86
88
  end
87
89
 
@@ -89,7 +91,7 @@ module Alchemy
89
91
  let(:systempage) { build(:systempage) }
90
92
 
91
93
  it "should not validate the page_layout" do
92
- systempage.should be_valid
94
+ expect(systempage).to be_valid
93
95
  end
94
96
  end
95
97
 
@@ -136,13 +138,13 @@ module Alchemy
136
138
  it "should not set the title automatically if the name changed but title is not blank" do
137
139
  page.name = "My Renaming Test"
138
140
  page.save; page.reload
139
- page.title.should == "My Testpage"
141
+ expect(page.title).to eq("My Testpage")
140
142
  end
141
143
 
142
144
  it "should not automatically set the title if it changed its value" do
143
145
  page.title = "I like SEO"
144
146
  page.save; page.reload
145
- page.title.should == "I like SEO"
147
+ expect(page.title).to eq("I like SEO")
146
148
  end
147
149
  end
148
150
 
@@ -151,15 +153,15 @@ module Alchemy
151
153
  it "should store legacy url if page is not redirect to external page" do
152
154
  page.urlname = 'new-urlname'
153
155
  page.save!
154
- page.legacy_urls.should_not be_empty
155
- page.legacy_urls.first.urlname.should == 'my-testpage'
156
+ expect(page.legacy_urls).not_to be_empty
157
+ expect(page.legacy_urls.first.urlname).to eq('my-testpage')
156
158
  end
157
159
 
158
160
  it "should not store legacy url if page is redirect to external page" do
159
161
  page.urlname = 'new-urlname'
160
162
  page.page_layout = "external"
161
163
  page.save!
162
- page.legacy_urls.should be_empty
164
+ expect(page.legacy_urls).to be_empty
163
165
  end
164
166
 
165
167
  it "should not store legacy url twice for same urlname" do
@@ -169,7 +171,7 @@ module Alchemy
169
171
  page.save!
170
172
  page.urlname = 'another-urlname'
171
173
  page.save!
172
- page.legacy_urls.select { |u| u.urlname == 'my-testpage' }.size.should == 1
174
+ expect(page.legacy_urls.select { |u| u.urlname == 'my-testpage' }.size).to eq(1)
173
175
  end
174
176
  end
175
177
 
@@ -177,7 +179,7 @@ module Alchemy
177
179
  it "should not store a legacy url" do
178
180
  page.urlname = 'my-testpage'
179
181
  page.save!
180
- page.legacy_urls.should be_empty
182
+ expect(page.legacy_urls).to be_empty
181
183
  end
182
184
  end
183
185
 
@@ -199,7 +201,7 @@ module Alchemy
199
201
  context "public has not changed" do
200
202
  it "should not update published_at" do
201
203
  page.update_attributes!(name: 'New Name')
202
- page.read_attribute(:published_at).should be_nil
204
+ expect(page.read_attribute(:published_at)).to be_nil
203
205
  end
204
206
  end
205
207
  end
@@ -210,9 +212,9 @@ module Alchemy
210
212
  let(:page) { FactoryGirl.create(:page, parent_id: parent_1.id, name: 'Page', visible: true) }
211
213
 
212
214
  it "updates the urlname" do
213
- page.urlname.should == 'parent-1/page'
215
+ expect(page.urlname).to eq('parent-1/page')
214
216
  page.move_to_child_of parent_2
215
- page.urlname.should == 'parent-2/page'
217
+ expect(page.urlname).to eq('parent-2/page')
216
218
  end
217
219
 
218
220
  context 'of an external page' do
@@ -220,7 +222,7 @@ module Alchemy
220
222
 
221
223
  it "the urlname does not get updated" do
222
224
  external.move_to_child_of parent_2
223
- external.urlname.should == 'http://google.com'
225
+ expect(external.urlname).to eq('http://google.com')
224
226
  end
225
227
  end
226
228
  end
@@ -232,36 +234,36 @@ module Alchemy
232
234
 
233
235
  it "should set the language code" do
234
236
  @page.save
235
- @page.language_code.should == "kl"
237
+ expect(@page.language_code).to eq("kl")
236
238
  end
237
239
 
238
240
  it "should autogenerate the elements" do
239
241
  @page.save
240
- @page.elements.should_not be_empty
242
+ expect(@page.elements).not_to be_empty
241
243
  end
242
244
 
243
245
  it "should not autogenerate elements that are already on the page" do
244
246
  @page.elements << FactoryGirl.create(:element, :name => 'header')
245
247
  @page.save
246
- @page.elements.select { |e| e.name == 'header' }.length.should == 1
248
+ expect(@page.elements.select { |e| e.name == 'header' }.length).to eq(1)
247
249
  end
248
250
 
249
251
  context "with cells" do
250
252
  before do
251
- @page.stub(:definition).and_return({'name' => 'with_cells', 'cells' => ['header', 'main']})
253
+ allow(@page).to receive(:definition).and_return({'name' => 'with_cells', 'cells' => ['header', 'main']})
252
254
  end
253
255
 
254
256
  it "should have the generated elements in their cells" do
255
- @page.stub(:cell_definitions).and_return([{'name' => 'header', 'elements' => ['article']}])
257
+ allow(@page).to receive(:cell_definitions).and_return([{'name' => 'header', 'elements' => ['article']}])
256
258
  @page.save
257
- @page.cells.where(:name => 'header').first.elements.should_not be_empty
259
+ expect(@page.cells.where(:name => 'header').first.elements).not_to be_empty
258
260
  end
259
261
 
260
262
  context "and no elements in cell definitions" do
261
263
  it "should have the elements in the nil cell" do
262
- @page.stub(:cell_definitions).and_return([{'name' => 'header', 'elements' => []}])
264
+ allow(@page).to receive(:cell_definitions).and_return([{'name' => 'header', 'elements' => []}])
263
265
  @page.save
264
- @page.cells.collect(&:elements).flatten.should be_empty
266
+ expect(@page.cells.collect(&:elements).flatten).to be_empty
265
267
  end
266
268
  end
267
269
  end
@@ -277,7 +279,7 @@ module Alchemy
277
279
 
278
280
  it "should restrict all its children" do
279
281
  @child1.reload
280
- @child1.restricted?.should be_true
282
+ expect(@child1.restricted?).to be_truthy
281
283
  end
282
284
  end
283
285
 
@@ -289,7 +291,7 @@ module Alchemy
289
291
  end
290
292
 
291
293
  it "should also be restricted" do
292
- @new_page.restricted?.should be_true
294
+ expect(@new_page.restricted?).to be_truthy
293
295
  end
294
296
  end
295
297
 
@@ -300,7 +302,7 @@ module Alchemy
300
302
 
301
303
  it "should not autogenerate the elements" do
302
304
  @page.save
303
- @page.elements.should be_empty
305
+ expect(@page.elements).to be_empty
304
306
  end
305
307
  end
306
308
  end
@@ -311,11 +313,11 @@ module Alchemy
311
313
  end
312
314
 
313
315
  it "should not get the language code for language" do
314
- @page.language_code.should be_nil
316
+ expect(@page.language_code).to be_nil
315
317
  end
316
318
 
317
319
  it "should not autogenerate the elements" do
318
- @page.elements.should be_empty
320
+ expect(@page.elements).to be_empty
319
321
  end
320
322
  end
321
323
 
@@ -332,7 +334,7 @@ module Alchemy
332
334
 
333
335
  it "should autogenerate elements" do
334
336
  news_page.update_attributes(page_layout: 'contact')
335
- news_page.elements.pluck(:name).should include('contactform')
337
+ expect(news_page.elements.pluck(:name)).to include('contactform')
336
338
  end
337
339
  end
338
340
  end
@@ -349,7 +351,7 @@ module Alchemy
349
351
  {'id' => page_1.id.to_s, 'action' => 'copy'},
350
352
  {'id' => page_2.id.to_s, 'action' => 'copy'}
351
353
  ]
352
- Page.all_from_clipboard_for_select(clipboard, language.id).should include(page_1, page_2)
354
+ expect(Page.all_from_clipboard_for_select(clipboard, language.id)).to include(page_1, page_2)
353
355
  end
354
356
  end
355
357
 
@@ -359,7 +361,7 @@ module Alchemy
359
361
  clipboard = [
360
362
  {'id' => page_1.id.to_s, 'action' => 'copy'}
361
363
  ]
362
- Page.all_from_clipboard_for_select(clipboard, language.id).should == []
364
+ expect(Page.all_from_clipboard_for_select(clipboard, language.id)).to eq([])
363
365
  end
364
366
  end
365
367
 
@@ -371,7 +373,7 @@ module Alchemy
371
373
  {'id' => page_1.id.to_s, 'action' => 'copy'},
372
374
  {'id' => page_2.id.to_s, 'action' => 'copy'}
373
375
  ]
374
- Page.all_from_clipboard_for_select(clipboard, language.id).should == [page_1]
376
+ expect(Page.all_from_clipboard_for_select(clipboard, language.id)).to eq([page_1])
375
377
  end
376
378
  end
377
379
  end
@@ -379,7 +381,7 @@ module Alchemy
379
381
  describe '.all_locked' do
380
382
  it "should return 1 page that is blocked by a user at the moment" do
381
383
  FactoryGirl.create(:public_page, :locked => true, :name => 'First Public Child', :parent_id => language_root.id, :language => language)
382
- Page.all_locked.should have(1).pages
384
+ expect(Page.all_locked.size).to eq(1)
383
385
  end
384
386
  end
385
387
 
@@ -392,15 +394,15 @@ module Alchemy
392
394
  end
393
395
 
394
396
  it "should return a collection of contentpages" do
395
- Page.contentpages.to_a.should include(language_root, @klingonian_lang_root, @contentpage)
397
+ expect(Page.contentpages.to_a).to include(language_root, @klingonian_lang_root, @contentpage)
396
398
  end
397
399
 
398
400
  it "should not contain pages with attribute :layoutpage set to true" do
399
- Page.contentpages.to_a.select { |p| p.layoutpage == true }.should be_empty
401
+ expect(Page.contentpages.to_a.select { |p| p.layoutpage == true }).to be_empty
400
402
  end
401
403
 
402
404
  it "should contain pages with attribute :layoutpage set to nil" do
403
- Page.contentpages.to_a.select { |p| p.layoutpage == nil }.should include(@klingonian_lang_root)
405
+ expect(Page.contentpages.to_a.select { |p| p.layoutpage == nil }).to include(@klingonian_lang_root)
404
406
  end
405
407
  end
406
408
 
@@ -409,7 +411,7 @@ module Alchemy
409
411
  subject { Page.copy(page) }
410
412
 
411
413
  it "the copy should have added (copy) to name" do
412
- subject.name.should == "#{page.name} (Copy)"
414
+ expect(subject.name).to eq("#{page.name} (Copy)")
413
415
  end
414
416
 
415
417
  context "page with tags" do
@@ -419,8 +421,8 @@ module Alchemy
419
421
  # The order of tags varies between postgresql and sqlite/mysql
420
422
  # This is related to acts-as-taggable-on v.2.4.1
421
423
  # To fix the spec we sort the tags until the issue is solved (https://github.com/mbleigh/acts-as-taggable-on/issues/363)
422
- subject.tag_list.should_not be_empty
423
- subject.tag_list.sort.should == page.tag_list.sort
424
+ expect(subject.tag_list).not_to be_empty
425
+ expect(subject.tag_list.sort).to eq(page.tag_list.sort)
424
426
  end
425
427
  end
426
428
 
@@ -428,8 +430,8 @@ module Alchemy
428
430
  before { page.elements << FactoryGirl.create(:element) }
429
431
 
430
432
  it "the copy should have source elements" do
431
- subject.elements.should_not be_empty
432
- subject.elements.count.should == page.elements.count
433
+ expect(subject.elements).not_to be_empty
434
+ expect(subject.elements.count).to eq(page.elements.count)
433
435
  end
434
436
  end
435
437
 
@@ -440,7 +442,7 @@ module Alchemy
440
442
  end
441
443
 
442
444
  it "the copy should not hold a copy of the trashed elements" do
443
- subject.elements.should be_empty
445
+ expect(subject.elements).to be_empty
444
446
  end
445
447
  end
446
448
 
@@ -448,26 +450,26 @@ module Alchemy
448
450
  before { page.cells << FactoryGirl.create(:cell) }
449
451
 
450
452
  it "the copy should have source cells" do
451
- subject.cells.should_not be_empty
452
- subject.cells.count.should == page.cells.length # It must be length, because!
453
+ expect(subject.cells).not_to be_empty
454
+ expect(subject.cells.count).to eq(page.cells.length) # It must be length, because!
453
455
  end
454
456
  end
455
457
 
456
458
  context "page with autogenerate elements" do
457
459
  before do
458
460
  page = FactoryGirl.create(:page)
459
- page.stub(:definition).and_return({'name' => 'standard', 'elements' => ['headline'], 'autogenerate' => ['headline']})
461
+ allow(page).to receive(:definition).and_return({'name' => 'standard', 'elements' => ['headline'], 'autogenerate' => ['headline']})
460
462
  end
461
463
 
462
464
  it "the copy should not autogenerate elements" do
463
- subject.elements.should be_empty
465
+ expect(subject.elements).to be_empty
464
466
  end
465
467
  end
466
468
 
467
469
  context "with different page name given" do
468
470
  subject { Page.copy(page, {:name => 'Different name'}) }
469
471
  it "should take this name" do
470
- subject.name.should == 'Different name'
472
+ expect(subject.name).to eq('Different name')
471
473
  end
472
474
  end
473
475
  end
@@ -476,12 +478,12 @@ module Alchemy
476
478
  context "before/after filter" do
477
479
  it "should automatically set the title from its name" do
478
480
  page = FactoryGirl.create(:page, :name => 'My Testpage', :language => language, :parent_id => language_root.id)
479
- page.title.should == 'My Testpage'
481
+ expect(page.title).to eq('My Testpage')
480
482
  end
481
483
 
482
484
  it "should get a webfriendly urlname" do
483
485
  page = FactoryGirl.create(:page, :name => 'klingon$&stößel ', :language => language, :parent_id => language_root.id)
484
- page.urlname.should == 'klingon-stoessel'
486
+ expect(page.urlname).to eq('klingon-stoessel')
485
487
  end
486
488
 
487
489
  context "with no name set" do
@@ -493,34 +495,34 @@ module Alchemy
493
495
 
494
496
  it "should generate a three letter urlname from two letter name" do
495
497
  page = FactoryGirl.create(:page, :name => 'Au', :language => language, :parent_id => language_root.id)
496
- page.urlname.should == '-au'
498
+ expect(page.urlname).to eq('-au')
497
499
  end
498
500
 
499
501
  it "should generate a three letter urlname from two letter name with umlaut" do
500
502
  page = FactoryGirl.create(:page, :name => 'Aü', :language => language, :parent_id => language_root.id)
501
- page.urlname.should == 'aue'
503
+ expect(page.urlname).to eq('aue')
502
504
  end
503
505
 
504
506
  it "should generate a three letter urlname from one letter name" do
505
507
  page = FactoryGirl.create(:page, :name => 'A', :language => language, :parent_id => language_root.id)
506
- page.urlname.should == '--a'
508
+ expect(page.urlname).to eq('--a')
507
509
  end
508
510
 
509
511
  it "should add a user stamper" do
510
512
  page = FactoryGirl.create(:page, :name => 'A', :language => language, :parent_id => language_root.id)
511
- page.class.stamper_class.to_s.should == 'DummyUser'
513
+ expect(page.class.stamper_class.to_s).to eq('DummyUser')
512
514
  end
513
515
 
514
516
  context "with language given" do
515
517
  it "does not set the language from parent" do
516
- Page.any_instance.should_not_receive(:set_language_from_parent_or_default)
518
+ expect_any_instance_of(Page).not_to receive(:set_language_from_parent_or_default)
517
519
  Page.create!(name: 'A', parent_id: language_root.id, page_layout: 'standard', language: language)
518
520
  end
519
521
  end
520
522
 
521
523
  context "with no language given" do
522
524
  it "sets the language from parent" do
523
- Page.any_instance.should_receive(:set_language_from_parent_or_default)
525
+ expect_any_instance_of(Page).to receive(:set_language_from_parent_or_default)
524
526
  Page.create!(name: 'A', parent_id: language_root.id, page_layout: 'standard')
525
527
  end
526
528
  end
@@ -533,15 +535,15 @@ module Alchemy
533
535
  let(:language) { mock_model('Language', name: 'English') }
534
536
  let(:language_id) { language.id }
535
537
 
536
- before { Language.stub(:find).and_return(language) }
538
+ before { allow(Language).to receive(:find).and_return(language) }
537
539
 
538
540
  context 'if no layout root page for given language id could be found' do
539
541
  before do
540
- Page.should_receive(:create!).and_return(page)
542
+ expect(Page).to receive(:create!).and_return(page)
541
543
  end
542
544
 
543
545
  it "creates one" do
544
- should eq(page)
546
+ is_expected.to eq(page)
545
547
  end
546
548
  end
547
549
 
@@ -549,11 +551,11 @@ module Alchemy
549
551
  let(:page) { mock_model('Page') }
550
552
 
551
553
  before do
552
- Page.should_receive(:layout_root_for).and_return(page)
554
+ expect(Page).to receive(:layout_root_for).and_return(page)
553
555
  end
554
556
 
555
557
  it "returns layout root page" do
556
- should eq(page)
558
+ is_expected.to eq(page)
557
559
  end
558
560
  end
559
561
  end
@@ -561,7 +563,7 @@ module Alchemy
561
563
  describe '.language_roots' do
562
564
  it "should return 1 language_root" do
563
565
  FactoryGirl.create(:public_page, :name => 'First Public Child', :parent_id => language_root.id, :language => language)
564
- Page.language_roots.should have(1).pages
566
+ expect(Page.language_roots.size).to eq(1)
565
567
  end
566
568
  end
567
569
 
@@ -572,11 +574,11 @@ module Alchemy
572
574
 
573
575
  context "for a language root page" do
574
576
  it "should return the page layout description as hash" do
575
- language_root.layout_description['name'].should == 'intro'
577
+ expect(language_root.layout_description['name']).to eq('intro')
576
578
  end
577
579
 
578
580
  it "should return an empty hash for root page" do
579
- rootpage.layout_description.should == {}
581
+ expect(rootpage.layout_description).to eq({})
580
582
  end
581
583
  end
582
584
  end
@@ -584,7 +586,7 @@ module Alchemy
584
586
  describe '.layoutpages' do
585
587
  it "should return 1 layoutpage" do
586
588
  FactoryGirl.create(:public_page, :layoutpage => true, :name => 'Layoutpage', :parent_id => rootpage.id, :language => language)
587
- Page.layoutpages.should have(1).pages
589
+ expect(Page.layoutpages.size).to eq(1)
588
590
  end
589
591
  end
590
592
 
@@ -592,14 +594,14 @@ module Alchemy
592
594
  it "should return pages that are not blocked by a user at the moment" do
593
595
  FactoryGirl.create(:public_page, :locked => true, :name => 'First Public Child', :parent_id => language_root.id, :language => language)
594
596
  FactoryGirl.create(:public_page, :name => 'Second Public Child', :parent_id => language_root.id, :language => language)
595
- Page.not_locked.should have(3).pages
597
+ expect(Page.not_locked.size).to eq(3)
596
598
  end
597
599
  end
598
600
 
599
601
  describe '.not_restricted' do
600
602
  it "should return 2 accessible pages" do
601
603
  FactoryGirl.create(:public_page, :name => 'First Public Child', :restricted => true, :parent_id => language_root.id, :language => language)
602
- Page.not_restricted.should have(2).pages
604
+ expect(Page.not_restricted.size).to eq(2)
603
605
  end
604
606
  end
605
607
 
@@ -607,27 +609,27 @@ module Alchemy
607
609
  it "should return pages that are public" do
608
610
  FactoryGirl.create(:public_page, :name => 'First Public Child', :parent_id => language_root.id, :language => language)
609
611
  FactoryGirl.create(:public_page, :name => 'Second Public Child', :parent_id => language_root.id, :language => language)
610
- Page.published.should have(3).pages
612
+ expect(Page.published.size).to eq(3)
611
613
  end
612
614
  end
613
615
 
614
616
  describe '.restricted' do
615
617
  it "should return 1 restricted page" do
616
618
  FactoryGirl.create(:public_page, :name => 'First Public Child', :restricted => true, :parent_id => language_root.id, :language => language)
617
- Page.restricted.should have(1).pages
619
+ expect(Page.restricted.size).to eq(1)
618
620
  end
619
621
  end
620
622
 
621
623
  describe '.rootpage' do
622
624
  it "should contain one rootpage" do
623
- Page.rootpage.should be_instance_of(Page)
625
+ expect(Page.rootpage).to be_instance_of(Page)
624
626
  end
625
627
  end
626
628
 
627
629
  describe '.visible' do
628
630
  it "should return 1 visible page" do
629
631
  FactoryGirl.create(:public_page, :name => 'First Public Child', :visible => true, :parent_id => language_root.id, :language => language)
630
- Page.visible.should have(1).pages
632
+ expect(Page.visible.size).to eq(1)
631
633
  end
632
634
  end
633
635
 
@@ -638,17 +640,22 @@ module Alchemy
638
640
  let(:page) { FactoryGirl.build_stubbed(:public_page) }
639
641
 
640
642
  it "returns all element definitions of available elements" do
641
- page.available_element_definitions.should be_an(Array)
642
- page.available_element_definitions.collect { |e| e['name'] }.should include('header')
643
+ expect(page.available_element_definitions).to be_an(Array)
644
+ expect(page.available_element_definitions.collect { |e| e['name'] }).to include('header')
643
645
  end
644
646
 
645
647
  context "with unique elements already on page" do
646
648
  let(:element) { FactoryGirl.build_stubbed(:unique_element) }
647
- before { page.stub_chain(:elements, :not_trashed, :pluck).and_return([element.name]) }
649
+
650
+ before do
651
+ allow(page)
652
+ .to receive(:elements)
653
+ .and_return double(not_trashed: double(pluck: [element.name]))
654
+ end
648
655
 
649
656
  it "does not return unique element definitions" do
650
- page.available_element_definitions.collect { |e| e['name'] }.should include('article')
651
- page.available_element_definitions.collect { |e| e['name'] }.should_not include('header')
657
+ expect(page.available_element_definitions.collect { |e| e['name'] }).to include('article')
658
+ expect(page.available_element_definitions.collect { |e| e['name'] }).not_to include('header')
652
659
  end
653
660
  end
654
661
 
@@ -670,7 +677,7 @@ module Alchemy
670
677
  let(:element_3) { FactoryGirl.build_stubbed(:element, name: 'column_headline') }
671
678
 
672
679
  before {
673
- Element.stub(:definitions).and_return([
680
+ allow(Element).to receive(:definitions).and_return([
674
681
  {
675
682
  'name' => 'column_headline',
676
683
  'amount' => 3,
@@ -683,25 +690,32 @@ module Alchemy
683
690
  'contents' => [{'name' => 'headline', 'type' => 'EssenceText'}]
684
691
  }
685
692
  ])
686
- PageLayout.stub(:get).and_return({
693
+ allow(PageLayout).to receive(:get).and_return({
687
694
  'name' => 'columns',
688
695
  'elements' => ['column_headline', 'unique_headline'],
689
696
  'autogenerate' => ['unique_headline', 'column_headline', 'column_headline', 'column_headline']
690
697
  })
691
- page.stub_chain(:elements, :not_trashed, :pluck).and_return([unique_element.name, element_1.name, element_2.name, element_3.name])
698
+ allow(page).to receive(:elements).and_return double(
699
+ not_trashed: double(pluck: [
700
+ unique_element.name,
701
+ element_1.name,
702
+ element_2.name,
703
+ element_3.name
704
+ ])
705
+ )
692
706
  }
693
707
 
694
708
  it "should be readable" do
695
709
  element = page.element_definitions_by_name('column_headline').first
696
- element['amount'].should be 3
710
+ expect(element['amount']).to be 3
697
711
  end
698
712
 
699
713
  it "should limit elements" do
700
- page.available_element_definitions.collect { |e| e['name'] }.should_not include('column_headline')
714
+ expect(page.available_element_definitions.collect { |e| e['name'] }).not_to include('column_headline')
701
715
  end
702
716
 
703
717
  it "should be ignored if unique" do
704
- page.available_element_definitions.collect { |e| e['name'] }.should_not include('unique_headline')
718
+ expect(page.available_element_definitions.collect { |e| e['name'] }).not_to include('unique_headline')
705
719
  end
706
720
  end
707
721
  end
@@ -715,44 +729,30 @@ module Alchemy
715
729
  end
716
730
 
717
731
  describe '#cache_key' do
718
- let(:page) do
719
- stub_model(Page, updated_at: Time.now, published_at: Time.now - 1.week)
720
- end
721
-
722
- subject { page.cache_key }
723
-
724
- before do
725
- expect(Page).to receive(:current_preview).and_return(preview)
726
- end
727
-
728
- context "when current page rendered in preview mode" do
729
- let(:preview) { page }
730
-
731
- it { is_expected.to eq("alchemy/pages/#{page.id}-#{page.updated_at}") }
732
- end
733
-
734
- context "when current page not in preview mode" do
735
- let(:preview) { nil }
732
+ let(:page) { stub_model(Page) }
733
+ subject { page }
736
734
 
737
- it { is_expected.to eq("alchemy/pages/#{page.id}-#{page.published_at}") }
735
+ describe '#cache_key' do
736
+ subject { super().cache_key }
737
+ it { is_expected.to match(page.id.to_s) }
738
738
  end
739
739
  end
740
740
 
741
741
  describe '#cell_definitions' do
742
742
  before do
743
743
  @page = FactoryGirl.build(:page, :page_layout => 'foo')
744
- @page.stub(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"]})
744
+ allow(@page).to receive(:layout_description).and_return({'name' => "foo", 'cells' => ["foo_cell"]})
745
745
  @cell_descriptions = [{'name' => "foo_cell", 'elements' => ["1", "2"]}]
746
- Cell.stub(:definitions).and_return(@cell_descriptions)
746
+ allow(Cell).to receive(:definitions).and_return(@cell_descriptions)
747
747
  end
748
748
 
749
749
  it "should return all cell definitions for its page_layout" do
750
- @page.cell_definitions.should == @cell_descriptions
750
+ expect(@page.cell_definitions).to eq(@cell_descriptions)
751
751
  end
752
752
 
753
753
  it "should return empty array if no cells defined in page layout" do
754
- @page.stub(:layout_description).and_return({'name' => "foo"})
755
- @page.cell_definitions.should == []
754
+ allow(@page).to receive(:layout_description).and_return({'name' => "foo"})
755
+ expect(@page.cell_definitions).to eq([])
756
756
  end
757
757
  end
758
758
 
@@ -762,7 +762,7 @@ module Alchemy
762
762
 
763
763
  it "should not delete the trashed elements" do
764
764
  news_page.destroy
765
- Element.trashed.should_not be_empty
765
+ expect(Element.trashed).not_to be_empty
766
766
  end
767
767
  end
768
768
  end
@@ -770,22 +770,22 @@ module Alchemy
770
770
  describe '#element_definitions' do
771
771
  let(:page) { FactoryGirl.build_stubbed(:page) }
772
772
  subject { page.element_definitions }
773
- before { Element.should_receive(:definitions).and_return([{'name' => 'article'}, {'name' => 'header'}]) }
773
+ before { expect(Element).to receive(:definitions).and_return([{'name' => 'article'}, {'name' => 'header'}]) }
774
774
 
775
775
  it "returns all element definitions that could be placed on current page" do
776
- should include({'name' => 'article'})
777
- should include({'name' => 'header'})
776
+ is_expected.to include({'name' => 'article'})
777
+ is_expected.to include({'name' => 'header'})
778
778
  end
779
779
  end
780
780
 
781
781
  describe '#element_definitions' do
782
782
  let(:page) { FactoryGirl.build_stubbed(:page) }
783
783
  subject { page.element_definitions }
784
- before { Element.should_receive(:definitions).and_return([{'name' => 'article'}, {'name' => 'header'}]) }
784
+ before { expect(Element).to receive(:definitions).and_return([{'name' => 'article'}, {'name' => 'header'}]) }
785
785
 
786
786
  it "returns all element definitions that could be placed on current page" do
787
- should include({'name' => 'article'})
788
- should include({'name' => 'header'})
787
+ is_expected.to include({'name' => 'article'})
788
+ is_expected.to include({'name' => 'header'})
789
789
  end
790
790
  end
791
791
 
@@ -794,20 +794,20 @@ module Alchemy
794
794
 
795
795
  context "with no name given" do
796
796
  it "returns empty array" do
797
- page.element_definitions_by_name(nil).should == []
797
+ expect(page.element_definitions_by_name(nil)).to eq([])
798
798
  end
799
799
  end
800
800
 
801
801
  context "with 'all' passed as name" do
802
802
  it "returns all element definitions" do
803
- Element.should_receive(:definitions)
803
+ expect(Element).to receive(:definitions)
804
804
  page.element_definitions_by_name('all')
805
805
  end
806
806
  end
807
807
 
808
808
  context "with :all passed as name" do
809
809
  it "returns all element definitions" do
810
- Element.should_receive(:definitions)
810
+ expect(Element).to receive(:definitions)
811
811
  page.element_definitions_by_name(:all)
812
812
  end
813
813
  end
@@ -817,12 +817,12 @@ module Alchemy
817
817
  let(:page) { FactoryGirl.build_stubbed(:public_page) }
818
818
 
819
819
  it "returns all element names defined in page layout" do
820
- page.element_definition_names.should == %w(article header)
820
+ expect(page.element_definition_names).to eq(%w(article header))
821
821
  end
822
822
 
823
823
  it "returns always an array" do
824
- page.stub(:definition).and_return({})
825
- page.element_definition_names.should be_an(Array)
824
+ allow(page).to receive(:definition).and_return({})
825
+ expect(page.element_definition_names).to be_an(Array)
826
826
  end
827
827
  end
828
828
 
@@ -830,13 +830,13 @@ module Alchemy
830
830
  let(:page) { FactoryGirl.create(:public_page, :do_not_autogenerate => false) }
831
831
 
832
832
  before do
833
- PageLayout.stub(:get).and_return({
833
+ allow(PageLayout).to receive(:get).and_return({
834
834
  'name' => 'standard',
835
835
  'cells' => ['header'],
836
836
  'elements' => ['header', 'text'],
837
837
  'autogenerate' => ['header', 'text']
838
838
  })
839
- Cell.stub(:definitions).and_return([{
839
+ allow(Cell).to receive(:definitions).and_return([{
840
840
  'name' => "header",
841
841
  'elements' => ["header"]
842
842
  }])
@@ -844,19 +844,19 @@ module Alchemy
844
844
 
845
845
  it "should return elements grouped by cell" do
846
846
  elements = page.elements_grouped_by_cells
847
- elements.keys.first.should be_instance_of(Cell)
848
- elements.values.first.first.should be_instance_of(Element)
847
+ expect(elements.keys.first).to be_instance_of(Cell)
848
+ expect(elements.values.first.first).to be_instance_of(Element)
849
849
  end
850
850
 
851
851
  it "should only include elements beeing in a cell " do
852
- page.elements_grouped_by_cells.keys.should_not include(nil)
852
+ expect(page.elements_grouped_by_cells.keys).not_to include(nil)
853
853
  end
854
854
  end
855
855
 
856
856
  describe '#feed_elements' do
857
857
  it "should return all rss feed elements" do
858
- news_page.feed_elements.should_not be_empty
859
- news_page.feed_elements.should == Element.where(name: 'news').to_a
858
+ expect(news_page.feed_elements).not_to be_empty
859
+ expect(news_page.feed_elements).to eq(Element.where(name: 'news').to_a)
860
860
  end
861
861
  end
862
862
 
@@ -868,23 +868,23 @@ module Alchemy
868
868
 
869
869
  context "with show_non_public argument TRUE" do
870
870
  it "should return all elements from empty options" do
871
- public_page.find_elements({}, true).to_a.should == public_page.elements.to_a
871
+ expect(public_page.find_elements({}, true).to_a).to eq(public_page.elements.to_a)
872
872
  end
873
873
 
874
874
  it "should only return the elements passed as options[:only]" do
875
- public_page.find_elements({:only => ['article']}, true).to_a.should == public_page.elements.named('article').to_a
875
+ expect(public_page.find_elements({:only => ['article']}, true).to_a).to eq(public_page.elements.named('article').to_a)
876
876
  end
877
877
 
878
878
  it "should not return the elements passed as options[:except]" do
879
- public_page.find_elements({:except => ['article']}, true).to_a.should == public_page.elements - public_page.elements.named('article').to_a
879
+ expect(public_page.find_elements({:except => ['article']}, true).to_a).to eq(public_page.elements - public_page.elements.named('article').to_a)
880
880
  end
881
881
 
882
882
  it "should return elements offsetted" do
883
- public_page.find_elements({:offset => 2}, true).to_a.should == public_page.elements.offset(2)
883
+ expect(public_page.find_elements({:offset => 2}, true).to_a).to eq(public_page.elements.offset(2))
884
884
  end
885
885
 
886
886
  it "should return elements limitted in count" do
887
- public_page.find_elements({:count => 1}, true).to_a.should == public_page.elements.limit(1)
887
+ expect(public_page.find_elements({:count => 1}, true).to_a).to eq(public_page.elements.limit(1))
888
888
  end
889
889
  end
890
890
 
@@ -892,29 +892,34 @@ module Alchemy
892
892
  let(:element) { FactoryGirl.build_stubbed(:element) }
893
893
 
894
894
  context "given as String" do
895
- context '' do
896
- before {
897
- public_page.cells.stub_chain(:find_by_name, :elements, :offset, :limit, :published).and_return([element])
898
- }
895
+ context 'with elements present' do
896
+ before do
897
+ expect(public_page.cells)
898
+ .to receive(:find_by_name)
899
+ .and_return double(elements: double(offset: double(limit: double(published: [element]))))
900
+ end
899
901
 
900
902
  it "returns only the elements from given cell" do
901
- public_page.find_elements(from_cell: 'A Cell').to_a.should == [element]
903
+ expect(public_page.find_elements(from_cell: 'A Cell').to_a).to eq([element])
902
904
  end
903
905
  end
904
906
 
905
907
  context "that can not be found" do
906
908
  let(:elements) {[]}
907
- before {
908
- elements.stub_chain(:offset, :limit, :published).and_return([])
909
- }
909
+
910
+ before do
911
+ allow(elements)
912
+ .to receive(:offset)
913
+ .and_return double(limit: double(published: elements))
914
+ end
910
915
 
911
916
  it "returns empty set" do
912
- Element.should_receive(:none).and_return(elements)
913
- public_page.find_elements(from_cell: 'Lolo').to_a.should == []
917
+ expect(Element).to receive(:none).and_return(elements)
918
+ expect(public_page.find_elements(from_cell: 'Lolo').to_a).to eq([])
914
919
  end
915
920
 
916
921
  it "loggs a warning" do
917
- Rails.logger.should_receive(:debug)
922
+ expect(Rails.logger).to receive(:debug)
918
923
  public_page.find_elements(from_cell: 'Lolo')
919
924
  end
920
925
  end
@@ -924,31 +929,34 @@ module Alchemy
924
929
  let(:cell) { FactoryGirl.build_stubbed(:cell, page: public_page) }
925
930
 
926
931
  it "returns only the elements from given cell" do
927
- cell.stub_chain(:elements, :offset, :limit, :published).and_return([element])
928
- public_page.find_elements(from_cell: cell).to_a.should == [element]
932
+ expect(cell)
933
+ .to receive(:elements)
934
+ .and_return double(offset: double(limit: double(published: [element])))
935
+
936
+ expect(public_page.find_elements(from_cell: cell).to_a).to eq([element])
929
937
  end
930
938
  end
931
939
  end
932
940
 
933
941
  context "with show_non_public argument FALSE" do
934
942
  it "should return all elements from empty arguments" do
935
- public_page.find_elements().to_a.should == public_page.elements.published.to_a
943
+ expect(public_page.find_elements().to_a).to eq(public_page.elements.published.to_a)
936
944
  end
937
945
 
938
946
  it "should only return the public elements passed as options[:only]" do
939
- public_page.find_elements(:only => ['article']).to_a.should == public_page.elements.published.named('article').to_a
947
+ expect(public_page.find_elements(:only => ['article']).to_a).to eq(public_page.elements.published.named('article').to_a)
940
948
  end
941
949
 
942
950
  it "should return all public elements except the ones passed as options[:except]" do
943
- public_page.find_elements(:except => ['article']).to_a.should == public_page.elements.published.to_a - public_page.elements.published.named('article').to_a
951
+ expect(public_page.find_elements(:except => ['article']).to_a).to eq(public_page.elements.published.to_a - public_page.elements.published.named('article').to_a)
944
952
  end
945
953
 
946
954
  it "should return elements offsetted" do
947
- public_page.find_elements({:offset => 2}).to_a.should == public_page.elements.published.offset(2)
955
+ expect(public_page.find_elements({:offset => 2}).to_a).to eq(public_page.elements.published.offset(2))
948
956
  end
949
957
 
950
958
  it "should return elements limitted in count" do
951
- public_page.find_elements({:count => 1}).to_a.should == public_page.elements.published.limit(1)
959
+ expect(public_page.find_elements({:count => 1}).to_a).to eq(public_page.elements.published.limit(1))
952
960
  end
953
961
  end
954
962
  end
@@ -960,11 +968,11 @@ module Alchemy
960
968
 
961
969
  it "should return first_public_child" do
962
970
  first_public_child = FactoryGirl.create(:public_page, :name => "First public child", :language => language, :parent_id => language_root.id)
963
- language_root.first_public_child.should == first_public_child
971
+ expect(language_root.first_public_child).to eq(first_public_child)
964
972
  end
965
973
 
966
974
  it "should return nil if no public child exists" do
967
- language_root.first_public_child.should == nil
975
+ expect(language_root.first_public_child).to eq(nil)
968
976
  end
969
977
  end
970
978
 
@@ -985,12 +993,14 @@ module Alchemy
985
993
 
986
994
  context 'with user is a active record model' do
987
995
  before do
988
- Alchemy.user_class.should_receive(:'<').and_return(true)
996
+ expect(Alchemy.user_class).to receive(:'<').and_return(true)
989
997
  end
990
998
 
991
999
  context 'if page is folded' do
992
1000
  before do
993
- page.stub_chain(:folded_pages, :where, :any?).and_return(true)
1001
+ expect(page)
1002
+ .to receive(:folded_pages)
1003
+ .and_return double(where: double(any?: true))
994
1004
  end
995
1005
 
996
1006
  it "should return true" do
@@ -1008,10 +1018,11 @@ module Alchemy
1008
1018
  end
1009
1019
 
1010
1020
  describe '#get_language_root' do
1021
+ before { language_root }
1011
1022
  subject { public_page.get_language_root }
1012
1023
 
1013
1024
  it "returns the language root page" do
1014
- should eq language_root
1025
+ is_expected.to eq language_root
1015
1026
  end
1016
1027
  end
1017
1028
 
@@ -1022,7 +1033,7 @@ module Alchemy
1022
1033
  it "should set locked to true" do
1023
1034
  page.lock_to!(user)
1024
1035
  page.reload
1025
- page.locked.should == true
1036
+ expect(page.locked).to eq(true)
1026
1037
  end
1027
1038
 
1028
1039
  it "should not update the timestamps " do
@@ -1032,7 +1043,7 @@ module Alchemy
1032
1043
  it "should set locked_by to the users id" do
1033
1044
  page.lock_to!(user)
1034
1045
  page.reload
1035
- page.locked_by.should == user.id
1046
+ expect(page.locked_by).to eq(user.id)
1036
1047
  end
1037
1048
  end
1038
1049
 
@@ -1045,7 +1056,7 @@ module Alchemy
1045
1056
  subject { Page.copy_and_paste(source, new_parent, page_name) }
1046
1057
 
1047
1058
  it "should copy the source page with the given name to the new parent" do
1048
- Page.should_receive(:copy).with(source, {
1059
+ expect(Page).to receive(:copy).with(source, {
1049
1060
  parent_id: new_parent.id,
1050
1061
  language: new_parent.language,
1051
1062
  name: page_name,
@@ -1055,15 +1066,15 @@ module Alchemy
1055
1066
  end
1056
1067
 
1057
1068
  it "should return the copied page" do
1058
- Page.stub(:copy).and_return(copied_page)
1069
+ allow(Page).to receive(:copy).and_return(copied_page)
1059
1070
  expect(subject).to be_a(copied_page.class)
1060
1071
  end
1061
1072
 
1062
1073
  context "if source page has children" do
1063
1074
  it "should also copy and paste the children" do
1064
- Page.stub(:copy).and_return(copied_page)
1065
- source.stub(:children).and_return([mock_model('Page')])
1066
- source.should_receive(:copy_children_to).with(copied_page)
1075
+ allow(Page).to receive(:copy).and_return(copied_page)
1076
+ allow(source).to receive(:children).and_return([mock_model('Page')])
1077
+ expect(source).to receive(:copy_children_to).with(copied_page)
1067
1078
  subject
1068
1079
  end
1069
1080
  end
@@ -1085,26 +1096,26 @@ module Alchemy
1085
1096
 
1086
1097
  describe '#previous' do
1087
1098
  it "should return the previous page on the same level" do
1088
- center_page.previous.should == public_page
1089
- next_page.previous.should == center_page
1099
+ expect(center_page.previous).to eq(public_page)
1100
+ expect(next_page.previous).to eq(center_page)
1090
1101
  end
1091
1102
 
1092
1103
  context "no previous page on same level present" do
1093
1104
  it "should return nil" do
1094
- public_page.previous.should be_nil
1105
+ expect(public_page.previous).to be_nil
1095
1106
  end
1096
1107
  end
1097
1108
 
1098
1109
  context "with options restricted" do
1099
1110
  context "set to true" do
1100
1111
  it "returns previous restricted page" do
1101
- center_page.previous(restricted: true).should == restricted_page
1112
+ expect(center_page.previous(restricted: true)).to eq(restricted_page)
1102
1113
  end
1103
1114
  end
1104
1115
 
1105
1116
  context "set to false" do
1106
1117
  it "skips restricted page" do
1107
- center_page.previous(restricted: false).should == public_page
1118
+ expect(center_page.previous(restricted: false)).to eq(public_page)
1108
1119
  end
1109
1120
  end
1110
1121
  end
@@ -1112,13 +1123,13 @@ module Alchemy
1112
1123
  context "with options public" do
1113
1124
  context "set to true" do
1114
1125
  it "returns previous public page" do
1115
- center_page.previous(public: true).should == public_page
1126
+ expect(center_page.previous(public: true)).to eq(public_page)
1116
1127
  end
1117
1128
  end
1118
1129
 
1119
1130
  context "set to false" do
1120
1131
  it "skips public page" do
1121
- center_page.previous(public: false).should == non_public_page
1132
+ expect(center_page.previous(public: false)).to eq(non_public_page)
1122
1133
  end
1123
1134
  end
1124
1135
  end
@@ -1126,12 +1137,12 @@ module Alchemy
1126
1137
 
1127
1138
  describe '#next' do
1128
1139
  it "should return the next page on the same level" do
1129
- center_page.next.should == next_page
1140
+ expect(center_page.next).to eq(next_page)
1130
1141
  end
1131
1142
 
1132
1143
  context "no next page on same level present" do
1133
1144
  it "should return nil" do
1134
- next_page.next.should be_nil
1145
+ expect(next_page.next).to be_nil
1135
1146
  end
1136
1147
  end
1137
1148
  end
@@ -1143,16 +1154,16 @@ module Alchemy
1143
1154
 
1144
1155
  before do
1145
1156
  current_time
1146
- Time.stub(:now).and_return(current_time)
1157
+ allow(Time).to receive(:now).and_return(current_time)
1147
1158
  page.publish!
1148
1159
  end
1149
1160
 
1150
1161
  it "sets public attribute to true" do
1151
- page.public.should == true
1162
+ expect(page.public).to eq(true)
1152
1163
  end
1153
1164
 
1154
1165
  it "sets published_at attribute to current time" do
1155
- page.published_at.should == current_time
1166
+ expect(page.published_at).to eq(current_time)
1156
1167
  end
1157
1168
  end
1158
1169
 
@@ -1160,7 +1171,7 @@ module Alchemy
1160
1171
  let(:default_language) { mock_model('Language', code: 'es') }
1161
1172
  let(:page) { Page.new }
1162
1173
 
1163
- before { page.stub(:parent).and_return(parent) }
1174
+ before { allow(page).to receive(:parent).and_return(parent) }
1164
1175
 
1165
1176
  subject { page }
1166
1177
 
@@ -1171,18 +1182,24 @@ module Alchemy
1171
1182
  page.send(:set_language_from_parent_or_default)
1172
1183
  end
1173
1184
 
1174
- its(:language_id) { should eq(parent.language_id) }
1185
+ describe '#language_id' do
1186
+ subject { super().language_id }
1187
+ it { is_expected.to eq(parent.language_id) }
1188
+ end
1175
1189
  end
1176
1190
 
1177
1191
  context "parent has no language" do
1178
1192
  let(:parent) { mock_model('Page', language: nil, language_id: nil, language_code: nil) }
1179
1193
 
1180
1194
  before do
1181
- Language.stub(:default).and_return(default_language)
1195
+ allow(Language).to receive(:default).and_return(default_language)
1182
1196
  page.send(:set_language_from_parent_or_default)
1183
1197
  end
1184
1198
 
1185
- its(:language_id) { should eq(default_language.id) }
1199
+ describe '#language_id' do
1200
+ subject { super().language_id }
1201
+ it { is_expected.to eq(default_language.id) }
1202
+ end
1186
1203
  end
1187
1204
  end
1188
1205
 
@@ -1190,24 +1207,24 @@ module Alchemy
1190
1207
  context "definition has 'taggable' key with true value" do
1191
1208
  it "should return true" do
1192
1209
  page = FactoryGirl.build(:page)
1193
- page.stub(:definition).and_return({'name' => 'standard', 'taggable' => true})
1194
- page.taggable?.should be_true
1210
+ allow(page).to receive(:definition).and_return({'name' => 'standard', 'taggable' => true})
1211
+ expect(page.taggable?).to be_truthy
1195
1212
  end
1196
1213
  end
1197
1214
 
1198
1215
  context "definition has 'taggable' key with foo value" do
1199
1216
  it "should return false" do
1200
1217
  page = FactoryGirl.build(:page)
1201
- page.stub(:definition).and_return({'name' => 'standard', 'taggable' => 'foo'})
1202
- page.taggable?.should be_false
1218
+ allow(page).to receive(:definition).and_return({'name' => 'standard', 'taggable' => 'foo'})
1219
+ expect(page.taggable?).to be_falsey
1203
1220
  end
1204
1221
  end
1205
1222
 
1206
1223
  context "definition has no 'taggable' key" do
1207
1224
  it "should return false" do
1208
1225
  page = FactoryGirl.build(:page)
1209
- page.stub(:definition).and_return({'name' => 'standard'})
1210
- page.taggable?.should be_false
1226
+ allow(page).to receive(:definition).and_return({'name' => 'standard'})
1227
+ expect(page.taggable?).to be_falsey
1211
1228
  end
1212
1229
  end
1213
1230
  end
@@ -1216,13 +1233,13 @@ module Alchemy
1216
1233
  let(:page) { FactoryGirl.create(:page, locked: true, locked_by: 1) }
1217
1234
 
1218
1235
  before do
1219
- page.stub(:save).and_return(true)
1236
+ allow(page).to receive(:save).and_return(true)
1220
1237
  end
1221
1238
 
1222
1239
  it "should set the locked status to false" do
1223
1240
  page.unlock!
1224
1241
  page.reload
1225
- page.locked.should == false
1242
+ expect(page.locked).to eq(false)
1226
1243
  end
1227
1244
 
1228
1245
  it "should not update the timestamps " do
@@ -1232,13 +1249,13 @@ module Alchemy
1232
1249
  it "should set locked_by to nil" do
1233
1250
  page.unlock!
1234
1251
  page.reload
1235
- page.locked_by.should == nil
1252
+ expect(page.locked_by).to eq(nil)
1236
1253
  end
1237
1254
 
1238
1255
  it "sets current preview to nil" do
1239
1256
  Page.current_preview = page
1240
1257
  page.unlock!
1241
- Page.current_preview.should be_nil
1258
+ expect(Page.current_preview).to be_nil
1242
1259
  end
1243
1260
  end
1244
1261
 
@@ -1252,24 +1269,24 @@ module Alchemy
1252
1269
  let(:language_root) { parentparent.parent }
1253
1270
 
1254
1271
  context "with activated url_nesting" do
1255
- before { Config.stub(:get).and_return(true) }
1272
+ before { allow(Config).to receive(:get).and_return(true) }
1256
1273
 
1257
1274
  it "should store all parents urlnames delimited by slash" do
1258
- page.urlname.should == 'parentparent/parent/page'
1275
+ expect(page.urlname).to eq('parentparent/parent/page')
1259
1276
  end
1260
1277
 
1261
1278
  it "should not include the root page" do
1262
1279
  Page.root.update_column(:urlname, 'root')
1263
1280
  language_root.update(urlname: 'new-urlname')
1264
- language_root.urlname.should_not =~ /root/
1281
+ expect(language_root.urlname).not_to match(/root/)
1265
1282
  end
1266
1283
 
1267
1284
  it "should not include the language root page" do
1268
- page.urlname.should_not =~ /startseite/
1285
+ expect(page.urlname).not_to match(/startseite/)
1269
1286
  end
1270
1287
 
1271
1288
  it "should not include invisible pages" do
1272
- contact.urlname.should_not =~ /invisible/
1289
+ expect(contact.urlname).not_to match(/invisible/)
1273
1290
  end
1274
1291
 
1275
1292
  context "after changing page's urlname" do
@@ -1278,7 +1295,7 @@ module Alchemy
1278
1295
  parentparent.urlname = 'new-urlname'
1279
1296
  parentparent.save!
1280
1297
  page.reload
1281
- page.urlname.should == 'new-urlname/parent/page'
1298
+ expect(page.urlname).to eq('new-urlname/parent/page')
1282
1299
  end
1283
1300
 
1284
1301
  context 'with descendants that are redirecting to external' do
@@ -1287,15 +1304,15 @@ module Alchemy
1287
1304
  parent.urlname = 'new-urlname'
1288
1305
  parent.save!
1289
1306
  external.reload
1290
- external.urlname.should == 'http://google.com'
1307
+ expect(external.urlname).to eq('http://google.com')
1291
1308
  end
1292
1309
  end
1293
1310
 
1294
1311
  it "should create a legacy url" do
1295
- page.stub(:slug).and_return('foo')
1312
+ allow(page).to receive(:slug).and_return('foo')
1296
1313
  page.update_urlname!
1297
- page.legacy_urls.should_not be_empty
1298
- page.legacy_urls.pluck(:urlname).should include('parentparent/parent/page')
1314
+ expect(page.legacy_urls).not_to be_empty
1315
+ expect(page.legacy_urls.pluck(:urlname)).to include('parentparent/parent/page')
1299
1316
  end
1300
1317
  end
1301
1318
 
@@ -1305,16 +1322,16 @@ module Alchemy
1305
1322
  parentparent.visible = false
1306
1323
  parentparent.save!
1307
1324
  page.reload
1308
- page.urlname.should == 'parent/page'
1325
+ expect(page.urlname).to eq('parent/page')
1309
1326
  end
1310
1327
  end
1311
1328
  end
1312
1329
 
1313
1330
  context "with disabled url_nesting" do
1314
- before { Config.stub(:get).and_return(false) }
1331
+ before { allow(Config).to receive(:get).and_return(false) }
1315
1332
 
1316
1333
  it "should only store my urlname" do
1317
- page.urlname.should == 'page'
1334
+ expect(page.urlname).to eq('page')
1318
1335
  end
1319
1336
  end
1320
1337
  end
@@ -1326,11 +1343,13 @@ module Alchemy
1326
1343
  let(:node) { TreeNode.new(10, 11, 12, 13, "another-url", true) }
1327
1344
 
1328
1345
  context "when nesting is enabled" do
1329
- before { Alchemy::Config.stub(:get).with(:url_nesting) { true } }
1346
+ before { allow(Alchemy::Config).to receive(:get).with(:url_nesting) { true } }
1330
1347
 
1331
1348
  context "when page is not external" do
1332
1349
 
1333
- before { page.stub(redirects_to_external?: false)}
1350
+ before do
1351
+ expect(page).to receive(:redirects_to_external?).and_return(false)
1352
+ end
1334
1353
 
1335
1354
  it "should update all attributes" do
1336
1355
  page.update_node!(node)
@@ -1363,8 +1382,11 @@ module Alchemy
1363
1382
  end
1364
1383
 
1365
1384
  context "when page is external" do
1366
-
1367
- before { page.stub(redirects_to_external?: true) }
1385
+ before do
1386
+ expect(page)
1387
+ .to receive(:redirects_to_external?)
1388
+ .and_return(true)
1389
+ end
1368
1390
 
1369
1391
  it "should update all attributes except url" do
1370
1392
  page.update_node!(node)
@@ -1386,11 +1408,14 @@ module Alchemy
1386
1408
  end
1387
1409
 
1388
1410
  context "when nesting is disabled" do
1389
- before { Alchemy::Config.stub(:get).with(:url_nesting) { false } }
1411
+ before do
1412
+ allow(Alchemy::Config).to receive(:get).with(:url_nesting) { false }
1413
+ end
1390
1414
 
1391
1415
  context "when page is not external" do
1392
-
1393
- before { page.stub(redirects_to_external?: false)}
1416
+ before do
1417
+ allow(page).to receive(:redirects_to_external?).and_return(false)
1418
+ end
1394
1419
 
1395
1420
  it "should update all attributes except url" do
1396
1421
  page.update_node!(node)
@@ -1408,14 +1433,13 @@ module Alchemy
1408
1433
  page.reload
1409
1434
  expect(page.legacy_urls.size).to eq(0)
1410
1435
  end
1411
-
1412
1436
  end
1413
1437
 
1414
1438
  context "when page is external" do
1415
-
1416
- before { page.stub(redirects_to_external?: true) }
1417
-
1418
- before { Alchemy::Config.stub(get: true) }
1439
+ before do
1440
+ expect(Alchemy::Config).to receive(:get).and_return(true)
1441
+ allow(page).to receive(:redirects_to_external?).and_return(true)
1442
+ end
1419
1443
 
1420
1444
  it "should update all attributes except url" do
1421
1445
  page.update_node!(node)
@@ -1442,7 +1466,7 @@ module Alchemy
1442
1466
  let(:page) { FactoryGirl.build(:page, urlname: 'root/parent/my-name')}
1443
1467
 
1444
1468
  it "should return the last part of the urlname" do
1445
- page.slug.should == 'my-name'
1469
+ expect(page.slug).to eq('my-name')
1446
1470
  end
1447
1471
  end
1448
1472
 
@@ -1450,7 +1474,7 @@ module Alchemy
1450
1474
  let(:page) { FactoryGirl.build(:page, urlname: 'my-name')}
1451
1475
 
1452
1476
  it "should return the last part of the urlname" do
1453
- page.slug.should == 'my-name'
1477
+ expect(page.slug).to eq('my-name')
1454
1478
  end
1455
1479
  end
1456
1480
 
@@ -1458,7 +1482,7 @@ module Alchemy
1458
1482
  let(:page) { FactoryGirl.build(:page, urlname: nil)}
1459
1483
 
1460
1484
  it "should return nil" do
1461
- page.slug.should be_nil
1485
+ expect(page.slug).to be_nil
1462
1486
  end
1463
1487
  end
1464
1488
  end
@@ -1496,25 +1520,25 @@ module Alchemy
1496
1520
 
1497
1521
  describe '#status' do
1498
1522
  it "returns a combined status hash" do
1499
- page.status.should == {public: true, visible: true, restricted: false, locked: false}
1523
+ expect(page.status).to eq({public: true, visible: true, restricted: false, locked: false})
1500
1524
  end
1501
1525
  end
1502
1526
 
1503
1527
  describe '#status_title' do
1504
1528
  it "returns a translated status string for public status" do
1505
- page.status_title(:public).should == 'Page is published.'
1529
+ expect(page.status_title(:public)).to eq('Page is published.')
1506
1530
  end
1507
1531
 
1508
1532
  it "returns a translated status string for visible status" do
1509
- page.status_title(:visible).should == 'Page is visible in navigation.'
1533
+ expect(page.status_title(:visible)).to eq('Page is visible in navigation.')
1510
1534
  end
1511
1535
 
1512
1536
  it "returns a translated status string for locked status" do
1513
- page.status_title(:locked).should == ''
1537
+ expect(page.status_title(:locked)).to eq('')
1514
1538
  end
1515
1539
 
1516
1540
  it "returns a translated status string for restricted status" do
1517
- page.status_title(:restricted).should == 'Page is not restricted.'
1541
+ expect(page.status_title(:restricted)).to eq('Page is not restricted.')
1518
1542
  end
1519
1543
  end
1520
1544
  end
@@ -1552,7 +1576,7 @@ module Alchemy
1552
1576
  %w(creator updater locker).each do |user_type|
1553
1577
  expect {
1554
1578
  page.send(user_type)
1555
- }.to_not raise_error(ActiveRecord::RecordNotFound)
1579
+ }.to_not raise_error
1556
1580
  end
1557
1581
  end
1558
1582
  end
@@ -1561,7 +1585,7 @@ module Alchemy
1561
1585
  let(:user) { double(name: 'Paul Page') }
1562
1586
 
1563
1587
  describe '#creator_name' do
1564
- before { page.stub(:creator).and_return(user) }
1588
+ before { allow(page).to receive(:creator).and_return(user) }
1565
1589
 
1566
1590
  it "returns the name of the creator" do
1567
1591
  expect(page.creator_name).to eq('Paul Page')
@@ -1569,7 +1593,7 @@ module Alchemy
1569
1593
  end
1570
1594
 
1571
1595
  describe '#updater_name' do
1572
- before { page.stub(:updater).and_return(user) }
1596
+ before { allow(page).to receive(:updater).and_return(user) }
1573
1597
 
1574
1598
  it "returns the name of the updater" do
1575
1599
  expect(page.updater_name).to eq('Paul Page')
@@ -1577,7 +1601,7 @@ module Alchemy
1577
1601
  end
1578
1602
 
1579
1603
  describe '#locker_name' do
1580
- before { page.stub(:locker).and_return(user) }
1604
+ before { allow(page).to receive(:locker).and_return(user) }
1581
1605
 
1582
1606
  it "returns the name of the current page editor" do
1583
1607
  expect(page.locker_name).to eq('Paul Page')
@@ -1589,7 +1613,7 @@ module Alchemy
1589
1613
  let(:user) { Alchemy.user_class.new }
1590
1614
 
1591
1615
  describe '#creator_name' do
1592
- before { page.stub(:creator).and_return(user) }
1616
+ before { allow(page).to receive(:creator).and_return(user) }
1593
1617
 
1594
1618
  it "returns unknown" do
1595
1619
  expect(page.creator_name).to eq('unknown')
@@ -1597,7 +1621,7 @@ module Alchemy
1597
1621
  end
1598
1622
 
1599
1623
  describe '#updater_name' do
1600
- before { page.stub(:updater).and_return(user) }
1624
+ before { allow(page).to receive(:updater).and_return(user) }
1601
1625
 
1602
1626
  it "returns unknown" do
1603
1627
  expect(page.updater_name).to eq('unknown')
@@ -1605,7 +1629,7 @@ module Alchemy
1605
1629
  end
1606
1630
 
1607
1631
  describe '#locker_name' do
1608
- before { page.stub(:locker).and_return(user) }
1632
+ before { allow(page).to receive(:locker).and_return(user) }
1609
1633
 
1610
1634
  it "returns unknown" do
1611
1635
  expect(page.locker_name).to eq('unknown')
@@ -1619,8 +1643,8 @@ module Alchemy
1619
1643
 
1620
1644
  context 'if the page has a custom controller defined in its description' do
1621
1645
  before do
1622
- page.stub(:has_controller?).and_return(true)
1623
- page.stub(:layout_description).and_return({'controller' => 'comments', 'action' => 'index'})
1646
+ allow(page).to receive(:has_controller?).and_return(true)
1647
+ allow(page).to receive(:layout_description).and_return({'controller' => 'comments', 'action' => 'index'})
1624
1648
  end
1625
1649
  it "should return a Hash with controller and action key-value pairs" do
1626
1650
  expect(page.controller_and_action).to eq({controller: '/comments', action: 'index'})