alchemy_cms 3.2.0.beta → 3.2.0.rc1

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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +661 -863
  3. data/README.md +5 -63
  4. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +11 -10
  5. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +6 -0
  6. data/app/assets/stylesheets/alchemy/_extends.scss +0 -6
  7. data/app/assets/stylesheets/alchemy/_mixins.scss +6 -0
  8. data/app/assets/stylesheets/alchemy/buttons.scss +1 -1
  9. data/app/assets/stylesheets/alchemy/elements.scss +1 -1
  10. data/app/assets/stylesheets/alchemy/menubar.scss +1 -1
  11. data/app/assets/stylesheets/alchemy/selects.scss +5 -1
  12. data/app/assets/stylesheets/alchemy/upload.scss +1 -1
  13. data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
  14. data/app/controllers/alchemy/base_controller.rb +4 -57
  15. data/app/controllers/alchemy/messages_controller.rb +2 -2
  16. data/app/controllers/alchemy/pages_controller.rb +22 -31
  17. data/app/controllers/alchemy/pictures_controller.rb +2 -2
  18. data/app/helpers/alchemy/admin/base_helper.rb +7 -0
  19. data/app/helpers/alchemy/admin/elements_helper.rb +31 -15
  20. data/app/helpers/alchemy/admin/pages_helper.rb +17 -0
  21. data/app/helpers/alchemy/base_helper.rb +0 -28
  22. data/app/helpers/alchemy/pages_helper.rb +18 -12
  23. data/app/helpers/alchemy/url_helper.rb +2 -2
  24. data/app/models/alchemy/cell.rb +1 -1
  25. data/app/models/alchemy/content/factory.rb +12 -6
  26. data/app/models/alchemy/element.rb +3 -3
  27. data/app/models/alchemy/element/definitions.rb +1 -1
  28. data/app/models/alchemy/element_to_page.rb +7 -0
  29. data/app/models/alchemy/language.rb +1 -1
  30. data/app/models/alchemy/page.rb +8 -1
  31. data/app/models/alchemy/page/page_cells.rb +2 -2
  32. data/app/models/alchemy/page/page_elements.rb +23 -5
  33. data/app/models/alchemy/page/page_natures.rb +3 -3
  34. data/app/models/alchemy/page/page_scopes.rb +1 -1
  35. data/app/models/alchemy/picture.rb +1 -1
  36. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +1 -1
  37. data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
  38. data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
  39. data/app/views/alchemy/breadcrumb/_page.html.erb +3 -2
  40. data/app/views/alchemy/breadcrumb/_separator.html.erb +1 -0
  41. data/app/views/alchemy/breadcrumb/_wrapper.html.erb +13 -0
  42. data/app/views/alchemy/language_links/_language.html.erb +1 -1
  43. data/app/views/alchemy/navigation/_link.html.erb +1 -1
  44. data/app/views/alchemy/pages/show.rss.builder +5 -7
  45. data/app/views/layouts/alchemy/admin.html.erb +5 -0
  46. data/config/routes.rb +13 -10
  47. data/lib/alchemy/configuration_methods.rb +29 -0
  48. data/lib/alchemy/controller_actions.rb +12 -4
  49. data/lib/alchemy/engine.rb +3 -0
  50. data/lib/alchemy/errors.rb +1 -1
  51. data/lib/alchemy/essence.rb +14 -12
  52. data/lib/alchemy/on_page_layout.rb +58 -0
  53. data/lib/alchemy/page_layout.rb +1 -1
  54. data/lib/alchemy/permissions.rb +21 -16
  55. data/lib/alchemy/routing_constraints.rb +49 -0
  56. data/lib/alchemy/seeder.rb +4 -2
  57. data/lib/alchemy/ssl_protection.rb +30 -0
  58. data/lib/alchemy/test_support/essence_shared_examples.rb +118 -25
  59. data/lib/alchemy/test_support/factories.rb +5 -8
  60. data/lib/alchemy/test_support/integration_helpers.rb +16 -10
  61. data/lib/alchemy/upgrader/three_point_two.rb +34 -4
  62. data/lib/alchemy/version.rb +1 -1
  63. data/lib/rails/generators/alchemy/{scaffold → install}/files/_article_editor.html.erb +0 -0
  64. data/lib/rails/generators/alchemy/{scaffold → install}/files/_article_view.html.erb +0 -0
  65. data/lib/rails/generators/alchemy/{scaffold → install}/files/_standard.html.erb +0 -0
  66. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.de.yml +0 -0
  67. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.elements.css.scss +0 -0
  68. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.en.yml +0 -0
  69. data/lib/rails/generators/alchemy/{scaffold → install}/files/alchemy.es.yml +0 -0
  70. data/lib/rails/generators/alchemy/{scaffold → install}/files/application.html.erb +0 -0
  71. data/lib/rails/generators/alchemy/install/install_generator.rb +69 -0
  72. data/lib/rails/generators/alchemy/{scaffold/files/elements.yml → install/templates/elements.yml.tt} +2 -0
  73. data/lib/rails/generators/alchemy/{scaffold → install}/templates/page_layouts.yml.tt +2 -0
  74. data/lib/rails/generators/alchemy/views/views_generator.rb +41 -0
  75. data/lib/rails/templates/alchemy.rb +2 -2
  76. data/lib/tasks/alchemy/db.rake +0 -5
  77. data/lib/tasks/alchemy/install.rake +10 -5
  78. data/lib/tasks/alchemy/tidy.rake +2 -0
  79. data/spec/controllers/admin/attachments_controller_spec.rb +1 -1
  80. data/spec/controllers/admin/clipboard_controller_spec.rb +1 -1
  81. data/spec/controllers/admin/contents_controller_spec.rb +1 -1
  82. data/spec/controllers/admin/dashboard_controller_spec.rb +2 -2
  83. data/spec/controllers/admin/elements_controller_spec.rb +1 -1
  84. data/spec/controllers/admin/essence_files_controller_spec.rb +1 -1
  85. data/spec/controllers/admin/essence_pictures_controller_spec.rb +1 -1
  86. data/spec/controllers/admin/languages_controller_spec.rb +1 -1
  87. data/spec/controllers/admin/layoutpages_controller_spec.rb +1 -1
  88. data/spec/controllers/admin/pages_controller_spec.rb +4 -4
  89. data/spec/controllers/admin/pictures_controller_spec.rb +1 -1
  90. data/spec/controllers/admin/resources_controller_spec.rb +1 -1
  91. data/spec/controllers/admin/trash_controller_spec.rb +1 -1
  92. data/spec/controllers/alchemy/admin/tags_controller_spec.rb +1 -1
  93. data/spec/controllers/attachments_controller_spec.rb +1 -1
  94. data/spec/controllers/base_controller_spec.rb +22 -0
  95. data/spec/controllers/elements_controller_spec.rb +1 -1
  96. data/spec/controllers/pages_controller_spec.rb +15 -16
  97. data/spec/controllers/pictures_controller_spec.rb +212 -162
  98. data/spec/dummy/app/controllers/login_controller.rb +5 -0
  99. data/spec/dummy/app/models/dummy_model.rb +3 -0
  100. data/spec/dummy/config/alchemy/cells.yml +4 -1
  101. data/spec/dummy/config/alchemy/elements.yml +8 -0
  102. data/spec/dummy/config/alchemy/page_layouts.yml +5 -1
  103. data/spec/dummy/config/routes.rb +1 -2
  104. data/spec/dummy/db/migrate/20150412103152_create_dummy_model.rb +7 -0
  105. data/spec/dummy/db/schema.rb +30 -26
  106. data/spec/features/admin/dashboard_spec.rb +11 -9
  107. data/spec/features/admin/language_tree_feature_spec.rb +5 -6
  108. data/spec/features/admin/legacy_page_url_management_spec.rb +1 -1
  109. data/spec/features/admin/link_overlay_spec.rb +1 -1
  110. data/spec/features/admin/locale_select_feature_spec.rb +1 -1
  111. data/spec/features/admin/modules_integration_spec.rb +1 -1
  112. data/spec/features/admin/navigation_feature_spec.rb +1 -1
  113. data/spec/features/admin/page_creation_feature_spec.rb +1 -1
  114. data/spec/features/admin/page_editing_feature_spec.rb +3 -3
  115. data/spec/features/admin/picture_library_integration_spec.rb +1 -1
  116. data/spec/features/admin/resources_integration_spec.rb +1 -1
  117. data/spec/features/admin/site_select_feature_spec.rb +32 -0
  118. data/spec/features/admin/tinymce_feature_spec.rb +1 -3
  119. data/spec/features/page_feature_spec.rb +36 -27
  120. data/spec/features/security_spec.rb +1 -1
  121. data/spec/features/translation_integration_spec.rb +3 -3
  122. data/spec/helpers/admin/elements_helper_spec.rb +103 -26
  123. data/spec/helpers/admin/pages_helper_spec.rb +32 -1
  124. data/spec/helpers/base_helper_spec.rb +0 -45
  125. data/spec/helpers/pages_helper_spec.rb +18 -17
  126. data/spec/helpers/url_helper_spec.rb +8 -5
  127. data/spec/libraries/controller_actions_spec.rb +2 -2
  128. data/spec/libraries/on_page_layout_spec.rb +112 -0
  129. data/spec/libraries/page_layout_spec.rb +5 -1
  130. data/spec/libraries/permissions_spec.rb +13 -15
  131. data/spec/models/cell_spec.rb +4 -0
  132. data/spec/models/content_spec.rb +6 -0
  133. data/spec/models/dummy_model_spec.rb +11 -0
  134. data/spec/models/element_spec.rb +6 -1
  135. data/spec/models/element_to_page_spec.rb +14 -0
  136. data/spec/models/page_spec.rb +111 -19
  137. data/spec/routing/routing_spec.rb +120 -101
  138. data/spec/spec_helper.rb +3 -3
  139. metadata +36 -21
  140. data/app/views/alchemy/breadcrumb/_spacer.html.erb +0 -1
  141. data/lib/alchemy/capistrano.rb +0 -230
  142. data/lib/alchemy/test_support/auth_helpers.rb +0 -35
  143. data/lib/rails/generators/alchemy/deploy_script/deploy_script_generator.rb +0 -90
  144. data/lib/rails/generators/alchemy/deploy_script/templates/deploy.rb.tt +0 -113
  145. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +0 -63
  146. data/spec/dummy/app/controllers/errors_controller.rb +0 -5
@@ -2,6 +2,7 @@
2
2
  #
3
3
  # For further informations please see http://guides.alchemy-cms.com/create_elements.html
4
4
 
5
+ <%- unless @options[:skip_demo_files] -%>
5
6
  - name: article
6
7
  hint: true
7
8
  unique: true
@@ -17,3 +18,4 @@
17
18
  type: EssenceRichtext
18
19
  default: :article_text
19
20
  hint: true
21
+ <%- end -%>
@@ -2,7 +2,9 @@
2
2
  #
3
3
  # For further informations please see http://guides.alchemy-cms.com/create_page_layouts.html
4
4
 
5
+ <%- unless @options[:skip_demo_files] -%>
5
6
  - name: <%= Alchemy::Config.get(:default_language)['page_layout'] %>
6
7
  unique: true
7
8
  elements: [article]
8
9
  autogenerate: [article]
10
+ <%- end -%>
@@ -0,0 +1,41 @@
1
+ require 'rails'
2
+
3
+ module Alchemy
4
+ module Generators
5
+ class ViewsGenerator < ::Rails::Generators::Base
6
+ ALCHEMY_VIEWS = %w(breadcrumb language_links messages navigation)
7
+
8
+ desc "Generates Alchemy views for #{ALCHEMY_VIEWS.to_sentence}."
9
+
10
+ class_option :only,
11
+ type: :array,
12
+ default: nil,
13
+ desc: "List of views to copy. Available views are #{ALCHEMY_VIEWS.to_sentence}."
14
+
15
+ class_option :except,
16
+ type: :array,
17
+ default: nil,
18
+ desc: "List of views not to copy. Available views are #{ALCHEMY_VIEWS.to_sentence}."
19
+
20
+ source_root File.expand_path("../../../../../app/views/alchemy", File.dirname(__FILE__))
21
+
22
+ def copy_alchemy_views
23
+ views_to_copy.each do |dir|
24
+ directory dir, Rails.root.join('app/views/alchemy', dir)
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def views_to_copy
31
+ if @options['except']
32
+ ALCHEMY_VIEWS - @options['except']
33
+ elsif @options['only']
34
+ ALCHEMY_VIEWS.select { |v| @options['only'].include?(v) }
35
+ else
36
+ ALCHEMY_VIEWS
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,7 +1,7 @@
1
1
  # This rails template installs Alchemy and all depending gems.
2
2
  require File.expand_path("../../../alchemy/version", __FILE__)
3
3
 
4
- gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: "master"
4
+ gem "alchemy_cms", github: "AlchemyCMS/alchemy_cms", branch: "3.2-stable"
5
5
  gem "alchemy-devise", github: "AlchemyCMS/alchemy-devise", branch: "master"
6
6
 
7
- gem "capistrano", "~> 2.15.5", group: "development"
7
+ gem "capistrano-alchemy", github: "AlchemyCMS/capistrano-alchemy", branch: "master", group: "development"
@@ -1,14 +1,9 @@
1
1
  require 'shellwords'
2
- require 'alchemy/seeder'
3
2
  require 'alchemy/tasks/helpers'
4
3
  include Alchemy::Tasks::Helpers
5
4
 
6
5
  namespace :alchemy do
7
6
  namespace :db do
8
- desc "Seeds your database with essential data for Alchemy CMS."
9
- task :seed => :environment do
10
- Alchemy::Seeder.seed!
11
- end
12
7
 
13
8
  desc "Dumps the database to STDOUT (Pass DUMP_FILENAME to store the dump into a file)."
14
9
  task :dump => :environment do
@@ -20,26 +20,32 @@ class Alchemy::InstallTask < Thor
20
20
  match = "default_language:\n code: #{code}\n name: #{name}"
21
21
  end
22
22
  end
23
- end
24
23
 
24
+ def inject_seeder
25
+ append_file "./db/seeds.rb", "Alchemy::Seeder.seed!\n"
26
+ end
27
+ end
25
28
  end
26
29
 
27
30
  namespace :alchemy do
28
31
 
29
32
  desc "Installs Alchemy CMS into your app."
30
33
  task :install do
34
+ install_helper = Alchemy::InstallTask.new
35
+
31
36
  unless ENV['from_binary']
32
37
  puts "\nAlchemy Installer"
33
38
  puts "-----------------"
34
39
  end
35
40
  Rake::Task["alchemy:mount"].invoke
36
- system("rails g alchemy:scaffold#{ ENV['from_binary'] ? ' --force' : '' }") || exit!(1)
37
- Alchemy::InstallTask.new.set_primary_language
41
+ system("rails g alchemy:install#{ ENV['from_binary'] ? ' --force' : '' }") || exit!(1)
42
+ install_helper.set_primary_language
38
43
  Rake::Task["db:create"].invoke
39
44
  # We can't invoke this rake task, because Rails will use wrong engine names otherwise
40
45
  `bundle exec rake railties:install:migrations`
41
46
  Rake::Task["db:migrate"].invoke
42
- Rake::Task["alchemy:db:seed"].invoke
47
+ install_helper.inject_seeder
48
+ Rake::Task["db:seed"].invoke
43
49
  unless ENV['from_binary']
44
50
  puts "\nAlchemy successfully installed."
45
51
  puts "\nNow start the server with:"
@@ -52,5 +58,4 @@ namespace :alchemy do
52
58
  task :mount do
53
59
  Alchemy::InstallTask.new.inject_routes
54
60
  end
55
-
56
61
  end
@@ -1,3 +1,5 @@
1
+ require 'alchemy/shell'
2
+
1
3
  namespace :alchemy do
2
4
  namespace :tidy do
3
5
 
@@ -5,7 +5,7 @@ module Alchemy
5
5
  let(:attachment) { build_stubbed(:attachment) }
6
6
 
7
7
  before do
8
- sign_in(admin_user)
8
+ authorize_user(:as_admin)
9
9
  end
10
10
 
11
11
  describe "#index" do
@@ -7,7 +7,7 @@ module Alchemy
7
7
  let(:another_element) { build_stubbed(:element, page: public_page) }
8
8
 
9
9
  before do
10
- sign_in(admin_user)
10
+ authorize_user(:as_admin)
11
11
  session[:alchemy_clipboard] = {}
12
12
  end
13
13
 
@@ -6,7 +6,7 @@ module Alchemy
6
6
  let(:content) { build_stubbed(:content, element: element) }
7
7
 
8
8
  before do
9
- sign_in(admin_user)
9
+ authorize_user(:as_admin)
10
10
  end
11
11
 
12
12
  context 'with element_id parameter' do
@@ -2,9 +2,9 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Admin::DashboardController do
5
- let(:user) { admin_user }
5
+ let(:user) { build(:alchemy_dummy_user, :as_admin) }
6
6
 
7
- before { sign_in(user) }
7
+ before { authorize_user(user) }
8
8
 
9
9
  describe '#index' do
10
10
  before do
@@ -7,7 +7,7 @@ module Alchemy
7
7
  let(:element_in_clipboard) { create(:element, :page_id => alchemy_page.id) }
8
8
  let(:clipboard) { session[:alchemy_clipboard] = {} }
9
9
 
10
- before { sign_in(author_user) }
10
+ before { authorize_user(:as_author) }
11
11
 
12
12
  describe '#index' do
13
13
  let(:alchemy_page) { build_stubbed(:page) }
@@ -3,7 +3,7 @@ require "spec_helper"
3
3
  module Alchemy
4
4
  describe Admin::EssenceFilesController do
5
5
  before do
6
- sign_in(admin_user)
6
+ authorize_user(:as_admin)
7
7
  end
8
8
 
9
9
  let(:essence_file) { mock_model('EssenceFile', :attachment= => nil, content: content) }
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  module Alchemy
4
4
  describe Admin::EssencePicturesController do
5
- before { sign_in(admin_user) }
5
+ before { authorize_user(:as_admin) }
6
6
 
7
7
  let(:essence) { EssencePicture.new }
8
8
  let(:content) { Content.new }
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  describe Alchemy::Admin::LanguagesController do
4
4
 
5
5
  before do
6
- sign_in(admin_user)
6
+ authorize_user(:as_admin)
7
7
  end
8
8
 
9
9
  describe "#new" do
@@ -4,7 +4,7 @@ module Alchemy
4
4
  describe Admin::LayoutpagesController do
5
5
 
6
6
  before(:each) do
7
- sign_in(admin_user)
7
+ authorize_user(:as_admin)
8
8
  end
9
9
 
10
10
  describe "#index" do
@@ -12,7 +12,7 @@ module Alchemy
12
12
  end
13
13
 
14
14
  context 'a member' do
15
- before { sign_in(member_user) }
15
+ before { authorize_user(build(:alchemy_dummy_user)) }
16
16
 
17
17
  it 'can not access page tree' do
18
18
  alchemy_get :index
@@ -21,9 +21,9 @@ module Alchemy
21
21
  end
22
22
 
23
23
  context 'with logged in editor user' do
24
- let(:user) { editor_user }
24
+ let(:user) { build(:alchemy_dummy_user, :as_editor) }
25
25
 
26
- before { sign_in(user) }
26
+ before { authorize_user(user) }
27
27
 
28
28
  describe '#index' do
29
29
  let(:language) { build_stubbed(:language) }
@@ -367,7 +367,7 @@ module Alchemy
367
367
 
368
368
  describe '#edit' do
369
369
  let!(:page) { create(:page) }
370
- let!(:other_user) { create(:author_user) }
370
+ let!(:other_user) { create(:alchemy_dummy_user, :as_author) }
371
371
 
372
372
  context 'if page is locked by another user' do
373
373
  before { page.lock_to!(other_user) }
@@ -4,7 +4,7 @@ module Alchemy
4
4
  describe Admin::PicturesController do
5
5
 
6
6
  before do
7
- sign_in(admin_user)
7
+ authorize_user(:as_admin)
8
8
  end
9
9
 
10
10
  describe "#index" do
@@ -14,7 +14,7 @@ describe Admin::EventsController do
14
14
  let(:lustig) { Event.create(name: 'Lustig') }
15
15
 
16
16
  before do
17
- sign_in(admin_user)
17
+ authorize_user(:as_admin)
18
18
  peter; lustig
19
19
  end
20
20
 
@@ -9,7 +9,7 @@ module Alchemy
9
9
  let(:element) { FactoryGirl.create(:element, :public => false, :page => alchemy_page) }
10
10
 
11
11
  before {
12
- sign_in(admin_user)
12
+ authorize_user(:as_admin)
13
13
  element.trash!
14
14
  }
15
15
 
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  module Alchemy
4
4
  module Admin
5
5
  describe TagsController do
6
- before { sign_in(admin_user) }
6
+ before { authorize_user(:as_admin) }
7
7
 
8
8
  describe '#create' do
9
9
  context 'without required params' do
@@ -47,7 +47,7 @@ module Alchemy
47
47
  end
48
48
 
49
49
  context "as member user" do
50
- before { sign_in(member_user) }
50
+ before { authorize_user(build(:alchemy_dummy_user)) }
51
51
 
52
52
  it "should be possible to download attachments from restricted pages" do
53
53
  alchemy_get :download, :id => attachment.id
@@ -25,5 +25,27 @@ module Alchemy
25
25
  end
26
26
  end
27
27
 
28
+ describe "#configuration" do
29
+ it "returns certain configuration options" do
30
+ allow(Config).to receive(:show).and_return({"some_option" => true})
31
+ expect(controller.configuration(:some_option)).to eq(true)
32
+ end
33
+ end
34
+
35
+ describe "#multi_language?" do
36
+ context "if more than one published language exists" do
37
+ it "returns true" do
38
+ allow(Alchemy::Language).to receive(:published).and_return double(count: 2)
39
+ expect(controller.multi_language?).to eq(true)
40
+ end
41
+ end
42
+
43
+ context "if less than two published languages exists" do
44
+ it "returns false" do
45
+ allow(Alchemy::Language).to receive(:published).and_return double(count: 1)
46
+ expect(controller.multi_language?).to eq(false)
47
+ end
48
+ end
49
+ end
28
50
  end
29
51
  end
@@ -36,7 +36,7 @@ module Alchemy
36
36
  end
37
37
 
38
38
  context "for member user" do
39
- before { sign_in(member_user) }
39
+ before { authorize_user(build(:alchemy_dummy_user)) }
40
40
 
41
41
  it "should render elements of restricted pages" do
42
42
  alchemy_get :show, id: restricted_element.id
@@ -12,11 +12,12 @@ module Alchemy
12
12
  context 'an author' do
13
13
  let(:unpublic) { create(:page, parent: default_language_root) }
14
14
 
15
- before { allow(controller).to receive(:current_alchemy_user).and_return(author_user) }
15
+ before { authorize_user(:as_author) }
16
16
 
17
17
  it "should not be able to visit a unpublic page" do
18
- alchemy_get :show, urlname: unpublic.urlname
19
- expect(response.status).to eq(404)
18
+ expect {
19
+ alchemy_get :show, urlname: unpublic.urlname
20
+ }.to raise_error(ActionController::RoutingError)
20
21
  end
21
22
  end
22
23
 
@@ -75,18 +76,18 @@ module Alchemy
75
76
 
76
77
  context "with incorrect levelnames in params" do
77
78
  it "should render a 404 page" do
78
- alchemy_get :show, {urlname: 'catalog/faqs/screwdriver'}
79
- expect(response.status).to eq(404)
80
- expect(response.body).to have_content('The page you were looking for doesn\'t exist')
79
+ expect {
80
+ alchemy_get :show, {urlname: 'catalog/faqs/screwdriver'}
81
+ }.to raise_error(ActionController::RoutingError)
81
82
  end
82
83
  end
83
84
  end
84
85
 
85
86
  context "when a non-existent page is requested" do
86
87
  it "should rescue a RoutingError with rendering a 404 page." do
87
- alchemy_get :show, {urlname: 'doesntexist'}
88
- expect(response.status).to eq(404)
89
- expect(response.body).to have_content('The page you were looking for doesn\'t exist')
88
+ expect {
89
+ alchemy_get :show, {urlname: 'doesntexist'}
90
+ }.to raise_error(ActionController::RoutingError)
90
91
  end
91
92
  end
92
93
 
@@ -139,14 +140,14 @@ module Alchemy
139
140
 
140
141
  it "should redirect permanently to page that belongs to legacy page url even if url has an unknown format & get parameters" do
141
142
  expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url4.urlname)
142
- alchemy_get :show, urlname: "index.php"
143
+ alchemy_get :show, urlname: legacy_url4.urlname
143
144
  expect(response.status).to eq(301)
144
145
  expect(response).to redirect_to("/#{second_page.urlname}")
145
146
  end
146
147
 
147
148
  it "should not pass query string for legacy routes" do
148
149
  expect(request).to receive(:fullpath).at_least(:once).and_return(legacy_url3.urlname)
149
- alchemy_get :show, urlname: "index.php"
150
+ alchemy_get :show, urlname: legacy_url4.urlname
150
151
  expect(URI.parse(response["Location"]).query).to be_nil
151
152
  end
152
153
 
@@ -184,12 +185,12 @@ module Alchemy
184
185
 
185
186
  context "with no lang parameter present" do
186
187
  it "should store defaults language id in the session." do
187
- alchemy_get :show, urlname: 'a-public-page'
188
+ alchemy_get :show, urlname: page.urlname
188
189
  expect(controller.session[:alchemy_language_id]).to eq(Language.default.id)
189
190
  end
190
191
 
191
192
  it "should store default language as class var." do
192
- alchemy_get :show, urlname: 'a-public-page'
193
+ alchemy_get :show, urlname: page.urlname
193
194
  expect(Language.current).to eq(Language.default)
194
195
  end
195
196
  end
@@ -209,10 +210,8 @@ module Alchemy
209
210
  end
210
211
 
211
212
  context 'with user logged in' do
212
- let(:author_user) { mock_model(Alchemy.user_class, cache_key: 'bbb') }
213
-
214
213
  before do
215
- sign_in(author_user)
214
+ authorize_user(mock_model(Alchemy.user_class, cache_key: 'bbb'))
216
215
  end
217
216
 
218
217
  it "returns another etag for response headers" do
@@ -19,12 +19,37 @@ module Alchemy
19
19
  create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/80x60.png', __FILE__), 'image/png'))
20
20
  end
21
21
 
22
- before { sign_in(editor_user) }
23
-
24
22
  it "renders the original image without any resizing" do
25
23
  alchemy_get :zoom, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
26
24
  expect(response.body[0x10..0x18].unpack('NN')).to eq([80, 60])
27
25
  end
26
+
27
+ context "Requesting a picture that is assigned with restricted pages only" do
28
+ before do
29
+ essence = restricted_element.contents.where(name: 'image').first.essence
30
+ essence.picture_id = picture.id
31
+ essence.save
32
+ end
33
+
34
+ context "as guest user" do
35
+ it "should not render the picture, but redirect to login path" do
36
+ alchemy_get :zoom, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
37
+ expect(response.status).to eq(302)
38
+ expect(response).to redirect_to(Alchemy.login_path)
39
+ end
40
+ end
41
+
42
+ context "as member user" do
43
+ before do
44
+ authorize_user(build(:alchemy_dummy_user))
45
+ end
46
+
47
+ it "should render the picture" do
48
+ alchemy_get :zoom, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
49
+ expect(response.status).to eq(200)
50
+ end
51
+ end
52
+ end
28
53
  end
29
54
 
30
55
  describe '#show' do
@@ -35,222 +60,247 @@ module Alchemy
35
60
  request.session_options.fetch(:skip) { false }
36
61
  }.to(true)
37
62
  end
38
- end
39
63
 
40
- context "Requesting a picture with tempared security token" do
41
- it "should render status 400" do
42
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: '14m4b4dh4ck3r'
43
- expect(response.status).to eq(400)
64
+ context "Requesting a picture with tempared security token" do
65
+ it "should render status 400" do
66
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: '14m4b4dh4ck3r'
67
+ expect(response.status).to eq(400)
68
+ end
44
69
  end
45
- end
46
70
 
47
- context "Requesting a picture with another format then the original image" do
48
- it "should convert the picture format" do
49
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :jpeg, sh: picture.security_token
50
- expect(response.content_type).to eq('image/jpeg')
71
+ context "Requesting a picture with another format then the original image" do
72
+ it "should convert the picture format" do
73
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :jpeg, sh: picture.security_token
74
+ expect(response.content_type).to eq('image/jpeg')
75
+ end
51
76
  end
52
- end
53
77
 
54
- context "Requesting a picture with not allowed format" do
55
- it "should raise error" do
56
- expect {
57
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :wim, sh: picture.security_token
58
- }.to raise_error(ActionController::UnknownFormat)
78
+ context "Requesting a picture with not allowed format" do
79
+ it "should raise error" do
80
+ expect {
81
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :wim, sh: picture.security_token
82
+ }.to raise_error(ActionController::UnknownFormat)
83
+ end
59
84
  end
60
- end
61
85
 
62
- describe '#thumbnail' do
63
- let(:picture) do
64
- create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
86
+ context "Requesting a picture that has no image file attached" do
87
+ before do
88
+ expect(picture).to receive(:image_file).and_return(nil)
89
+ expect(Picture).to receive(:find).and_return(picture)
90
+ end
91
+
92
+ it "raises missing file error" do
93
+ expect {
94
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
95
+ }.to raise_error(Alchemy::MissingImageFileError)
96
+ end
65
97
  end
66
98
 
67
- before { sign_in(author_user) }
99
+ context "Requesting a picture with crop_from and crop_size parameters" do
100
+ let(:picture) do
101
+ create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
102
+ end
68
103
 
69
- context 'with size param set to small' do
70
- it "resizes the image to 80x60 while maintaining aspect ratio" do
71
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'small', format: :png, sh: picture.security_token(size: 'small')
72
- expect(response.body[0x10..0x18].unpack('NN')).to eq([60, 60])
104
+ it "renders the cropped picture" do
105
+ alchemy_get :show, id: picture.id, name: picture.urlname, crop: 'crop', size: '123x44', crop_size: '123x44',
106
+ crop_from: '0x0', format: :png,
107
+ sh: picture.security_token(crop_size: '123x44', crop_from: '0x0', crop: true, size: '123x44')
108
+ expect(response.body[0x10..0x18].unpack('NN')).to eq([123, 44])
73
109
  end
74
110
  end
75
111
 
76
- context 'with size param set to medium' do
77
- it "resizes the image to 160x120 while maintaining aspect ratio" do
78
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'medium', format: :png, sh: picture.security_token(size: 'medium')
79
- expect(response.body[0x10..0x18].unpack('NN')).to eq([120, 120])
112
+ context "Requesting a picture with crop_from and crop_size parameters with different size param" do
113
+ let(:picture) do
114
+ create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
80
115
  end
81
- end
82
116
 
83
- context 'with size param set to large' do
84
- it "resizes the image to 240x180 while maintaining aspect ratio" do
85
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'large', format: :png, sh: picture.security_token(size: 'large')
86
- expect(response.body[0x10..0x18].unpack('NN')).to eq([180, 180])
117
+ it "renders the cropped picture" do
118
+ alchemy_get :show,
119
+ id: picture.id,
120
+ name: picture.urlname,
121
+ crop: 'crop',
122
+ size: '100x100',
123
+ crop_size: '200x200',
124
+ crop_from: '0x0',
125
+ format: :png,
126
+ sh: picture.security_token(
127
+ crop_size: '200x200',
128
+ crop_from: '0x0',
129
+ crop: true,
130
+ size: '100x100'
131
+ )
132
+ expect(response.body[0x10..0x18].unpack('NN')).to eq [100, 100]
87
133
  end
88
134
  end
89
135
 
90
- context 'with size param set to nil' do
91
- it "resizes the image to 111x93 while maintaining aspect ratio" do
92
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
93
- expect(response.body[0x10..0x18].unpack('NN')).to eq([93, 93])
136
+ context "Requesting a picture with crop_from and crop_size parameters with larger size param" do
137
+ let(:picture) do
138
+ create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
94
139
  end
95
- end
96
140
 
97
- context 'with size param set to another value' do
98
- it "resizes the image to the given size while maintaining aspect ratio" do
99
- alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: '33x33', format: :png, sh: picture.security_token(size: '33x33')
100
- expect(response.body[0x10..0x18].unpack('NN')).to eq([33, 33])
141
+ it "renders the cropped picture without upsampling" do
142
+ alchemy_get :show,
143
+ id: picture.id,
144
+ name: picture.urlname,
145
+ crop: 'crop',
146
+ size: '400x400',
147
+ crop_size: '200x200',
148
+ crop_from: '0x0',
149
+ format: :png,
150
+ sh: picture.security_token(
151
+ crop_size: '200x200',
152
+ crop_from: '0x0',
153
+ crop: true,
154
+ size: '400x400'
155
+ )
156
+ expect(response.body[0x10..0x18].unpack('NN')).to eq [200, 200]
101
157
  end
102
158
  end
103
- end
104
159
 
105
- context "Requesting a picture that has no image file attached" do
106
- before do
107
- expect(picture).to receive(:image_file).and_return(nil)
108
- expect(Picture).to receive(:find).and_return(picture)
160
+ context "Requesting a picture with crop_from and crop_size parameters with larger size param and upsample set" do
161
+ let(:picture) do
162
+ create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
163
+ end
164
+
165
+ it "renders the cropped picture with upsampling" do
166
+ alchemy_get :show,
167
+ id: picture.id,
168
+ name: picture.urlname,
169
+ crop: 'crop',
170
+ size: '400x400',
171
+ crop_size: '200x200',
172
+ crop_from: '0x0',
173
+ format: :png,
174
+ upsample: 'true',
175
+ sh: picture.security_token(
176
+ crop_size: '200x200',
177
+ crop_from: '0x0',
178
+ crop: true,
179
+ size: '400x400',
180
+ upsample: 'true'
181
+ )
182
+ expect(response.body[0x10..0x18].unpack('NN')).to eq [400, 400]
183
+ end
109
184
  end
110
185
 
111
- it "raises missing file error" do
112
- expect {
186
+ context "Requesting a picture that is not assigned with any page" do
187
+ it "should render the picture" do
113
188
  alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
114
- }.to raise_error(Alchemy::MissingImageFileError)
189
+ expect(response.status).to eq(200)
190
+ end
115
191
  end
116
- end
117
192
 
118
- context "Requesting a picture with crop_from and crop_size parameters" do
119
- let(:picture) do
120
- create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
121
- end
193
+ context "Requesting a picture that is assigned on restricted and non-restricted pages" do
194
+ before do
195
+ essence = element.contents.where(name: 'image').first.essence
196
+ essence.picture_id = picture.id
197
+ essence.save
122
198
 
123
- it "renders the cropped picture" do
124
- alchemy_get :show, id: picture.id, name: picture.urlname, crop: 'crop', size: '123x44', crop_size: '123x44',
125
- crop_from: '0x0', format: :png,
126
- sh: picture.security_token(crop_size: '123x44', crop_from: '0x0', crop: true, size: '123x44')
127
- expect(response.body[0x10..0x18].unpack('NN')).to eq([123, 44])
128
- end
129
- end
199
+ essence = restricted_element.contents.where(name: 'image').first.essence
200
+ essence.picture_id = picture.id
201
+ essence.save
202
+ end
130
203
 
131
- context "Requesting a picture with crop_from and crop_size parameters with different size param" do
132
- let(:picture) do
133
- create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
204
+ context "as guest user" do
205
+ it "should render the picture" do
206
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
207
+ expect(response.status).to eq(200)
208
+ end
209
+ end
134
210
  end
135
211
 
136
- it "renders the cropped picture" do
137
- alchemy_get :show,
138
- id: picture.id,
139
- name: picture.urlname,
140
- crop: 'crop',
141
- size: '100x100',
142
- crop_size: '200x200',
143
- crop_from: '0x0',
144
- format: :png,
145
- sh: picture.security_token(
146
- crop_size: '200x200',
147
- crop_from: '0x0',
148
- crop: true,
149
- size: '100x100'
150
- )
151
- expect(response.body[0x10..0x18].unpack('NN')).to eq [100, 100]
152
- end
153
- end
212
+ context "Requesting a picture that is assigned with restricted pages only" do
213
+ before do
214
+ essence = restricted_element.contents.where(name: 'image').first.essence
215
+ essence.picture_id = picture.id
216
+ essence.save
217
+ end
154
218
 
155
- context "Requesting a picture with crop_from and crop_size parameters with larger size param" do
156
- let(:picture) do
157
- create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
158
- end
219
+ context "as guest user" do
220
+ it "should not render the picture, but redirect to login path" do
221
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
222
+ expect(response.status).to eq(302)
223
+ expect(response).to redirect_to(Alchemy.login_path)
224
+ end
225
+ end
159
226
 
160
- it "renders the cropped picture without upsampling" do
161
- alchemy_get :show,
162
- id: picture.id,
163
- name: picture.urlname,
164
- crop: 'crop',
165
- size: '400x400',
166
- crop_size: '200x200',
167
- crop_from: '0x0',
168
- format: :png,
169
- sh: picture.security_token(
170
- crop_size: '200x200',
171
- crop_from: '0x0',
172
- crop: true,
173
- size: '400x400'
174
- )
175
- expect(response.body[0x10..0x18].unpack('NN')).to eq [200, 200]
227
+ context "as member user" do
228
+ before do
229
+ authorize_user(build(:alchemy_dummy_user))
230
+ end
231
+
232
+ it "should render the picture" do
233
+ alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
234
+ expect(response.status).to eq(200)
235
+ end
236
+ end
176
237
  end
177
238
  end
178
239
 
179
- context "Requesting a picture with crop_from and crop_size parameters with larger size param and upsample set" do
240
+ describe '#thumbnail' do
180
241
  let(:picture) do
181
242
  create(:picture, image_file: fixture_file_upload(File.expand_path('../../fixtures/500x500.png', __FILE__), 'image/png'))
182
243
  end
183
244
 
184
- it "renders the cropped picture with upsampling" do
185
- alchemy_get :show,
186
- id: picture.id,
187
- name: picture.urlname,
188
- crop: 'crop',
189
- size: '400x400',
190
- crop_size: '200x200',
191
- crop_from: '0x0',
192
- format: :png,
193
- upsample: 'true',
194
- sh: picture.security_token(
195
- crop_size: '200x200',
196
- crop_from: '0x0',
197
- crop: true,
198
- size: '400x400',
199
- upsample: 'true'
200
- )
201
- expect(response.body[0x10..0x18].unpack('NN')).to eq [400, 400]
202
- end
203
- end
204
-
205
- context "Requesting a picture that is not assigned with any page" do
206
- it "should render the picture" do
207
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
208
- expect(response.status).to eq(200)
245
+ context 'with size param set to small' do
246
+ it "resizes the image to 80x60 while maintaining aspect ratio" do
247
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'small', format: :png, sh: picture.security_token(size: 'small')
248
+ expect(response.body[0x10..0x18].unpack('NN')).to eq([60, 60])
249
+ end
209
250
  end
210
- end
211
251
 
212
- context "Requesting a picture that is assigned on restricted and non-restricted pages" do
213
- before do
214
- essence = element.contents.where(name: 'image').first.essence
215
- essence.picture_id = picture.id
216
- essence.save
217
-
218
- essence = restricted_element.contents.where(name: 'image').first.essence
219
- essence.picture_id = picture.id
220
- essence.save
252
+ context 'with size param set to medium' do
253
+ it "resizes the image to 160x120 while maintaining aspect ratio" do
254
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'medium', format: :png, sh: picture.security_token(size: 'medium')
255
+ expect(response.body[0x10..0x18].unpack('NN')).to eq([120, 120])
256
+ end
221
257
  end
222
258
 
223
- context "as guest user" do
224
- it "should render the picture" do
225
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
226
- expect(response.status).to eq(200)
259
+ context 'with size param set to large' do
260
+ it "resizes the image to 240x180 while maintaining aspect ratio" do
261
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: 'large', format: :png, sh: picture.security_token(size: 'large')
262
+ expect(response.body[0x10..0x18].unpack('NN')).to eq([180, 180])
227
263
  end
228
264
  end
229
- end
230
265
 
231
- context "Requesting a picture that is assigned with restricted pages only" do
232
- before do
233
- essence = restricted_element.contents.where(name: 'image').first.essence
234
- essence.picture_id = picture.id
235
- essence.save
266
+ context 'with size param set to nil' do
267
+ it "resizes the image to 111x93 while maintaining aspect ratio" do
268
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
269
+ expect(response.body[0x10..0x18].unpack('NN')).to eq([93, 93])
270
+ end
236
271
  end
237
272
 
238
- context "as guest user" do
239
- it "should not render the picture, but redirect to login path" do
240
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
241
- expect(response.status).to eq(302)
242
- expect(response).to redirect_to(Alchemy.login_path)
273
+ context 'with size param set to another value' do
274
+ it "resizes the image to the given size while maintaining aspect ratio" do
275
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, size: '33x33', format: :png, sh: picture.security_token(size: '33x33')
276
+ expect(response.body[0x10..0x18].unpack('NN')).to eq([33, 33])
243
277
  end
244
278
  end
245
279
 
246
- context "as member user" do
280
+ context "Requesting a picture that is assigned with restricted pages only" do
247
281
  before do
248
- sign_in(member_user)
282
+ essence = restricted_element.contents.where(name: 'image').first.essence
283
+ essence.picture_id = picture.id
284
+ essence.save
249
285
  end
250
286
 
251
- it "should render the picture" do
252
- alchemy_get :show, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
253
- expect(response.status).to eq(200)
287
+ context "as guest user" do
288
+ it "should not render the picture, but redirect to login path" do
289
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
290
+ expect(response.status).to eq(302)
291
+ expect(response).to redirect_to(Alchemy.login_path)
292
+ end
293
+ end
294
+
295
+ context "as member user" do
296
+ before do
297
+ authorize_user(build(:alchemy_dummy_user))
298
+ end
299
+
300
+ it "should render the picture" do
301
+ alchemy_get :thumbnail, id: picture.id, name: picture.urlname, format: :png, sh: picture.security_token
302
+ expect(response.status).to eq(200)
303
+ end
254
304
  end
255
305
  end
256
306
  end