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
@@ -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