alchemy_cms 3.2.0.beta → 3.2.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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