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
@@ -10,11 +10,11 @@ module Alchemy
10
10
  let(:new_tag) { Tag.new(name: 'green') }
11
11
 
12
12
  before do
13
- picture.stub(:tag_list).and_return(['red'])
14
- element.stub(:tag_list).and_return(['red'])
15
- picture.stub(:save).and_return(true)
16
- element.stub(:save).and_return(true)
17
- tag.stub(:taggings).and_return([
13
+ allow(picture).to receive(:tag_list).and_return(['red'])
14
+ allow(element).to receive(:tag_list).and_return(['red'])
15
+ allow(picture).to receive(:save).and_return(true)
16
+ allow(element).to receive(:save).and_return(true)
17
+ allow(tag).to receive(:taggings).and_return([
18
18
  mock_model(ActsAsTaggableOn::Tagging, taggable: picture),
19
19
  mock_model(ActsAsTaggableOn::Tagging, taggable: element)
20
20
  ])
@@ -22,8 +22,8 @@ module Alchemy
22
22
 
23
23
  it "should replace given tag with new one on all models tagged with tag" do
24
24
  Tag.replace(tag, new_tag)
25
- picture.tag_list.should eq(['green'])
26
- element.tag_list.should eq(['green'])
25
+ expect(picture.tag_list).to eq(['green'])
26
+ expect(element.tag_list).to eq(['green'])
27
27
  end
28
28
  end
29
29
 
@@ -0,0 +1,150 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'The API routes' do
4
+ routes { Alchemy::Engine.routes }
5
+
6
+ describe "for pages" do
7
+ it "has route to show all pages." do
8
+ expect({get: "/api/pages.json"}).to route_to(
9
+ controller: "alchemy/api/pages",
10
+ action: "index",
11
+ format: "json"
12
+ )
13
+ end
14
+
15
+ context 'with missing format' do
16
+ it "defaults to json." do
17
+ expect({get: "/api/pages"}).to route_to(
18
+ controller: "alchemy/api/pages",
19
+ action: "index",
20
+ format: "json"
21
+ )
22
+ end
23
+ end
24
+
25
+ it "has route to show a page by urlname." do
26
+ expect({get: "/api/pages/a-page.json"}).to route_to(
27
+ controller: "alchemy/api/pages",
28
+ action: "show",
29
+ urlname: "a-page",
30
+ format: "json"
31
+ )
32
+ end
33
+
34
+ it "has route to show a page by nested urlname." do
35
+ expect({get: "/api/pages/nested/a-page"}).to route_to(
36
+ controller: "alchemy/api/pages",
37
+ action: "show",
38
+ urlname: "nested/a-page",
39
+ format: "json"
40
+ )
41
+ end
42
+
43
+ context 'with admin namespace' do
44
+ it "routes to api pages controller." do
45
+ expect({get: "/api/admin/pages/8"}).to route_to(
46
+ controller: "alchemy/api/pages",
47
+ action: "show",
48
+ id: "8",
49
+ format: "json"
50
+ )
51
+ end
52
+ end
53
+ end
54
+
55
+ describe 'for elements' do
56
+ it "has route to show all elements." do
57
+ expect({get: "/api/elements.json"}).to route_to(
58
+ controller: "alchemy/api/elements",
59
+ action: "index",
60
+ format: "json"
61
+ )
62
+ end
63
+
64
+ context 'with missing format' do
65
+ it "defaults to json." do
66
+ expect({get: "/api/elements"}).to route_to(
67
+ controller: "alchemy/api/elements",
68
+ action: "index",
69
+ format: "json"
70
+ )
71
+ end
72
+ end
73
+
74
+ it "has route to show all elements for page id." do
75
+ expect({get: "/api/pages/1/elements.json"}).to route_to(
76
+ controller: "alchemy/api/elements",
77
+ action: "index",
78
+ page_id: "1",
79
+ format: "json"
80
+ )
81
+ end
82
+
83
+ it "has route to show all elements for page id and name." do
84
+ expect({get: "/api/pages/1/elements/article.json"}).to route_to(
85
+ controller: "alchemy/api/elements",
86
+ action: "index",
87
+ page_id: "1",
88
+ named: "article",
89
+ format: "json"
90
+ )
91
+ end
92
+
93
+ it "has route to show an element." do
94
+ expect({get: "/api/elements/1.json"}).to route_to(
95
+ controller: "alchemy/api/elements",
96
+ action: "show",
97
+ id: "1",
98
+ format: "json"
99
+ )
100
+ end
101
+ end
102
+
103
+ describe 'for contents' do
104
+ it "has route to show all contents." do
105
+ expect({get: "/api/contents.json"}).to route_to(
106
+ controller: "alchemy/api/contents",
107
+ action: "index",
108
+ format: "json"
109
+ )
110
+ end
111
+
112
+ context 'with missing format' do
113
+ it "defaults to json." do
114
+ expect({get: "/api/contents"}).to route_to(
115
+ controller: "alchemy/api/contents",
116
+ action: "index",
117
+ format: "json"
118
+ )
119
+ end
120
+ end
121
+
122
+ it "has route to show all contents for element id." do
123
+ expect({get: "/api/elements/1/contents.json"}).to route_to(
124
+ controller: "alchemy/api/contents",
125
+ action: "index",
126
+ element_id: "1",
127
+ format: "json"
128
+ )
129
+ end
130
+
131
+ it "has route to show all contents for element id and name." do
132
+ expect({get: "/api/elements/1/contents/headline.json"}).to route_to(
133
+ controller: "alchemy/api/contents",
134
+ action: "show",
135
+ element_id: "1",
136
+ name: "headline",
137
+ format: "json"
138
+ )
139
+ end
140
+
141
+ it "has route to show a content." do
142
+ expect({get: "/api/contents/1.json"}).to route_to(
143
+ controller: "alchemy/api/contents",
144
+ action: "show",
145
+ id: "1",
146
+ format: "json"
147
+ )
148
+ end
149
+ end
150
+ end
@@ -7,9 +7,9 @@ describe "The Routing" do
7
7
  context "for downloads" do
8
8
 
9
9
  it "should have a named route" do
10
- {
10
+ expect({
11
11
  :get => "/attachment/32/download/Presseveranstaltung.pdf"
12
- }.should route_to(
12
+ }).to route_to(
13
13
  :controller => "alchemy/attachments",
14
14
  :action => "download",
15
15
  :id => "32",
@@ -25,9 +25,9 @@ describe "The Routing" do
25
25
  context "one level deep nested" do
26
26
 
27
27
  it "should route to pages show" do
28
- {
28
+ expect({
29
29
  :get => "/products/my-product"
30
- }.should route_to(
30
+ }).to route_to(
31
31
  :controller => "alchemy/pages",
32
32
  :action => "show",
33
33
  :urlname => "products/my-product"
@@ -37,9 +37,9 @@ describe "The Routing" do
37
37
  context "and language" do
38
38
 
39
39
  it "should route to pages show" do
40
- {
40
+ expect({
41
41
  :get => "/de/products/my-product"
42
- }.should route_to(
42
+ }).to route_to(
43
43
  :controller => "alchemy/pages",
44
44
  :action => "show",
45
45
  :urlname => "products/my-product",
@@ -54,9 +54,9 @@ describe "The Routing" do
54
54
  context "two levels deep nested" do
55
55
 
56
56
  it "should route to pages show" do
57
- {
57
+ expect({
58
58
  :get => "/catalog/products/my-product"
59
- }.should route_to(
59
+ }).to route_to(
60
60
  :controller => "alchemy/pages",
61
61
  :action => "show",
62
62
  :urlname => "catalog/products/my-product"
@@ -66,9 +66,9 @@ describe "The Routing" do
66
66
  context "and language" do
67
67
 
68
68
  it "should route to pages show" do
69
- {
69
+ expect({
70
70
  :get => "/de/catalog/products/my-product"
71
- }.should route_to(
71
+ }).to route_to(
72
72
  :controller => "alchemy/pages",
73
73
  :action => "show",
74
74
  :urlname => "catalog/products/my-product",
@@ -83,9 +83,9 @@ describe "The Routing" do
83
83
  context "with a blog date url" do
84
84
 
85
85
  it "should route to pages show" do
86
- {
86
+ expect({
87
87
  :get => "/2011/12/08/my-post"
88
- }.should route_to(
88
+ }).to route_to(
89
89
  :controller => "alchemy/pages",
90
90
  :action => "show",
91
91
  :urlname => "2011/12/08/my-post"
@@ -95,9 +95,9 @@ describe "The Routing" do
95
95
  context "and language" do
96
96
 
97
97
  it "should route to pages show" do
98
- {
98
+ expect({
99
99
  :get => "/de/2011/12/08/my-post"
100
- }.should route_to(
100
+ }).to route_to(
101
101
  :controller => "alchemy/pages",
102
102
  :action => "show",
103
103
  :urlname => "2011/12/08/my-post",
@@ -114,9 +114,9 @@ describe "The Routing" do
114
114
  describe "for displaying pictures" do
115
115
 
116
116
  it "should route to show action" do
117
- {
117
+ expect({
118
118
  :get => "/pictures/3/show/900x300/kitten.jpg"
119
- }.should route_to(
119
+ }).to route_to(
120
120
  :controller => "alchemy/pictures",
121
121
  :action => "show",
122
122
  :id => "3",
@@ -127,9 +127,9 @@ describe "The Routing" do
127
127
  end
128
128
 
129
129
  it "should route to cropped show action" do
130
- {
130
+ expect({
131
131
  :get => "/pictures/3/show/900x300/crop/kitten.jpg"
132
- }.should route_to(
132
+ }).to route_to(
133
133
  :controller => "alchemy/pictures",
134
134
  :action => "show",
135
135
  :id => "3",
@@ -141,9 +141,9 @@ describe "The Routing" do
141
141
  end
142
142
 
143
143
  it "should route to cropped mask show action" do
144
- get(
144
+ expect(get(
145
145
  "/pictures/3/show/300x300/crop/200x50/100x100/kitten.jpg"
146
- ).should route_to(
146
+ )).to route_to(
147
147
  :controller => "alchemy/pictures",
148
148
  :action => "show",
149
149
  :id => "3",
@@ -157,9 +157,9 @@ describe "The Routing" do
157
157
  end
158
158
 
159
159
  it "should route to thumbnail action" do
160
- get(
160
+ expect(get(
161
161
  "/pictures/3/thumbnails/small/kitten.jpg"
162
- ).should route_to(
162
+ )).to route_to(
163
163
  :controller => "alchemy/pictures",
164
164
  :action => "thumbnail",
165
165
  :id => "3",
@@ -170,9 +170,9 @@ describe "The Routing" do
170
170
  end
171
171
 
172
172
  it "should route to cropped thumbnail action" do
173
- get(
173
+ expect(get(
174
174
  "/pictures/3/thumbnails/small/crop/kitten.jpg"
175
- ).should route_to(
175
+ )).to route_to(
176
176
  :controller => "alchemy/pictures",
177
177
  :action => "thumbnail",
178
178
  :id => "3",
@@ -184,9 +184,9 @@ describe "The Routing" do
184
184
  end
185
185
 
186
186
  it "should route to cropped and masked thumbnail" do
187
- get(
187
+ expect(get(
188
188
  "/pictures/3/thumbnails/small/0x0/200x200/kitten.jpg"
189
- ).should route_to(
189
+ )).to route_to(
190
190
  :controller => "alchemy/pictures",
191
191
  :action => "thumbnail",
192
192
  :id => "3",
@@ -199,9 +199,9 @@ describe "The Routing" do
199
199
  end
200
200
 
201
201
  it "should route to zoomed picture" do
202
- get(
202
+ expect(get(
203
203
  "/pictures/3/zoom/kitten.jpg"
204
- ).should route_to(
204
+ )).to route_to(
205
205
  :controller => "alchemy/pictures",
206
206
  :action => "zoom",
207
207
  :id => "3",
@@ -34,12 +34,13 @@ require 'alchemy/test_support/integration_helpers'
34
34
  require 'alchemy/test_support/factories'
35
35
  require 'alchemy/test_support/essence_shared_examples'
36
36
  require_relative "support/hint_examples.rb"
37
+ require_relative "support/transformation_examples.rb"
37
38
 
38
39
  # Configure capybara for integration testing
39
40
  Capybara.default_driver = :rack_test
40
41
  Capybara.default_selector = :css
41
42
  Capybara.register_driver :poltergeist do |app|
42
- Capybara::Poltergeist::Driver.new(app, js_errors: false)
43
+ Capybara::Poltergeist::Driver.new(app)
43
44
  end
44
45
  Capybara.register_driver(:rack_test_translated_header) do |app|
45
46
  Capybara::RackTest::Driver.new(app, headers: { 'HTTP_ACCEPT_LANGUAGE' => 'de' })
@@ -48,7 +49,7 @@ Capybara.javascript_driver = :poltergeist
48
49
  Capybara.ignore_hidden_elements = false
49
50
 
50
51
  RSpec.configure do |config|
51
- config.treat_symbols_as_metadata_keys_with_true_values = true
52
+ config.infer_spec_type_from_file_location!
52
53
  config.run_all_when_everything_filtered = true
53
54
  config.filter_run :focus
54
55
  config.include Alchemy::Engine.routes.url_helpers
@@ -65,7 +66,7 @@ RSpec.configure do |config|
65
66
  end
66
67
 
67
68
  # All specs are running in transactions, but feature specs not.
68
- config.before(:each) do
69
+ config.before(:each) do |example|
69
70
  Alchemy::Site.current = nil
70
71
  ::I18n.locale = :en
71
72
  if example.metadata[:type] == :feature
@@ -80,8 +81,8 @@ RSpec.configure do |config|
80
81
  # After every feature spec the database gets seeded so the next spec can rely on that data.
81
82
  config.append_after(:each) do
82
83
  DatabaseCleaner.clean
83
- if example.metadata[:type] == :feature
84
- Alchemy::Seeder.stub(:puts)
84
+ if RSpec.current_example.metadata[:type] == :feature
85
+ allow(Alchemy::Seeder).to receive(:puts)
85
86
  Alchemy::Seeder.seed!
86
87
  end
87
88
  end
@@ -6,22 +6,22 @@ module Alchemy
6
6
  describe '#hint' do
7
7
  context 'with hint as text' do
8
8
  before do
9
- subject.stub(definition: {'hint' => 'The hint'})
9
+ expect(subject).to receive(:definition).and_return({'hint' => 'The hint'})
10
10
  end
11
11
 
12
12
  it "returns the hint" do
13
- subject.hint.should == 'The hint'
13
+ expect(subject.hint).to eq('The hint')
14
14
  end
15
15
  end
16
16
 
17
17
  context 'with hint set to true' do
18
18
  before do
19
- subject.stub(definition: {'hint' => true})
20
- I18n.stub(t: 'The hint')
19
+ expect(subject).to receive(:definition).and_return({'hint' => true})
20
+ expect(I18n).to receive(:t).and_return('The hint')
21
21
  end
22
22
 
23
23
  it "returns the hint from translation" do
24
- subject.hint.should == 'The hint'
24
+ expect(subject.hint).to eq('The hint')
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ module Alchemy
4
+ shared_examples_for "has image transformations" do
5
+
6
+ describe "#thumbnail_size" do
7
+ context "picture is 300x400 and has no crop size" do
8
+ it "should return the correct recalculated size value" do
9
+ allow(picture).to receive(:image_file_width) { 400 }
10
+ allow(picture).to receive(:image_file_height) { 300 }
11
+
12
+ expect(picture.thumbnail_size()).to eq('111x83')
13
+ end
14
+ end
15
+
16
+ context "picture is 300x400 and has no crop size" do
17
+ it "should return the correct recalculated size value" do
18
+ allow(picture).to receive(:image_file_width) { 300 }
19
+ allow(picture).to receive(:image_file_height) { 400 }
20
+
21
+ expect(picture.thumbnail_size()).to eq('70x93')
22
+ end
23
+ end
24
+
25
+ context "picture has crop_size of 400x300" do
26
+ it "scales to 400x300 if that is the size of the cropped image" do
27
+ allow(picture).to receive(:crop_size) { "400x300" }
28
+ expect(picture.thumbnail_size()).to eq('111x83')
29
+ end
30
+ end
31
+ end
32
+
33
+ describe '#landscape_format?' do
34
+ subject { picture.landscape_format? }
35
+
36
+ context 'image has landscape format' do
37
+ before { allow(picture).to receive(:image_file).and_return double(landscape?: true) }
38
+
39
+ it { is_expected.to be_truthy }
40
+ end
41
+
42
+ context 'image has portrait format' do
43
+ before { allow(picture).to receive(:image_file).and_return double(landscape?: false) }
44
+
45
+ it { is_expected.to be_falsey }
46
+ end
47
+
48
+ it "is aliased as landscape?" do
49
+ expect(picture.respond_to?(:landscape?)).to be_truthy
50
+ end
51
+ end
52
+
53
+ describe '#portrait_format?' do
54
+ subject { picture.portrait_format? }
55
+
56
+ context 'image has portrait format' do
57
+ before { allow(picture).to receive(:image_file).and_return double(portrait?: true) }
58
+
59
+ it { is_expected.to be_truthy }
60
+ end
61
+
62
+ context 'image has landscape format' do
63
+ before { allow(picture).to receive(:image_file).and_return double(portrait?: false) }
64
+
65
+ it { is_expected.to be_falsey }
66
+ end
67
+
68
+ it "is aliased as portrait?" do
69
+ expect(picture.respond_to?(:portrait?)).to be_truthy
70
+ end
71
+ end
72
+
73
+ describe '#square_format?' do
74
+ subject { picture.square_format? }
75
+
76
+ context 'image has square format' do
77
+ before { expect(picture).to receive(:image_file).and_return double(aspect_ratio: 1.0) }
78
+
79
+ it { is_expected.to be_truthy }
80
+ end
81
+
82
+ context 'image has rectangle format' do
83
+ before { expect(picture).to receive(:image_file).and_return double(aspect_ratio: 8.0) }
84
+
85
+ it { is_expected.to be_falsey }
86
+ end
87
+
88
+ it "is aliased as square?" do
89
+ expect(picture.respond_to?(:square?)).to be_truthy
90
+ end
91
+ end
92
+
93
+ describe '#default_mask' do
94
+ before do
95
+ allow(picture).to receive(:image_file_width) { 200 }
96
+ allow(picture).to receive(:image_file_height) { 100 }
97
+ end
98
+
99
+ it "should return a Hash" do
100
+ expect(picture.default_mask({ width: 10, height: 10 })).to be_a(Hash)
101
+ end
102
+
103
+ it "should return a Hash with four keys x1, x2, y1, y2" do
104
+ expect(picture.default_mask({ width: 10, height: 10 }).keys.sort).to eq([:x1, :x2, :y1, :y2])
105
+ end
106
+
107
+ it "should return a Hash where all values are Integer" do
108
+ expect(picture.default_mask({ width: 13, height: 13 }).all? do |k, v|
109
+ v.is_a? Integer
110
+ end).to be_truthy
111
+ end
112
+
113
+ context "making a default cropping mask" do
114
+ it "to 200x50 pixel, the hash should be {x1: 0, y1: 25, x2: 200, y2: 75}" do
115
+ expect(picture.default_mask({ width: 200, height: 50 })).to eq({x1: 0, y1: 25, x2: 200, y2: 75})
116
+ end
117
+
118
+ it "to 0x0 pixel, it should not crop the picture" do
119
+ expect(picture.default_mask({ width: 0, height: 0 })).to eq({x1: 0, y1: 0, x2: 200, y2: 100})
120
+ end
121
+
122
+ it "to 50x100 pixel, the hash should be {x1: 75, y1: 0, x2: 125, y2: 100}" do
123
+ expect(picture.default_mask({ width: 50, height: 100 })).to eq({x1: 75, y1: 0, x2: 125, y2: 100})
124
+ end
125
+
126
+ it "to 50x50 pixel, the hash should be {x1: 50, y1: 0, x2: 150, y2: 100}" do
127
+ expect(picture.default_mask({ width: 50, height: 50 })).to eq({x1: 50, y1: 0, x2: 150, y2: 100})
128
+ end
129
+
130
+ it "to 400x200 pixel, the hash should be {x1: 0, y1: 0, x2: 200, y2: 100}" do
131
+ expect(picture.default_mask({ width: 400, height: 200 })).to eq({x1: 0, y1: 0, x2: 200, y2: 100})
132
+ end
133
+
134
+ it "to 400x100 pixel, the hash should be {x1: 0, y1: 25, x2: 200, y2: 75}" do
135
+ expect(picture.default_mask({ width: 400, height: 100 })).to eq({x1: 0, y1: 25, x2: 200, y2: 75})
136
+ end
137
+
138
+ it "to 200x200 pixel, the hash should be {x1: 50, y1: 0, x2: 150, y2: 100}" do
139
+ expect(picture.default_mask({ width: 200, height: 200 })).to eq({x1: 50, y1: 0, x2: 150, y2: 100})
140
+ end
141
+ end
142
+ end
143
+
144
+ describe "#can_be_cropped_to" do
145
+ context "picture is 300x400 and shall be cropped to 200x100" do
146
+ it "should return true" do
147
+ allow(picture).to receive(:image_file_width) { 400 }
148
+ allow(picture).to receive(:image_file_height) { 300 }
149
+
150
+ expect(picture.can_be_cropped_to("200x100")).to be_truthy
151
+ end
152
+ end
153
+
154
+ context "picture is 300x400 and shall be cropped to 600x500" do
155
+ it "should return false" do
156
+ allow(picture).to receive(:image_file_width) { 400 }
157
+ allow(picture).to receive(:image_file_height) { 300 }
158
+
159
+ expect(picture.can_be_cropped_to("600x500")).to be_falsey
160
+ end
161
+ end
162
+
163
+ context "picture is 300x400 and shall be cropped to 600x500 with upsample set to true" do
164
+ it "should return true" do
165
+ allow(picture).to receive(:image_file_width) { 400 }
166
+ allow(picture).to receive(:image_file_height) { 300 }
167
+
168
+ expect(picture.can_be_cropped_to("600x500", true)).to be_truthy
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end