alchemy_cms 3.0.4 → 3.1.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -2,7 +2,6 @@ require "spec_helper"
2
2
 
3
3
  module Alchemy
4
4
  describe Admin::EssenceFilesController do
5
-
6
5
  before do
7
6
  sign_in(admin_user)
8
7
  end
@@ -13,7 +12,7 @@ module Alchemy
13
12
 
14
13
  describe '#edit' do
15
14
  before do
16
- Content.stub(find: content)
15
+ expect(Content).to receive(:find).and_return(content)
17
16
  end
18
17
 
19
18
  it "should assign @content with the Content found by id" do
@@ -29,19 +28,19 @@ module Alchemy
29
28
 
30
29
  describe '#update' do
31
30
  before do
32
- EssenceFile.stub(find: essence_file)
31
+ expect(EssenceFile).to receive(:find).and_return(essence_file)
33
32
  end
34
33
 
35
34
  it "should update the attributes of essence_file" do
36
- essence_file.should_receive(:update_attributes).and_return(true)
35
+ expect(essence_file).to receive(:update_attributes).and_return(true)
37
36
  xhr :put, :update, id: essence_file.id
38
37
  end
39
38
  end
40
39
 
41
40
  describe '#assign' do
42
41
  before do
43
- Content.stub(find_by: content)
44
- Attachment.stub(find_by: attachment)
42
+ expect(Content).to receive(:find_by).and_return(content)
43
+ expect(Attachment).to receive(:find_by).and_return(attachment)
45
44
  end
46
45
 
47
46
  it "should assign @attachment with the Attachment found by attachment_id" do
@@ -50,7 +49,7 @@ module Alchemy
50
49
  end
51
50
 
52
51
  it "should assign @content.essence.attachment with the attachment found by id" do
53
- content.essence.should_receive(:attachment=).with(attachment)
52
+ expect(content.essence).to receive(:attachment=).with(attachment)
54
53
  xhr :put, :assign, content_id: content.id, attachment_id: attachment.id
55
54
  end
56
55
 
@@ -10,8 +10,8 @@ module Alchemy
10
10
 
11
11
  describe '#edit' do
12
12
  before do
13
- EssencePicture.should_receive(:find).and_return(essence)
14
- Content.should_receive(:find).and_return(content)
13
+ expect(EssencePicture).to receive(:find).and_return(essence)
14
+ expect(Content).to receive(:find).and_return(content)
15
15
  end
16
16
 
17
17
  it 'should assign @essence_picture and @content instance variables' do
@@ -23,11 +23,13 @@ module Alchemy
23
23
 
24
24
  describe '#crop' do
25
25
  before do
26
- EssencePicture.should_receive(:find).and_return(essence)
26
+ expect(EssencePicture).to receive(:find).and_return(essence)
27
27
  end
28
28
 
29
29
  context 'with no picture assigned' do
30
- before { essence.should_receive(:picture).and_return(nil) }
30
+ before do
31
+ expect(essence).to receive(:picture).at_least(:once).and_return(nil)
32
+ end
31
33
 
32
34
  it "renders error message" do
33
35
  get :crop, id: 1
@@ -36,69 +38,86 @@ module Alchemy
36
38
  end
37
39
 
38
40
  context 'with picture assigned' do
39
- let(:default_mask) { {'x1' => '0', 'y1' => '0', 'x2' => '100', 'y2' => '100'} }
41
+ let(:default_mask) do
42
+ {
43
+ x1: 0,
44
+ y1: 0,
45
+ x2: 300,
46
+ y2: 250
47
+ }
48
+ end
40
49
 
41
50
  before do
42
51
  picture.image_file_width = 300
43
52
  picture.image_file_height = 250
44
- essence.should_receive(:picture).any_number_of_times.and_return(picture)
53
+ expect(essence).to receive(:picture).at_least(:once).and_return(picture)
45
54
  end
46
55
 
47
56
  context 'with no render_size present in essence' do
48
57
  before do
49
- essence.should_receive(:render_size).and_return(nil)
58
+ expect(essence).to receive(:render_size).at_least(:once).and_return(nil)
50
59
  end
51
60
 
52
61
  context 'with sizes in params' do
53
62
  it "sets sizes to given values" do
54
63
  get :crop, id: 1, options: {image_size: '300x250'}
55
- expect(assigns(:size_x)).to eq('300')
56
- expect(assigns(:size_y)).to eq('250')
64
+ expect(assigns(:min_size)).to eq({ width: 300, height: 250 })
57
65
  end
58
66
  end
59
67
 
60
68
  context 'with no sizes in params' do
61
69
  it "sets sizes to zero" do
62
70
  get :crop, id: 1
63
- expect(assigns(:size_x)).to eq(0)
64
- expect(assigns(:size_y)).to eq(0)
71
+ expect(assigns(:min_size)).to eq({ width: 0, height: 0 })
65
72
  end
66
73
  end
67
74
  end
68
75
 
69
76
  context 'with render_size present in essence' do
70
77
  it "sets sizes from these values" do
71
- essence.stub(:render_size).and_return('30x25')
78
+ expect(essence).to receive(:render_size).at_least(:once).and_return('30x25')
72
79
 
73
80
  get :crop, id: 1
74
- expect(assigns(:size_x)).to eq(30)
75
- expect(assigns(:size_y)).to eq(25)
81
+ expect(assigns(:min_size)).to eq({ width: 30, height: 25 })
76
82
  end
77
83
 
78
84
  context 'when width or height is not fixed' do
79
85
  it 'infers the height from the image file preserving the aspect ratio' do
80
- essence.stub(:render_size).and_return('30')
86
+ expect(essence).to receive(:render_size).at_least(:once).and_return('30x')
81
87
 
82
88
  get :crop, id: 1
83
- expect(assigns(:size_x)).to eq(30)
84
- expect(assigns(:size_y)).to eq(25)
89
+ expect(assigns(:min_size)).to eq({ width: 30, height: 0})
90
+ end
91
+
92
+ it 'does not infer the height from the image file preserving the aspect ratio' do
93
+ expect(essence).to receive(:render_size).at_least(:once).and_return('x25')
94
+
95
+ get :crop, id: 1, options: { fixed_ratio: "2"}
96
+ expect(assigns(:min_size)).to eq({ width: 50, height: 25 })
97
+ end
98
+ end
99
+
100
+ context 'when width or height is not fixed and an aspect ratio is given' do
101
+ it 'width is given, it infers the height from width and ratio' do
102
+ expect(essence).to receive(:render_size).at_least(:once).and_return('30x')
103
+
104
+ get :crop, id: 1, options: { fixed_ratio: "0.5" }
105
+ expect(assigns(:min_size)).to eq({ width: 30, height: 60 })
85
106
  end
86
107
 
87
108
  it 'infers the height from the image file preserving the aspect ratio' do
88
- essence.stub(:render_size).and_return('x25')
109
+ expect(essence).to receive(:render_size).at_least(:once).and_return('x25')
89
110
 
90
111
  get :crop, id: 1
91
- expect(assigns(:size_x)).to eq(30)
92
- expect(assigns(:size_y)).to eq(25)
112
+ expect(assigns(:min_size)).to eq({ width: 0, height: 25})
93
113
  end
94
114
  end
95
115
  end
96
116
 
97
117
  context 'no crop sizes present in essence' do
98
118
  before do
99
- essence.stub(:crop_from).and_return(nil)
100
- essence.stub(:crop_size).and_return(nil)
101
- picture.should_receive(:default_mask).and_return(default_mask)
119
+ expect(essence).to receive(:crop_from).and_return(nil)
120
+ allow(essence).to receive(:crop_size).and_return(nil)
102
121
  end
103
122
 
104
123
  it "assigns default mask boxes" do
@@ -112,13 +131,12 @@ module Alchemy
112
131
  let(:mask) { {'x1' => '0', 'y1' => '0', 'x2' => '120', 'y2' => '160'} }
113
132
 
114
133
  before do
115
- essence.stub(:crop_from).and_return('0x0')
116
- essence.stub(:crop_size).and_return('120x160')
117
- picture.should_receive(:default_mask).and_return(default_mask)
134
+ allow(essence).to receive(:crop_from).and_return('0x0')
135
+ allow(essence).to receive(:crop_size).and_return('120x160')
118
136
  end
119
137
 
120
138
  it "assigns cropping boxes" do
121
- essence.should_receive(:cropping_mask).and_return(mask)
139
+ expect(essence).to receive(:cropping_mask).and_return(mask)
122
140
  get :crop, id: 1
123
141
  expect(assigns(:initial_box)).to eq(mask)
124
142
  expect(assigns(:default_box)).to eq(default_mask)
@@ -138,40 +156,33 @@ module Alchemy
138
156
  expect(assigns(:ratio)).to eq(80.0/60.0)
139
157
  end
140
158
  end
141
-
142
- context 'with size_y set to zero' do
143
- it "sets ratio to 1" do
144
- get :crop, id: 1
145
- expect(assigns(:ratio)).to eq(1)
146
- end
147
- end
148
159
  end
149
160
  end
150
161
 
151
162
  describe '#update' do
152
163
  before do
153
- EssencePicture.should_receive(:find).and_return(essence)
154
- Content.should_receive(:find).and_return(content)
164
+ expect(EssencePicture).to receive(:find).and_return(essence)
165
+ expect(Content).to receive(:find).and_return(content)
155
166
  end
156
167
 
157
168
  let(:attributes) { {render_size: '1x1', alt_tag: 'Alt Tag', caption: 'Caption', css_class: 'CSS Class', title: 'Title'} }
158
169
 
159
170
  it "updates the essence attributes" do
160
- essence.should_receive(:update).and_return(true)
171
+ expect(essence).to receive(:update).and_return(true)
161
172
  xhr :put, :update, id: 1, essence_picture: attributes
162
173
  end
163
174
 
164
175
  it "saves the cropping mask" do
165
- essence.should_receive(:update).and_return(true)
176
+ expect(essence).to receive(:update).and_return(true)
166
177
  xhr :put, :update, id: 1, essence_picture: {render_size: '1x1', crop_from: '0x0', crop_size: '100x100'}
167
178
  end
168
179
  end
169
180
 
170
181
  describe '#assign' do
171
182
  before do
172
- Content.should_receive(:find).and_return(content)
173
- Content.any_instance.stub(:essence).and_return(essence)
174
- Picture.should_receive(:find_by_id).and_return(picture)
183
+ expect(Content).to receive(:find).and_return(content)
184
+ expect(content).to receive(:essence).at_least(:once).and_return(essence)
185
+ expect(Picture).to receive(:find_by).and_return(picture)
175
186
  end
176
187
 
177
188
  it "should assign a Picture" do
@@ -179,6 +190,5 @@ module Alchemy
179
190
  expect(assigns(:content).essence.picture).to eq(picture)
180
191
  end
181
192
  end
182
-
183
193
  end
184
194
  end
@@ -14,7 +14,7 @@ describe Alchemy::Admin::LanguagesController do
14
14
  context "when default_language.page_layout is set" do
15
15
  it "should use it as page_layout-default for the new language" do
16
16
  # FML :/
17
- Alchemy::Config.stub(:get) do |arg|
17
+ allow(Alchemy::Config).to receive(:get) do |arg|
18
18
  if arg == :default_language
19
19
  {'page_layout' => "new_standard"}
20
20
  else
@@ -22,14 +22,14 @@ describe Alchemy::Admin::LanguagesController do
22
22
  end
23
23
  end
24
24
  get :new
25
- assigns(:language).page_layout.should eql("new_standard")
25
+ expect(assigns(:language).page_layout).to eql("new_standard")
26
26
  end
27
27
  end
28
28
 
29
29
  context "when default_language or page_layout aren't configured" do
30
30
  it "should fallback to one configured in config.yml" do
31
31
  get :new
32
- assigns(:language).page_layout.should eql("index")
32
+ expect(assigns(:language).page_layout).to eql("index")
33
33
  end
34
34
  end
35
35
 
@@ -12,26 +12,26 @@ module Alchemy
12
12
 
13
13
  context 'with existing language root page' do
14
14
  before do
15
- Language.should_receive(:current_root_page).and_return(language_root)
15
+ expect(Language).to receive(:current_root_page).and_return(language_root)
16
16
  end
17
17
 
18
18
  it "assigns @page_root variable" do
19
19
  get :index
20
- assigns(:page_root).should be(language_root)
20
+ expect(assigns(:page_root)).to be(language_root)
21
21
  end
22
22
  end
23
23
 
24
24
  context 'without language root page' do
25
25
  before do
26
- Language.should_receive(:current_root_page).and_return(nil)
27
- Language.stub(find_by: language)
28
- Language.stub(all: [language])
29
- Language.stub(with_root_page: [language])
26
+ expect(Language).to receive(:current_root_page).and_return(nil)
27
+ expect(Language).to receive(:find_by).and_return(language)
28
+ expect(Language).to receive(:all).and_return([language])
29
+ expect(Language).to receive(:with_root_page).and_return([language])
30
30
  end
31
31
 
32
32
  it "it assigns current language" do
33
33
  get :index
34
- assigns(:language).should be(language)
34
+ expect(assigns(:language)).to be(language)
35
35
  end
36
36
  end
37
37
  end
@@ -42,12 +42,12 @@ module Alchemy
42
42
  let(:page_2) { build_stubbed(:page) }
43
43
 
44
44
  before do
45
- Language.stub(current: language)
45
+ expect(Language).to receive(:current).at_least(:once).and_return(language)
46
46
  end
47
47
 
48
48
  it "should remove the cache of all pages" do
49
- page_1.should_receive(:publish!)
50
- page_2.should_receive(:publish!)
49
+ expect(page_1).to receive(:publish!)
50
+ expect(page_2).to receive(:publish!)
51
51
  xhr :post, :flush
52
52
  end
53
53
  end
@@ -61,17 +61,17 @@ module Alchemy
61
61
 
62
62
  it "should load all pages from clipboard" do
63
63
  xhr :get, :new, {page_id: page.id}
64
- assigns(:clipboard_items).should be_kind_of(Array)
64
+ expect(assigns(:clipboard_items)).to be_kind_of(Array)
65
65
  end
66
66
  end
67
67
  end
68
68
 
69
69
  describe '#show' do
70
- let(:page) { mock_model(Alchemy::Page, language_code: 'nl') }
70
+ let(:page) { build_stubbed(:page, language_code: 'nl') }
71
71
 
72
72
  before do
73
- Page.should_receive(:find).with("#{page.id}").and_return(page)
74
- Page.stub(:language_root_for).and_return(mock_model(Alchemy::Page))
73
+ expect(Page).to receive(:find).with("#{page.id}").and_return(page)
74
+ allow(Page).to receive(:language_root_for).and_return(mock_model(Alchemy::Page))
75
75
  end
76
76
 
77
77
  it "should assign @preview_mode with true" do
@@ -82,7 +82,7 @@ module Alchemy
82
82
  it "should store page as current preview" do
83
83
  Page.current_preview = nil
84
84
  get :show, id: page.id
85
- Page.current_preview.should == page
85
+ expect(Page.current_preview).to eq(page)
86
86
  end
87
87
 
88
88
  it "should set the I18n locale to the pages language code" do
@@ -112,7 +112,9 @@ module Alchemy
112
112
  end
113
113
 
114
114
  context 'with url nesting enabled' do
115
- before { Alchemy::Config.stub(get: true) }
115
+ before do
116
+ expect(Alchemy::Config).to receive(:get).with(:url_nesting).at_least(:once).and_return(true)
117
+ end
116
118
 
117
119
  it "updates the pages urlnames" do
118
120
  xhr :post, :order, set: set_of_pages.to_json
@@ -172,7 +174,7 @@ module Alchemy
172
174
  it "updates restricted status of descendants" do
173
175
  xhr :post, :order, set: set_of_pages.to_json
174
176
  page_3.reload
175
- expect(page_3.restricted).to be_true
177
+ expect(page_3.restricted).to be_truthy
176
178
  end
177
179
  end
178
180
 
@@ -188,7 +190,11 @@ module Alchemy
188
190
  it "does not raise error" do
189
191
  expect {
190
192
  xhr :post, :order, set: set_of_pages.to_json
191
- }.to_not raise_error(TypeError)
193
+ }.not_to raise_error
194
+ end
195
+
196
+ it "still generates the correct urlname on page_3" do
197
+ xhr :post, :order, set: set_of_pages.to_json
192
198
  [page_1, page_2, page_3].map(&:reload)
193
199
  expect(page_3.urlname).to eq("#{page_1.slug}/#{page_2.slug}/#{page_3.slug}")
194
200
  end
@@ -211,7 +217,7 @@ module Alchemy
211
217
 
212
218
  it "should always show the slug" do
213
219
  xhr :get, :configure, {id: page.id}
214
- response.body.should match /value="foobar"/
220
+ expect(response.body).to match /value="foobar"/
215
221
  end
216
222
  end
217
223
  end
@@ -223,28 +229,28 @@ module Alchemy
223
229
 
224
230
  context "a new page" do
225
231
  before do
226
- Page.any_instance.stub(:set_language_from_parent_or_default)
227
- Page.any_instance.stub(save: true)
232
+ allow_any_instance_of(Page).to receive(:set_language_from_parent_or_default)
233
+ allow_any_instance_of(Page).to receive(:save).and_return(true)
228
234
  end
229
235
 
230
236
  it "is nested under given parent" do
231
- controller.stub(:edit_admin_page_path).and_return('bla')
237
+ allow(controller).to receive(:edit_admin_page_path).and_return('bla')
232
238
  xhr :post, :create, {page: page_params}
233
239
  expect(assigns(:page).parent_id).to eq(parent.id)
234
240
  end
235
241
 
236
242
  it "redirects to edit page template" do
237
243
  page = mock_model('Page')
238
- controller.should_receive(:edit_admin_page_path).and_return('bla')
244
+ expect(controller).to receive(:edit_admin_page_path).and_return('bla')
239
245
  post :create, page: page_params
240
- response.should redirect_to('bla')
246
+ expect(response).to redirect_to('bla')
241
247
  end
242
248
 
243
249
  context "if new page can not be saved" do
244
250
  it "renders the create form" do
245
- Page.any_instance.stub(:save).and_return(false)
251
+ allow_any_instance_of(Page).to receive(:save).and_return(false)
246
252
  post :create, page: {name: 'page'}
247
- response.should render_template('new')
253
+ expect(response).to render_template('new')
248
254
  end
249
255
  end
250
256
 
@@ -255,25 +261,25 @@ module Alchemy
255
261
 
256
262
  it "should redirect to given url" do
257
263
  post :create, page: page_params, redirect_to: admin_pictures_path
258
- response.should redirect_to(admin_pictures_path)
264
+ expect(response).to redirect_to(admin_pictures_path)
259
265
  end
260
266
 
261
267
  context "but new page can not be saved" do
262
268
  render_views
263
269
 
264
270
  it "should render the `new` template" do
265
- Page.any_instance.stub(:save).and_return(false)
271
+ allow_any_instance_of(Page).to receive(:save).and_return(false)
266
272
  xhr :post, :create, page: {name: 'page'}, redirect_to: admin_pictures_path
267
- response.body.should match /form.+action=\"\/admin\/pages\"/
273
+ expect(response.body).to match /form.+action=\"\/admin\/pages\"/
268
274
  end
269
275
  end
270
276
  end
271
277
 
272
278
  context 'with page redirecting to external' do
273
279
  it "redirects to sitemap" do
274
- Page.any_instance.should_receive(:redirects_to_external?).and_return(true)
280
+ expect_any_instance_of(Page).to receive(:redirects_to_external?).and_return(true)
275
281
  post :create, page: page_params
276
- response.should redirect_to(admin_pages_path)
282
+ expect(response).to redirect_to(admin_pages_path)
277
283
  end
278
284
  end
279
285
  end
@@ -282,12 +288,12 @@ module Alchemy
282
288
  let(:page_in_clipboard) { mock_model(Alchemy::Page) }
283
289
 
284
290
  before do
285
- Page.stub(:find_by).with(id: "#{parent.id}").and_return(parent)
286
- Page.stub(:find).with("#{page_in_clipboard.id}").and_return(page_in_clipboard)
291
+ allow(Page).to receive(:find_by).with(id: "#{parent.id}").and_return(parent)
292
+ allow(Page).to receive(:find).with("#{page_in_clipboard.id}").and_return(page_in_clipboard)
287
293
  end
288
294
 
289
295
  it "should call Page#copy_and_paste" do
290
- Page.should_receive(:copy_and_paste).with(
296
+ expect(Page).to receive(:copy_and_paste).with(
291
297
  page_in_clipboard,
292
298
  parent,
293
299
  'pasted Page'
@@ -306,35 +312,35 @@ module Alchemy
306
312
  let(:root_page) { mock_model('Page') }
307
313
 
308
314
  before do
309
- Page.stub(copy: copy_of_language_root)
310
- Page.stub(root: root_page)
311
- Page.stub(language_root_for: language_root_to_copy_from)
312
- Page.any_instance.stub(:move_to_child_of)
313
- Page.any_instance.stub(:copy_children_to)
314
- controller.stub(:store_current_language)
315
- Language.stub(:current).and_return(mock_model('Language', language_code: 'it', code: 'it'))
315
+ allow(Page).to receive(:copy).and_return(copy_of_language_root)
316
+ allow(Page).to receive(:root).and_return(root_page)
317
+ allow(Page).to receive(:language_root_for).and_return(language_root_to_copy_from)
318
+ allow_any_instance_of(Page).to receive(:move_to_child_of)
319
+ allow_any_instance_of(Page).to receive(:copy_children_to)
320
+ allow(controller).to receive(:store_current_language)
321
+ allow(Language).to receive(:current).and_return(mock_model('Language', language_code: 'it', code: 'it'))
316
322
  end
317
323
 
318
324
  it "should copy the language root page over to the other language" do
319
- Page.should_receive(:copy).with(language_root_to_copy_from, {language_id: '2', language_code: 'it'})
325
+ expect(Page).to receive(:copy).with(language_root_to_copy_from, {language_id: '2', language_code: 'it'})
320
326
  post :copy_language_tree, params
321
327
  end
322
328
 
323
329
  it "should move the newly created language-root-page below the absolute root page" do
324
- copy_of_language_root.should_receive(:move_to_child_of).with(root_page)
330
+ expect(copy_of_language_root).to receive(:move_to_child_of).with(root_page)
325
331
  post :copy_language_tree, params
326
332
  end
327
333
 
328
334
  it "should copy all childs of the original page over to the new created one" do
329
- controller.stub(language_root_to_copy_from: language_root_to_copy_from)
330
- controller.stub(copy_of_language_root: copy_of_language_root)
331
- language_root_to_copy_from.should_receive(:copy_children_to).with(copy_of_language_root)
335
+ expect(controller).to receive(:language_root_to_copy_from).and_return(language_root_to_copy_from)
336
+ expect(controller).to receive(:copy_of_language_root).and_return(copy_of_language_root)
337
+ expect(language_root_to_copy_from).to receive(:copy_children_to).with(copy_of_language_root)
332
338
  post :copy_language_tree, params
333
339
  end
334
340
 
335
341
  it "should redirect to admin_pages_path" do
336
- controller.stub(:copy_of_language_root)
337
- controller.stub_chain(:language_root_to_copy_from, :copy_children_to)
342
+ allow(controller).to receive(:copy_of_language_root)
343
+ allow(controller).to receive(:language_root_to_copy_from).and_return(double(copy_children_to: nil))
338
344
  post :copy_language_tree, params
339
345
  expect(response).to redirect_to(admin_pages_path)
340
346
  end
@@ -348,7 +354,9 @@ module Alchemy
348
354
  before { page.lock_to!(other_user) }
349
355
 
350
356
  context 'that is signed in' do
351
- before { DummyUser.any_instance.stub(logged_in?: true) }
357
+ before do
358
+ expect_any_instance_of(DummyUser).to receive(:logged_in?).and_return(true)
359
+ end
352
360
 
353
361
  it 'redirects to sitemap' do
354
362
  get :edit, id: page.id
@@ -357,7 +365,9 @@ module Alchemy
357
365
  end
358
366
 
359
367
  context 'that is not signed in' do
360
- before { DummyUser.any_instance.stub(logged_in?: false) }
368
+ before do
369
+ expect_any_instance_of(DummyUser).to receive(:logged_in?).and_return(false)
370
+ end
361
371
 
362
372
  it 'renders the edit view' do
363
373
  get :edit, id: page.id
@@ -368,8 +378,8 @@ module Alchemy
368
378
 
369
379
  context 'if page is locked by myself' do
370
380
  before do
371
- Page.any_instance.stub(locker: user)
372
- user.stub(logged_in?: true)
381
+ expect_any_instance_of(Page).to receive(:locker).and_return(user)
382
+ expect(user).to receive(:logged_in?).and_return(true)
373
383
  end
374
384
 
375
385
  it 'renders the edit view' do
@@ -380,7 +390,7 @@ module Alchemy
380
390
 
381
391
  context 'if page is not locked' do
382
392
  before do
383
- Page.any_instance.stub(locker: nil)
393
+ expect_any_instance_of(Page).to receive(:locker).and_return(nil)
384
394
  end
385
395
 
386
396
  it 'renders the edit view' do
@@ -389,7 +399,7 @@ module Alchemy
389
399
  end
390
400
 
391
401
  it "lockes the page to myself" do
392
- Page.any_instance.should_receive(:lock_to!)
402
+ expect_any_instance_of(Page).to receive(:lock_to!)
393
403
  get :edit, id: page.id
394
404
  end
395
405
  end
@@ -403,7 +413,7 @@ module Alchemy
403
413
 
404
414
  it "should also remove the page from clipboard" do
405
415
  xhr :post, :destroy, {id: page.id, _method: :delete}
406
- clipboard['pages'].should be_empty
416
+ expect(clipboard['pages']).to be_empty
407
417
  end
408
418
  end
409
419
 
@@ -411,12 +421,12 @@ module Alchemy
411
421
  let(:page) { stub_model(Page, published_at: nil, public: false, name: "page", parent_id: 1, urlname: "page", language: stub_model(Language), page_layout: "bla") }
412
422
 
413
423
  before do
414
- @controller.stub(:load_page).and_return(page)
424
+ allow(@controller).to receive(:load_page).and_return(page)
415
425
  @controller.instance_variable_set("@page", page)
416
426
  end
417
427
 
418
428
  it "should publish the page" do
419
- page.should_receive(:publish!)
429
+ expect(page).to receive(:publish!)
420
430
  post :publish, { id: page.id }
421
431
  end
422
432
  end
@@ -425,9 +435,9 @@ module Alchemy
425
435
  let(:page) { mock_model(Alchemy::Page, urlname: 'home') }
426
436
 
427
437
  before do
428
- Page.stub(:find).with("#{page.id}").and_return(page)
429
- page.stub(:unlock!).and_return(true)
430
- @controller.stub(:multi_language?).and_return(false)
438
+ allow(Page).to receive(:find).with("#{page.id}").and_return(page)
439
+ allow(page).to receive(:unlock!).and_return(true)
440
+ allow(@controller).to receive(:multi_language?).and_return(false)
431
441
  end
432
442
 
433
443
  it "should redirect to the page path" do
@@ -437,29 +447,29 @@ module Alchemy
437
447
 
438
448
  describe '#fold' do
439
449
  let(:page) { mock_model(Alchemy::Page) }
440
- before { Page.stub(:find).and_return(page) }
450
+ before { allow(Page).to receive(:find).and_return(page) }
441
451
 
442
452
  context "if page is currently not folded" do
443
- before { page.stub(:folded?).and_return(false) }
453
+ before { allow(page).to receive(:folded?).and_return(false) }
444
454
 
445
455
  it "should fold the page" do
446
- page.should_receive(:fold!).with(user.id, true).and_return(true)
456
+ expect(page).to receive(:fold!).with(user.id, true).and_return(true)
447
457
  xhr :post, :fold, id: page.id
448
458
  end
449
459
  end
450
460
 
451
461
  context "if page is already folded" do
452
- before { page.stub(:folded?).and_return(true) }
462
+ before { allow(page).to receive(:folded?).and_return(true) }
453
463
 
454
464
  it "should unfold the page" do
455
- page.should_receive(:fold!).with(user.id, false).and_return(true)
465
+ expect(page).to receive(:fold!).with(user.id, false).and_return(true)
456
466
  xhr :post, :fold, id: page.id
457
467
  end
458
468
  end
459
469
  end
460
470
 
461
471
  describe '#sort' do
462
- before { Page.stub(:language_root_for).and_return(mock_model(Alchemy::Page)) }
472
+ before { allow(Page).to receive(:language_root_for).and_return(mock_model(Alchemy::Page)) }
463
473
 
464
474
  it "should assign @sorting with true" do
465
475
  xhr :get, :sort
@@ -471,9 +481,9 @@ module Alchemy
471
481
  let(:page) { mock_model(Alchemy::Page, name: 'Best practices') }
472
482
 
473
483
  before do
474
- Page.stub(:find).with("#{page.id}").and_return(page)
475
- Page.stub_chain(:from_current_site, :all_locked_by).and_return(nil)
476
- page.should_receive(:unlock!).and_return(true)
484
+ allow(Page).to receive(:find).with("#{page.id}").and_return(page)
485
+ allow(Page).to receive(:from_current_site).and_return(double(all_locked_by: nil))
486
+ expect(page).to receive(:unlock!).and_return(true)
477
487
  end
478
488
 
479
489
  it "should unlock the page" do
@@ -497,7 +507,7 @@ module Alchemy
497
507
  let(:language) { build_stubbed(:klingonian)}
498
508
 
499
509
  before do
500
- Language.stub(:find_by).and_return(language)
510
+ allow(Language).to receive(:find_by).and_return(language)
501
511
  end
502
512
 
503
513
  it "should store the current language in session" do
@@ -511,7 +521,7 @@ module Alchemy
511
521
 
512
522
  context "coming from layoutpages" do
513
523
  before {
514
- request.stub(:referer).and_return('admin/layoutpages')
524
+ allow(request).to receive(:referer).and_return('admin/layoutpages')
515
525
  }
516
526
 
517
527
  it "should redirect to layoutpages" do