alchemy_cms 3.3.0.rc1 → 3.3.0.rc2

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 (269) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -2
  3. data/Gemfile +1 -0
  4. data/alchemy_cms.gemspec +6 -6
  5. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -7
  6. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +4 -4
  7. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +51 -5
  8. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +0 -2
  9. data/app/assets/stylesheets/alchemy/elements.scss +2 -2
  10. data/app/controllers/alchemy/admin/elements_controller.rb +2 -0
  11. data/app/controllers/alchemy/admin/pages_controller.rb +11 -3
  12. data/app/controllers/alchemy/admin/pictures_controller.rb +1 -0
  13. data/app/models/alchemy/element.rb +3 -1
  14. data/app/models/alchemy/element/element_contents.rb +2 -7
  15. data/app/models/alchemy/element/presenters.rb +11 -4
  16. data/app/models/alchemy/page.rb +3 -1
  17. data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
  18. data/app/views/alchemy/admin/contents/create.js.erb +0 -1
  19. data/app/views/alchemy/admin/elements/_element_header.html.erb +3 -1
  20. data/app/views/alchemy/admin/elements/order.js.erb +25 -10
  21. data/app/views/alchemy/admin/elements/update.js.erb +1 -2
  22. data/app/views/alchemy/admin/essence_files/assign.js.erb +0 -1
  23. data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -1
  24. data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +0 -1
  25. data/app/views/alchemy/admin/pages/destroy.js.erb +0 -1
  26. data/app/views/alchemy/admin/pages/update.js.erb +6 -4
  27. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +2 -1
  28. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -7
  29. data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -1
  30. data/bin/alchemy +1 -1
  31. data/bin/rspec +3 -2
  32. data/bin/spring +6 -6
  33. data/config/alchemy/config.yml +6 -1
  34. data/lib/alchemy/seeder.rb +9 -3
  35. data/lib/alchemy/version.rb +1 -1
  36. metadata +6 -471
  37. data/spec/controllers/alchemy/admin/attachments_controller_spec.rb +0 -193
  38. data/spec/controllers/alchemy/admin/base_controller_spec.rb +0 -87
  39. data/spec/controllers/alchemy/admin/clipboard_controller_spec.rb +0 -60
  40. data/spec/controllers/alchemy/admin/contents_controller_spec.rb +0 -78
  41. data/spec/controllers/alchemy/admin/dashboard_controller_spec.rb +0 -144
  42. data/spec/controllers/alchemy/admin/elements_controller_spec.rb +0 -496
  43. data/spec/controllers/alchemy/admin/essence_files_controller_spec.rb +0 -76
  44. data/spec/controllers/alchemy/admin/essence_pictures_controller_spec.rb +0 -202
  45. data/spec/controllers/alchemy/admin/languages_controller_spec.rb +0 -73
  46. data/spec/controllers/alchemy/admin/layoutpages_controller_spec.rb +0 -21
  47. data/spec/controllers/alchemy/admin/pages_controller_spec.rb +0 -639
  48. data/spec/controllers/alchemy/admin/pictures_controller_spec.rb +0 -383
  49. data/spec/controllers/alchemy/admin/resources_controller_spec.rb +0 -81
  50. data/spec/controllers/alchemy/admin/tags_controller_spec.rb +0 -63
  51. data/spec/controllers/alchemy/admin/trash_controller_spec.rb +0 -67
  52. data/spec/controllers/alchemy/api/contents_controller_spec.rb +0 -125
  53. data/spec/controllers/alchemy/api/elements_controller_spec.rb +0 -124
  54. data/spec/controllers/alchemy/api/pages_controller_spec.rb +0 -167
  55. data/spec/controllers/alchemy/attachments_controller_spec.rb +0 -64
  56. data/spec/controllers/alchemy/base_controller_spec.rb +0 -106
  57. data/spec/controllers/alchemy/elements_controller_spec.rb +0 -48
  58. data/spec/controllers/alchemy/messages_controller_spec.rb +0 -204
  59. data/spec/controllers/alchemy/on_page_layout_mixin_spec.rb +0 -330
  60. data/spec/controllers/alchemy/pages_controller_spec.rb +0 -343
  61. data/spec/controllers/alchemy/pictures_controller_spec.rb +0 -415
  62. data/spec/dummy/Rakefile +0 -6
  63. data/spec/dummy/app/assets/javascripts/application.js +0 -13
  64. data/spec/dummy/app/assets/stylesheets/application.css +0 -15
  65. data/spec/dummy/app/controllers/admin/events_controller.rb +0 -3
  66. data/spec/dummy/app/controllers/application_controller.rb +0 -15
  67. data/spec/dummy/app/controllers/login_controller.rb +0 -5
  68. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  69. data/spec/dummy/app/mailers/.gitkeep +0 -0
  70. data/spec/dummy/app/models/ability.rb +0 -9
  71. data/spec/dummy/app/models/dummy_model.rb +0 -3
  72. data/spec/dummy/app/models/dummy_user.rb +0 -15
  73. data/spec/dummy/app/models/event.rb +0 -10
  74. data/spec/dummy/app/models/location.rb +0 -3
  75. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_editor.html.erb +0 -11
  76. data/spec/dummy/app/views/alchemy/elements/_all_you_can_eat_view.html.erb +0 -31
  77. data/spec/dummy/app/views/alchemy/elements/_article_editor.html.erb +0 -6
  78. data/spec/dummy/app/views/alchemy/elements/_article_view.html.erb +0 -10
  79. data/spec/dummy/app/views/alchemy/elements/_bild_editor.html.erb +0 -3
  80. data/spec/dummy/app/views/alchemy/elements/_bild_view.html.erb +0 -5
  81. data/spec/dummy/app/views/alchemy/elements/_contactform_editor.html.erb +0 -6
  82. data/spec/dummy/app/views/alchemy/elements/_contactform_view.html.erb +0 -16
  83. data/spec/dummy/app/views/alchemy/elements/_download_editor.html.erb +0 -3
  84. data/spec/dummy/app/views/alchemy/elements/_download_view.html.erb +0 -5
  85. data/spec/dummy/app/views/alchemy/elements/_erb_element_editor.html.erb +0 -3
  86. data/spec/dummy/app/views/alchemy/elements/_erb_element_view.html.erb +0 -5
  87. data/spec/dummy/app/views/alchemy/elements/_header_editor.html.erb +0 -3
  88. data/spec/dummy/app/views/alchemy/elements/_header_view.html.erb +0 -5
  89. data/spec/dummy/app/views/alchemy/elements/_headline_editor.html.erb +0 -1
  90. data/spec/dummy/app/views/alchemy/elements/_headline_view.html.erb +0 -1
  91. data/spec/dummy/app/views/alchemy/elements/_news_editor.html.erb +0 -5
  92. data/spec/dummy/app/views/alchemy/elements/_news_view.html.erb +0 -11
  93. data/spec/dummy/app/views/alchemy/elements/_search_editor.html.erb +0 -1
  94. data/spec/dummy/app/views/alchemy/elements/_search_view.html.erb +0 -4
  95. data/spec/dummy/app/views/alchemy/elements/_slide_editor.html.erb +0 -3
  96. data/spec/dummy/app/views/alchemy/elements/_slide_view.html.erb +0 -5
  97. data/spec/dummy/app/views/alchemy/elements/_slider_editor.html.erb +0 -2
  98. data/spec/dummy/app/views/alchemy/elements/_slider_view.html.erb +0 -4
  99. data/spec/dummy/app/views/alchemy/elements/_text_editor.html.erb +0 -3
  100. data/spec/dummy/app/views/alchemy/elements/_text_view.html.erb +0 -5
  101. data/spec/dummy/app/views/alchemy/page_layouts/_standard.html.erb +0 -15
  102. data/spec/dummy/app/views/layouts/application.html.erb +0 -17
  103. data/spec/dummy/bin/bundle +0 -3
  104. data/spec/dummy/bin/rails +0 -4
  105. data/spec/dummy/bin/rake +0 -4
  106. data/spec/dummy/config.ru +0 -4
  107. data/spec/dummy/config/alchemy/cells.yml +0 -5
  108. data/spec/dummy/config/alchemy/elements.yml +0 -109
  109. data/spec/dummy/config/alchemy/page_layouts.yml +0 -32
  110. data/spec/dummy/config/application.rb +0 -32
  111. data/spec/dummy/config/boot.rb +0 -5
  112. data/spec/dummy/config/database.yml +0 -32
  113. data/spec/dummy/config/environment.rb +0 -5
  114. data/spec/dummy/config/environments/development.rb +0 -41
  115. data/spec/dummy/config/environments/production.rb +0 -77
  116. data/spec/dummy/config/environments/test.rb +0 -43
  117. data/spec/dummy/config/initializers/alchemy.rb +0 -3
  118. data/spec/dummy/config/initializers/assets.rb +0 -11
  119. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  120. data/spec/dummy/config/initializers/cookies_serializer.rb +0 -3
  121. data/spec/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  122. data/spec/dummy/config/initializers/inflections.rb +0 -16
  123. data/spec/dummy/config/initializers/mime_types.rb +0 -4
  124. data/spec/dummy/config/initializers/secret_token.rb +0 -12
  125. data/spec/dummy/config/initializers/session_store.rb +0 -3
  126. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  127. data/spec/dummy/config/locales/kl.yml +0 -2
  128. data/spec/dummy/config/routes.rb +0 -12
  129. data/spec/dummy/config/secrets.yml +0 -22
  130. data/spec/dummy/db/migrate/20121026104128_create_events.rb +0 -20
  131. data/spec/dummy/db/migrate/20130328101418_create_locations.rb +0 -9
  132. data/spec/dummy/db/migrate/20130827094554_alchemy_two_point_six.rb +0 -1
  133. data/spec/dummy/db/migrate/20130828121054_remove_do_not_index_from_alchemy_essence_texts.rb +0 -1
  134. data/spec/dummy/db/migrate/20130828121120_remove_do_not_index_from_alchemy_essence_richtexts.rb +0 -1
  135. data/spec/dummy/db/migrate/20130918201742_add_published_at_to_alchemy_pages.rb +0 -1
  136. data/spec/dummy/db/migrate/20131209225243_create_dummy_users.rb +0 -9
  137. data/spec/dummy/db/migrate/20150122213511_acts_as_taggable_on_migration.acts_as_taggable_on_engine.rb +0 -31
  138. data/spec/dummy/db/migrate/20150122213512_add_missing_unique_indices.acts_as_taggable_on_engine.rb +0 -20
  139. data/spec/dummy/db/migrate/20150122213513_add_taggings_counter_cache_to_tags.acts_as_taggable_on_engine.rb +0 -15
  140. data/spec/dummy/db/migrate/20150122213514_add_missing_taggable_index.acts_as_taggable_on_engine.rb +0 -10
  141. data/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb +0 -7
  142. data/spec/dummy/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +0 -1
  143. data/spec/dummy/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +0 -1
  144. data/spec/dummy/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +0 -1
  145. data/spec/dummy/db/schema.rb +0 -326
  146. data/spec/dummy/db/seeds.rb +0 -1
  147. data/spec/dummy/lib/assets/.gitkeep +0 -0
  148. data/spec/dummy/public/404.html +0 -67
  149. data/spec/dummy/public/422.html +0 -67
  150. data/spec/dummy/public/500.html +0 -66
  151. data/spec/dummy/public/favicon.ico +0 -0
  152. data/spec/dummy/spec/javascripts +0 -1
  153. data/spec/factories.rb +0 -13
  154. data/spec/features/admin/admin_layout_spec.rb +0 -14
  155. data/spec/features/admin/dashboard_spec.rb +0 -81
  156. data/spec/features/admin/edit_elements_feature_spec.rb +0 -36
  157. data/spec/features/admin/language_tree_feature_spec.rb +0 -32
  158. data/spec/features/admin/languages_features_spec.rb +0 -65
  159. data/spec/features/admin/legacy_page_url_management_spec.rb +0 -62
  160. data/spec/features/admin/link_overlay_spec.rb +0 -53
  161. data/spec/features/admin/locale_select_feature_spec.rb +0 -25
  162. data/spec/features/admin/modules_integration_spec.rb +0 -23
  163. data/spec/features/admin/navigation_feature_spec.rb +0 -22
  164. data/spec/features/admin/page_creation_feature_spec.rb +0 -51
  165. data/spec/features/admin/page_editing_feature_spec.rb +0 -135
  166. data/spec/features/admin/picture_library_integration_spec.rb +0 -62
  167. data/spec/features/admin/resources_integration_spec.rb +0 -128
  168. data/spec/features/admin/site_select_feature_spec.rb +0 -31
  169. data/spec/features/admin/tinymce_feature_spec.rb +0 -33
  170. data/spec/features/navigation_spec.rb +0 -9
  171. data/spec/features/page_feature_spec.rb +0 -186
  172. data/spec/features/page_redirects_spec.rb +0 -358
  173. data/spec/features/picture_security_spec.rb +0 -29
  174. data/spec/features/security_spec.rb +0 -24
  175. data/spec/features/translation_integration_spec.rb +0 -51
  176. data/spec/fixtures/500x500.png +0 -0
  177. data/spec/fixtures/80x60.png +0 -0
  178. data/spec/fixtures/animated.gif +0 -0
  179. data/spec/fixtures/image with spaces.png +0 -0
  180. data/spec/fixtures/image.png +0 -0
  181. data/spec/fixtures/image2.PNG +0 -0
  182. data/spec/fixtures/image3.jpeg +0 -0
  183. data/spec/helpers/alchemy/admin/attachments_helper_spec.rb +0 -15
  184. data/spec/helpers/alchemy/admin/base_helper_spec.rb +0 -280
  185. data/spec/helpers/alchemy/admin/contents_helper_spec.rb +0 -46
  186. data/spec/helpers/alchemy/admin/elements_helper_spec.rb +0 -314
  187. data/spec/helpers/alchemy/admin/essences_helper_spec.rb +0 -201
  188. data/spec/helpers/alchemy/admin/navigation_helper_spec.rb +0 -294
  189. data/spec/helpers/alchemy/admin/pages_helper_spec.rb +0 -63
  190. data/spec/helpers/alchemy/admin/pictures_helper_spec.rb +0 -28
  191. data/spec/helpers/alchemy/admin/tags_helper_spec.rb +0 -111
  192. data/spec/helpers/alchemy/base_helper_spec.rb +0 -44
  193. data/spec/helpers/alchemy/elements_block_helper_spec.rb +0 -135
  194. data/spec/helpers/alchemy/elements_helper_spec.rb +0 -326
  195. data/spec/helpers/alchemy/essences_helper_spec.rb +0 -85
  196. data/spec/helpers/alchemy/pages_helper_spec.rb +0 -499
  197. data/spec/helpers/alchemy/picture_url_helpers_spec.rb +0 -78
  198. data/spec/helpers/alchemy/url_helper_spec.rb +0 -200
  199. data/spec/javascripts/alchemy/dialog_spec.coffee +0 -82
  200. data/spec/javascripts/alchemy/link_overlay_spec.coffee +0 -25
  201. data/spec/javascripts/alchemy_integration_spec.coffee +0 -3
  202. data/spec/javascripts/fixtures/select.html +0 -3
  203. data/spec/javascripts/helpers/mock-ajax.js +0 -199
  204. data/spec/javascripts/helpers/test_responses/test_responses.js +0 -1
  205. data/spec/javascripts/support/jasmine.yml +0 -29
  206. data/spec/libraries/auth_accessors_spec.rb +0 -40
  207. data/spec/libraries/config_spec.rb +0 -111
  208. data/spec/libraries/controller_actions_spec.rb +0 -133
  209. data/spec/libraries/i18n_spec.rb +0 -37
  210. data/spec/libraries/kaminari/scoped_pagination_url_helper_spec.rb +0 -30
  211. data/spec/libraries/modules_spec.rb +0 -67
  212. data/spec/libraries/mount_point_spec.rb +0 -77
  213. data/spec/libraries/page_layout_spec.rb +0 -150
  214. data/spec/libraries/paths_spec.rb +0 -15
  215. data/spec/libraries/permissions_spec.rb +0 -260
  216. data/spec/libraries/resource_spec.rb +0 -344
  217. data/spec/libraries/resources_helper_spec.rb +0 -193
  218. data/spec/libraries/shell_spec.rb +0 -121
  219. data/spec/libraries/template_tracker_spec.rb +0 -85
  220. data/spec/libraries/tinymce_spec.rb +0 -111
  221. data/spec/libraries/userstamp_spec.rb +0 -10
  222. data/spec/mailers/alchemy/messages_spec.rb +0 -21
  223. data/spec/models/alchemy/attachment_spec.rb +0 -250
  224. data/spec/models/alchemy/cell_spec.rb +0 -101
  225. data/spec/models/alchemy/content_spec.rb +0 -513
  226. data/spec/models/alchemy/element_spec.rb +0 -862
  227. data/spec/models/alchemy/element_to_page_spec.rb +0 -13
  228. data/spec/models/alchemy/essence_boolean_spec.rb +0 -10
  229. data/spec/models/alchemy/essence_date_spec.rb +0 -28
  230. data/spec/models/alchemy/essence_file_spec.rb +0 -40
  231. data/spec/models/alchemy/essence_html_spec.rb +0 -18
  232. data/spec/models/alchemy/essence_link_spec.rb +0 -10
  233. data/spec/models/alchemy/essence_picture_spec.rb +0 -255
  234. data/spec/models/alchemy/essence_richtext_spec.rb +0 -23
  235. data/spec/models/alchemy/essence_select_spec.rb +0 -10
  236. data/spec/models/alchemy/essence_text_spec.rb +0 -110
  237. data/spec/models/alchemy/language_spec.rb +0 -243
  238. data/spec/models/alchemy/legacy_page_url_spec.rb +0 -21
  239. data/spec/models/alchemy/message_spec.rb +0 -55
  240. data/spec/models/alchemy/page_spec.rb +0 -2108
  241. data/spec/models/alchemy/picture_spec.rb +0 -418
  242. data/spec/models/alchemy/site_spec.rb +0 -168
  243. data/spec/models/alchemy/tag_spec.rb +0 -29
  244. data/spec/models/dummy_model_spec.rb +0 -10
  245. data/spec/requests/alchemy/admin/resources_requests_spec.rb +0 -26
  246. data/spec/requests/alchemy/admin/site_requests_spec.rb +0 -19
  247. data/spec/requests/alchemy/site_requests_spec.rb +0 -18
  248. data/spec/requests/alchemy/sitemap_spec.rb +0 -56
  249. data/spec/routing/api_routing_spec.rb +0 -150
  250. data/spec/routing/routing_spec.rb +0 -340
  251. data/spec/spec_helper.rb +0 -90
  252. data/spec/support/ci/install_phantomjs +0 -7
  253. data/spec/support/hint_examples.rb +0 -28
  254. data/spec/support/test_tweaks.rb +0 -31
  255. data/spec/support/transformation_examples.rb +0 -179
  256. data/spec/tasks/helpers_spec.rb +0 -217
  257. data/spec/views/admin/pictures/show_spec.rb +0 -43
  258. data/spec/views/essences/essence_boolean_editor_spec.rb +0 -32
  259. data/spec/views/essences/essence_boolean_view_spec.rb +0 -23
  260. data/spec/views/essences/essence_date_view_spec.rb +0 -38
  261. data/spec/views/essences/essence_file_editor_spec.rb +0 -59
  262. data/spec/views/essences/essence_file_view_spec.rb +0 -77
  263. data/spec/views/essences/essence_html_view_spec.rb +0 -22
  264. data/spec/views/essences/essence_link_view_spec.rb +0 -41
  265. data/spec/views/essences/essence_picture_editor_spec.rb +0 -80
  266. data/spec/views/essences/essence_picture_view_spec.rb +0 -128
  267. data/spec/views/essences/essence_richtext_view_spec.rb +0 -32
  268. data/spec/views/essences/essence_select_view_spec.rb +0 -11
  269. data/spec/views/essences/essence_text_view_spec.rb +0 -51
@@ -1,343 +0,0 @@
1
- require 'ostruct'
2
- require 'spec_helper'
3
-
4
- module Alchemy
5
- describe PagesController do
6
- let(:default_language) { Language.default }
7
-
8
- let(:default_language_root) do
9
- create :alchemy_page, :language_root,
10
- language: default_language,
11
- name: 'Home',
12
- public: true
13
- end
14
-
15
- let(:page) do
16
- create :alchemy_page, :public,
17
- parent_id: default_language_root.id,
18
- page_layout: 'news',
19
- name: 'News',
20
- urlname: 'news',
21
- language: default_language,
22
- do_not_autogenerate: false
23
- end
24
-
25
- before do
26
- allow(controller).to receive(:signup_required?).and_return(false)
27
- end
28
-
29
- describe "#index" do
30
- before do
31
- default_language_root
32
- allow(Config).to receive(:get) do |arg|
33
- arg == :redirect_index ? false : Config.parameter(arg)
34
- end
35
- end
36
-
37
- it 'renders :show template' do
38
- expect(alchemy_get(:index)).to render_template(:show)
39
- end
40
-
41
- context 'requesting nothing' do
42
- it 'loads default language root page' do
43
- alchemy_get :index
44
- expect(assigns(:page)).to eq(default_language_root)
45
- end
46
-
47
- it 'sets @root_page to default language root' do
48
- alchemy_get(:index)
49
- expect(assigns(:root_page)).to eq(default_language_root)
50
- end
51
-
52
- context 'and the root page is not public' do
53
- before do
54
- default_language_root.update!(public: false)
55
- end
56
-
57
- context 'and redirect_to_public_child is set to false' do
58
- before do
59
- allow(Config).to receive(:get) do |arg|
60
- arg == :redirect_to_public_child ? false : Config.parameter(arg)
61
- end
62
- end
63
-
64
- it 'raises routing error (404)' do
65
- expect {
66
- alchemy_get :index
67
- }.to raise_error(ActionController::RoutingError)
68
- end
69
- end
70
-
71
- context 'and redirect_to_public_child is set to true' do
72
- before do
73
- allow(Config).to receive(:get) do |arg|
74
- arg == :redirect_to_public_child ? true : Config.parameter(arg)
75
- end
76
- end
77
-
78
- context 'that has a public child' do
79
- let!(:public_child) do
80
- create(:alchemy_page, :public, parent: default_language_root)
81
- end
82
-
83
- it 'loads this page' do
84
- alchemy_get :index
85
- expect(assigns(:page)).to eq(public_child)
86
- end
87
- end
88
-
89
- context 'that has a non public child' do
90
- let!(:non_public_child) do
91
- create(:alchemy_page, parent: default_language_root)
92
- end
93
-
94
- context 'that has a public child' do
95
- let!(:public_child) do
96
- create(:alchemy_page, :public, parent: non_public_child)
97
- end
98
-
99
- it 'loads this page' do
100
- alchemy_get :index
101
- expect(assigns(:page)).to eq(public_child)
102
- end
103
- end
104
-
105
- context 'that has a non public child' do
106
- before do
107
- create(:alchemy_page, parent: non_public_child)
108
- end
109
-
110
- it 'raises routing error (404)' do
111
- expect {
112
- alchemy_get :index
113
- }.to raise_error(ActionController::RoutingError)
114
- end
115
- end
116
- end
117
- end
118
- end
119
- end
120
-
121
- context 'requesting non default locale' do
122
- let!(:deutsch) do
123
- create(:alchemy_language, name: 'Deutsch', code: 'de', default: false)
124
- end
125
-
126
- let!(:startseite) do
127
- create :alchemy_page, :language_root,
128
- language: deutsch, public: true, name: 'Startseite'
129
- end
130
-
131
- before do
132
- allow(::I18n).to receive(:default_locale) { 'en' }
133
- end
134
-
135
- it 'loads the root page of that language' do
136
- alchemy_get :index, locale: 'de'
137
- expect(assigns(:page)).to eq(startseite)
138
- end
139
-
140
- it 'sets @root_page to root page of that language' do
141
- alchemy_get :index, locale: 'de'
142
- expect(assigns(:root_page)).to eq(startseite)
143
- end
144
- end
145
- end
146
-
147
- context 'an author' do
148
- let(:unpublic) { create(:alchemy_page, parent: default_language_root) }
149
-
150
- before { authorize_user(:as_author) }
151
-
152
- it "should not be able to visit a unpublic page" do
153
- expect {
154
- alchemy_get :show, urlname: unpublic.urlname
155
- }.to raise_error(ActionController::RoutingError)
156
- end
157
- end
158
-
159
- context "requested for a page containing a feed" do
160
- render_views
161
-
162
- it "should render a rss feed" do
163
- alchemy_get :show, urlname: page.urlname, format: :rss
164
- expect(response.content_type).to eq('application/rss+xml')
165
- end
166
-
167
- it "should include content" do
168
- page.elements.first.content_by_name('news_headline').essence.update_attributes({body: 'Peters Petshop'})
169
- alchemy_get :show, urlname: 'news', format: :rss
170
- expect(response.body).to match /Peters Petshop/
171
- end
172
- end
173
-
174
- context "requested for a page that does not contain a feed" do
175
- it "should render xml 404 error" do
176
- alchemy_get :show, urlname: default_language_root.urlname, format: :rss
177
- expect(response.status).to eq(404)
178
- end
179
- end
180
-
181
- describe "Layout rendering" do
182
- context "with ajax request" do
183
- it "should not render a layout" do
184
- alchemy_xhr :get, :show, urlname: page.urlname
185
- expect(response).to render_template(:show)
186
- expect(response).not_to render_template(layout: 'application')
187
- end
188
- end
189
- end
190
-
191
- describe "url nesting" do
192
- render_views
193
-
194
- let(:catalog) { create(:alchemy_page, :public, name: "Catalog", urlname: 'catalog', parent: default_language_root, language: default_language, visible: true) }
195
- let(:products) { create(:alchemy_page, :public, name: "Products", urlname: 'products', parent: catalog, language: default_language, visible: true) }
196
- let(:product) { create(:alchemy_page, :public, name: "Screwdriver", urlname: 'screwdriver', parent: products, language: default_language, do_not_autogenerate: false, visible: true) }
197
-
198
- before do
199
- allow(Alchemy.user_class).to receive(:admins).and_return(OpenStruct.new(count: 1))
200
- allow(Config).to receive(:get) { |arg| arg == :url_nesting ? true : false }
201
- product.elements.find_by_name('article').contents.essence_texts.first.essence.update_column(:body, 'screwdriver')
202
- end
203
-
204
- context "with correct levelnames in params" do
205
- it "should show the requested page" do
206
- alchemy_get :show, {urlname: 'catalog/products/screwdriver'}
207
- expect(response.status).to eq(200)
208
- expect(response.body).to have_content("screwdriver")
209
- end
210
- end
211
-
212
- context "with incorrect levelnames in params" do
213
- it "should render a 404 page" do
214
- expect {
215
- alchemy_get :show, {urlname: 'catalog/faqs/screwdriver'}
216
- }.to raise_error(ActionController::RoutingError)
217
- end
218
- end
219
- end
220
-
221
- context "when a non-existent page is requested" do
222
- it "should rescue a RoutingError with rendering a 404 page." do
223
- expect {
224
- alchemy_get :show, {urlname: 'doesntexist'}
225
- }.to raise_error(ActionController::RoutingError)
226
- end
227
- end
228
-
229
- describe 'Redirecting to legacy page urls' do
230
- context 'Request a page with legacy url' do
231
- let(:page) { create(:alchemy_page, :public, name: 'New page name') }
232
- let(:second_page) { create(:alchemy_page, :public, name: 'Second Page') }
233
- let(:legacy_page) { create(:alchemy_page, :public, name: 'Legacy Url') }
234
- let!(:legacy_url) { LegacyPageUrl.create(urlname: 'legacy-url', page: page) }
235
- let(:legacy_url2) { LegacyPageUrl.create(urlname: 'legacy-url', page: second_page) }
236
- let(:legacy_url3) { LegacyPageUrl.create(urlname: 'index.php?id=2', page: second_page) }
237
- let(:legacy_url4) { LegacyPageUrl.create(urlname: 'index.php?option=com_content&view=article&id=48&Itemid=69', page: second_page) }
238
- let(:legacy_url5) { LegacyPageUrl.create(urlname: 'nested/legacy/url', page: second_page) }
239
-
240
- it "should redirect permanently to page that belongs to legacy page url even if url has an unknown format & get parameters" do
241
- expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url4.urlname)
242
- alchemy_get :show, urlname: legacy_url4.urlname
243
- expect(response.status).to eq(301)
244
- expect(response).to redirect_to("/#{second_page.urlname}")
245
- end
246
-
247
- it "should not pass query string for legacy routes" do
248
- expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url3.urlname)
249
- alchemy_get :show, urlname: legacy_url4.urlname
250
- expect(URI.parse(response["Location"]).query).to be_nil
251
- end
252
-
253
- it "should only redirect to legacy url if no page was found for urlname" do
254
- alchemy_get :show, urlname: legacy_page.urlname
255
- expect(response.status).to eq(200)
256
- expect(response).not_to redirect_to("/#{page.urlname}")
257
- end
258
-
259
- it "should redirect to last page that has that legacy url" do
260
- expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url2.urlname)
261
- alchemy_get :show, urlname: legacy_url2.urlname
262
- expect(response).to redirect_to("/#{second_page.urlname}")
263
- end
264
-
265
- it "should redirect even if the url has get parameters" do
266
- expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url3.urlname)
267
- alchemy_get :show, urlname: legacy_url3.urlname
268
- expect(response).to redirect_to("/#{second_page.urlname}")
269
- end
270
-
271
- it "should redirect even if the url has nested urlname" do
272
- expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url5.urlname)
273
- alchemy_get :show, urlname: legacy_url5.urlname
274
- expect(response).to redirect_to("/#{second_page.urlname}")
275
- end
276
- end
277
- end
278
-
279
- describe "while redirecting" do
280
- context "not in multi language mode" do
281
- before do
282
- allow_any_instance_of(PagesController).to receive(:multi_language?).and_return(false)
283
- end
284
-
285
- context "with no lang parameter present" do
286
- it "should store defaults language id in the session." do
287
- alchemy_get :show, urlname: page.urlname
288
- expect(controller.session[:alchemy_language_id]).to eq(Language.default.id)
289
- end
290
-
291
- it "should store default language as class var." do
292
- alchemy_get :show, urlname: page.urlname
293
- expect(Language.current).to eq(Language.default)
294
- end
295
- end
296
- end
297
- end
298
-
299
- context 'in an environment with multiple languages' do
300
- let(:klingon) { create(:alchemy_language, :klingon) }
301
-
302
- context 'having two pages with the same url names in different languages' do
303
- render_views
304
-
305
- let!(:klingon_page) { create(:alchemy_page, :public, language: klingon, name: "same-name", do_not_autogenerate: false) }
306
- let!(:english_page) { create(:alchemy_page, :public, language: default_language, name: "same-name") }
307
-
308
- before do
309
- # Set a text in an essence rendered on the page so we can match against that
310
- klingon_page.essence_texts.first.update_column(:body, 'klingon page')
311
- end
312
-
313
- it 'renders the page related to its language' do
314
- alchemy_get :show, {urlname: "same-name", locale: klingon_page.language_code}
315
- expect(response.body).to have_content("klingon page")
316
- end
317
- end
318
- end
319
-
320
- describe '#page_etag' do
321
- subject { controller.send(:page_etag) }
322
-
323
- before do
324
- expect(page).to receive(:cache_key).and_return('aaa')
325
- controller.instance_variable_set('@page', page)
326
- end
327
-
328
- it "returns the etag for response headers" do
329
- expect(subject).to eq('aaa')
330
- end
331
-
332
- context 'with user logged in' do
333
- before do
334
- authorize_user(mock_model(Alchemy.user_class, cache_key: 'bbb'))
335
- end
336
-
337
- it "returns another etag for response headers" do
338
- expect(subject).to eq('aaabbb')
339
- end
340
- end
341
- end
342
- end
343
- end
@@ -1,415 +0,0 @@
1
- require 'spec_helper'
2
-
3
- # Fixes missing method tempfile error
4
- class Rack::Test::UploadedFile
5
- attr_reader :tempfile
6
- end
7
-
8
- module Alchemy
9
- describe PicturesController do
10
- let(:public_page) { create(:alchemy_page, :public, restricted: false) }
11
- let(:restricted_page) { create(:alchemy_page, :public, restricted: true) }
12
- let(:element) { create(:alchemy_element, page: public_page, name: 'bild', create_contents_after_create: true) }
13
- let(:restricted_element) { create(:alchemy_element, page: restricted_page, name: 'bild', create_contents_after_create: true) }
14
- let(:picture) { create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/image.png', __FILE__), 'image/png')) }
15
-
16
- describe '#zoom' do
17
- let(:picture) do
18
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/80x60.png', __FILE__), 'image/png'))
19
- end
20
-
21
- it "renders the original image without any resizing" do
22
- alchemy_get :zoom, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
23
- expect(response.body[0x10..0x18].unpack('NN')).to eq([80, 60])
24
- end
25
-
26
- context "Requesting a picture that is assigned with restricted pages only" do
27
- before do
28
- essence = restricted_element.contents.where(name: 'image').first.essence
29
- essence.picture_id = picture.id
30
- essence.save
31
- end
32
-
33
- context "as guest user" do
34
- it "should not render the picture, but redirect to login path" do
35
- alchemy_get :zoom, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
36
- expect(response.status).to eq(302)
37
- expect(response).to redirect_to(Alchemy.login_path)
38
- end
39
- end
40
-
41
- context "as member user" do
42
- before do
43
- authorize_user(build(:alchemy_dummy_user))
44
- end
45
-
46
- it "should render the picture" do
47
- alchemy_get :zoom, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
48
- expect(response.status).to eq(200)
49
- end
50
- end
51
- end
52
- end
53
-
54
- describe '#show' do
55
- it "skips the session cookie" do
56
- expect {
57
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
58
- }.to change {
59
- request.session_options.fetch(:skip) { false }
60
- }.to(true)
61
- end
62
-
63
- context "Requesting a picture with tempared security token" do
64
- it "should render status 400" do
65
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: '14m4b4dh4ck3r'
66
- expect(response.status).to eq(400)
67
- end
68
- end
69
-
70
- context "Requesting a picture with another format then the original image" do
71
- it "should convert the picture format" do
72
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :jpeg, sh: picture.security_token
73
- expect(response.content_type).to eq('image/jpeg')
74
- end
75
- end
76
-
77
- context "Requesting a picture with not allowed format" do
78
- it "should raise error" do
79
- expect {
80
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :wim, sh: picture.security_token
81
- }.to raise_error(ActionController::UnknownFormat)
82
- end
83
- end
84
-
85
- context "Requesting a picture that has no image file attached" do
86
- before do
87
- expect(picture).to receive(:image_file).and_return(nil)
88
- expect(Picture).to receive(:find).and_return(picture)
89
- end
90
-
91
- it "raises missing file error" do
92
- expect {
93
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
94
- }.to raise_error(Alchemy::MissingImageFileError)
95
- end
96
- end
97
-
98
- context "Requesting a picture with crop_from and crop_size parameters" do
99
- let(:picture) do
100
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/500x500.png', __FILE__), 'image/png'))
101
- end
102
-
103
- it "renders the cropped picture" do
104
- alchemy_get :show, id: picture.id, name: picture.urlname, crop: 'crop', size: '123x44', crop_size: '123x44',
105
- crop_from: '0x0', format: :png,
106
- sh: picture.security_token(crop_size: '123x44', crop_from: '0x0', crop: true, size: '123x44')
107
- expect(response.body[0x10..0x18].unpack('NN')).to eq([123, 44])
108
- end
109
- end
110
-
111
- context "Requesting a picture with crop_from and crop_size parameters with different size param" do
112
- let(:picture) do
113
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/500x500.png', __FILE__), 'image/png'))
114
- end
115
-
116
- it "renders the cropped picture" do
117
- alchemy_get :show,
118
- id: picture.id,
119
- name: picture.urlname,
120
- crop: 'crop',
121
- size: '100x100',
122
- crop_size: '200x200',
123
- crop_from: '0x0',
124
- format: :png,
125
- sh: picture.security_token(
126
- crop_size: '200x200',
127
- crop_from: '0x0',
128
- crop: true,
129
- size: '100x100'
130
- )
131
- expect(response.body[0x10..0x18].unpack('NN')).to eq [100, 100]
132
- end
133
- end
134
-
135
- context "Requesting a picture with crop_from and crop_size parameters with larger size param" do
136
- let(:picture) do
137
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/500x500.png', __FILE__), 'image/png'))
138
- end
139
-
140
- it "renders the cropped picture without upsampling" do
141
- alchemy_get :show,
142
- id: picture.id,
143
- name: picture.urlname,
144
- crop: 'crop',
145
- size: '400x400',
146
- crop_size: '200x200',
147
- crop_from: '0x0',
148
- format: :png,
149
- sh: picture.security_token(
150
- crop_size: '200x200',
151
- crop_from: '0x0',
152
- crop: true,
153
- size: '400x400'
154
- )
155
- expect(response.body[0x10..0x18].unpack('NN')).to eq [200, 200]
156
- end
157
- end
158
-
159
- context "Requesting a picture with crop_from and crop_size parameters with larger size param and upsample set" do
160
- let(:picture) do
161
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/500x500.png', __FILE__), 'image/png'))
162
- end
163
-
164
- it "renders the cropped picture with upsampling" do
165
- alchemy_get :show,
166
- id: picture.id,
167
- name: picture.urlname,
168
- crop: 'crop',
169
- size: '400x400',
170
- crop_size: '200x200',
171
- crop_from: '0x0',
172
- format: :png,
173
- upsample: 'true',
174
- sh: picture.security_token(
175
- crop_size: '200x200',
176
- crop_from: '0x0',
177
- crop: true,
178
- size: '400x400',
179
- upsample: 'true'
180
- )
181
- expect(response.body[0x10..0x18].unpack('NN')).to eq [400, 400]
182
- end
183
- end
184
-
185
- context "Requesting a picture that is not assigned with any page" do
186
- it "should render the picture" do
187
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
188
- expect(response.status).to eq(200)
189
- end
190
- end
191
-
192
- context "Requesting a picture that is assigned on restricted and non-restricted pages" do
193
- before do
194
- essence = element.contents.where(name: 'image').first.essence
195
- essence.picture_id = picture.id
196
- essence.save
197
-
198
- essence = restricted_element.contents.where(name: 'image').first.essence
199
- essence.picture_id = picture.id
200
- essence.save
201
- end
202
-
203
- context "as guest user" do
204
- it "should render the picture" do
205
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
206
- expect(response.status).to eq(200)
207
- end
208
- end
209
- end
210
-
211
- context "Requesting a picture that is assigned with restricted pages only" do
212
- before do
213
- essence = restricted_element.contents.where(name: 'image').first.essence
214
- essence.picture_id = picture.id
215
- essence.save
216
- end
217
-
218
- context "as guest user" do
219
- it "should not render the picture, but redirect to login path" do
220
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
221
- expect(response.status).to eq(302)
222
- expect(response).to redirect_to(Alchemy.login_path)
223
- end
224
- end
225
-
226
- context "as member user" do
227
- before do
228
- authorize_user(build(:alchemy_dummy_user))
229
- end
230
-
231
- it "should render the picture" do
232
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
233
- expect(response.status).to eq(200)
234
- end
235
- end
236
- end
237
-
238
- context 'requesting an animated gif with different format' do
239
- let(:image) do
240
- fixture_file_upload(
241
- File.expand_path('../../../fixtures/animated.gif', __FILE__),
242
- 'image/gif'
243
- )
244
- end
245
-
246
- let(:picture) { build_stubbed(:alchemy_picture, image_file: image) }
247
-
248
- before do
249
- expect(image).to receive(:ext) { 'gif' }
250
- expect(picture).to receive(:image_file) { image }
251
- expect(Alchemy::Picture).to receive(:find) { picture }
252
- end
253
-
254
- it 'flattens the gif before converting the format.' do
255
- expect(image).to receive(:encode).with('png', '-flatten') { double(data: '') }
256
- alchemy_get :show, id: picture.id, name: picture.urlname,
257
- format: 'png', sh: picture.security_token
258
- end
259
- end
260
- end
261
-
262
- describe '#thumbnail' do
263
- let(:picture) do
264
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/500x500.png', __FILE__), 'image/png'))
265
- end
266
-
267
- context 'with size param set to small' do
268
- it "resizes the image to 80x60 while maintaining aspect ratio" do
269
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'small', format: :png, sh: picture.security_token(size: 'small')
270
- expect(response.body[0x10..0x18].unpack('NN')).to eq([60, 60])
271
- end
272
- end
273
-
274
- context 'with size param set to medium' do
275
- it "resizes the image to 160x120 while maintaining aspect ratio" do
276
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'medium', format: :png, sh: picture.security_token(size: 'medium')
277
- expect(response.body[0x10..0x18].unpack('NN')).to eq([120, 120])
278
- end
279
- end
280
-
281
- context 'with size param set to large' do
282
- it "resizes the image to 240x180 while maintaining aspect ratio" do
283
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'large', format: :png, sh: picture.security_token(size: 'large')
284
- expect(response.body[0x10..0x18].unpack('NN')).to eq([180, 180])
285
- end
286
- end
287
-
288
- context 'with size param set to nil' do
289
- it "resizes the image to 111x93 while maintaining aspect ratio" do
290
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
291
- expect(response.body[0x10..0x18].unpack('NN')).to eq([93, 93])
292
- end
293
- end
294
-
295
- context 'with size param set to another value' do
296
- it "resizes the image to the given size while maintaining aspect ratio" do
297
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: '33x33', format: :png, sh: picture.security_token(size: '33x33')
298
- expect(response.body[0x10..0x18].unpack('NN')).to eq([33, 33])
299
- end
300
- end
301
-
302
- context "Requesting a picture that is assigned with restricted pages only" do
303
- before do
304
- essence = restricted_element.contents.where(name: 'image').first.essence
305
- essence.picture_id = picture.id
306
- essence.save
307
- end
308
-
309
- context "as guest user" do
310
- it "should not render the picture, but redirect to login path" do
311
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
312
- expect(response.status).to eq(302)
313
- expect(response).to redirect_to(Alchemy.login_path)
314
- end
315
- end
316
-
317
- context "as member user" do
318
- before do
319
- authorize_user(build(:alchemy_dummy_user))
320
- end
321
-
322
- it "should render the picture" do
323
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
324
- expect(response.status).to eq(200)
325
- end
326
- end
327
- end
328
- end
329
-
330
- describe 'Picture processing' do
331
- let(:big_picture) do
332
- create(:alchemy_picture, image_file: fixture_file_upload(File.expand_path('../../../fixtures/80x60.png', __FILE__), 'image/png'))
333
- end
334
-
335
- context "with crop and size parameters" do
336
- it "should return a cropped image." do
337
- options = {
338
- crop: 'crop',
339
- size: '10x10',
340
- format: 'png'
341
- }
342
- alchemy_get :show, options.merge(id: big_picture.id, name: big_picture.urlname, sh: big_picture.security_token(options))
343
- expect(response.body[0x10..0x18].unpack('NN')).to eq([10, 10])
344
- end
345
-
346
- context "without a full size specification" do
347
- it "should raise an error" do
348
- options = {
349
- crop: 'crop',
350
- size: '10',
351
- format: 'png'
352
- }
353
- expect {
354
- alchemy_get :show, options.merge(id: big_picture.id, name: big_picture.urlname, sh: big_picture.security_token(options))
355
- }.to raise_error ArgumentError
356
- end
357
- end
358
-
359
- context "without upsample parameter" do
360
- it "should not upsample the image." do
361
- options = {
362
- crop: 'crop',
363
- size: '10x10',
364
- format: 'png'
365
- }
366
- alchemy_get :show, options.merge(id: picture.id, name: big_picture.urlname, sh: picture.security_token(options))
367
- expect(response.body[0x10..0x18].unpack('NN')).to eq([1, 1])
368
- end
369
- end
370
-
371
- context "and with upsample true" do
372
- it "should return an upsampled image." do
373
- options = {
374
- crop: 'crop',
375
- size: '10x10',
376
- upsample: 'true',
377
- format: 'png'
378
- }
379
- alchemy_get :show, options.merge(id: picture.id, name: big_picture.urlname, sh: picture.security_token(options))
380
- expect(response.body[0x10..0x18].unpack('NN')).to eq([10, 10])
381
- end
382
- end
383
- end
384
-
385
- context "without crop but with size parameter" do
386
- it "should resize the image preserving aspect ratio" do
387
- options = {
388
- size: '40x40',
389
- format: 'png'
390
- }
391
- alchemy_get :show, options.merge(id: big_picture.id, name: big_picture.urlname, sh: big_picture.security_token(options))
392
- expect(response.body[0x10..0x18].unpack('NN')).to eq([40, 30])
393
- end
394
-
395
- it "should resize the image inferring the height if not given" do
396
- options = {
397
- size: '40x',
398
- format: 'png'
399
- }
400
- alchemy_get :show, options.merge(id: big_picture.id, name: big_picture.urlname, sh: big_picture.security_token(options))
401
- expect(response.body[0x10..0x18].unpack('NN')).to eq([40, 30])
402
- end
403
-
404
- it "should resize the image inferring the width if not given" do
405
- options = {
406
- size: 'x30',
407
- format: 'png'
408
- }
409
- alchemy_get :show, options.merge(id: big_picture.id, name: big_picture.urlname, sh: big_picture.security_token(options))
410
- expect(response.body[0x10..0x18].unpack('NN')).to eq([40, 30])
411
- end
412
- end
413
- end
414
- end
415
- end