alchemy_cms 2.7.5 → 2.8.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 491ad71e83bcd6aaaeb4f79f9c696982ea8c8112
4
- data.tar.gz: 64c210c6d964efa046475945ede684ecf3e626ed
3
+ metadata.gz: edf3ac4fd7a2b98807ac909f6f091cdafb11f9c6
4
+ data.tar.gz: 4515777e5e93ef98b427f57dd9fd5a9f4b59333f
5
5
  SHA512:
6
- metadata.gz: be1fe2cef675009c89d8f1a70f6b8b90ded20c81e91e74c0619347e9d7047d73da29683391d8512281147a7a71d0a88b3dbd840b94c5a0427814ada8eb9fb1a0
7
- data.tar.gz: 91beddf874b48a4f4b761a5952c73a18059e5b355d0e28b417d8a34c1a4c61fda2f20e18369ee13488c2521555b3ddd8f9fb1c139b09f14d750d6402e6aba36c
6
+ metadata.gz: a32052e6ccd970e0ba9f51e978d57897b67ffd0980425c283ddb1c01d27e5a8f71006d553867c6833420c33fc95802917987de9a599322fd1f44908e0e4d9455
7
+ data.tar.gz: d8199c8dce2e4d9f52aa0d6da2eca587050a574ef6d67855fe28c484718a8cb4d19a5fba1848e39ff1163512a148fabf014bc5d5ebd1c0002e55f304459be1eb
data/.travis.yml CHANGED
@@ -4,7 +4,7 @@ rvm:
4
4
  - 2.0.0
5
5
  branches:
6
6
  only:
7
- - 2.7-stable
7
+ - 2.8-stable
8
8
  script: rake
9
9
  env:
10
10
  - DB=mysql
data/Gemfile CHANGED
@@ -14,8 +14,6 @@ gem 'sqlite3' if ENV['DB'].nil? || ENV['DB'] == 'sqlite'
14
14
  gem 'mysql2' if ENV['DB'] == 'mysql'
15
15
  gem 'pg' if ENV['DB'] == 'postgresql'
16
16
 
17
- gem 'database_cleaner'
18
-
19
17
  unless ENV['CI']
20
18
  gem 'pry'
21
19
  gem 'quiet_assets' # Mute assets loggin
@@ -25,6 +23,7 @@ end
25
23
  group :test do
26
24
  unless ENV['FAST_SPECS']
27
25
  gem 'poltergeist'
26
+ gem 'connection_pool' # https://gist.github.com/mperham/3049152
28
27
  unless ENV['CI']
29
28
  gem 'launchy'
30
29
  end
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  ![Alchemy CMS](http://alchemy-cms.com/assets/alchemy_logo.png)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/alchemy_cms.png)](http://badge.fury.io/rb/alchemy_cms)
4
- [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_cms.png?branch=2.7-stable)](http://travis-ci.org/magiclabs/alchemy_cms) [![Code Climate](https://codeclimate.com/github/magiclabs/alchemy_cms.png)](https://codeclimate.com/github/magiclabs/alchemy_cms) [![Coverage Status](https://coveralls.io/repos/magiclabs/alchemy_cms/badge.png?branch=2.7-stable)](https://coveralls.io/r/magiclabs/alchemy_cms)
4
+ [![Build Status](https://secure.travis-ci.org/magiclabs/alchemy_cms.png?branch=2.8-stable)](http://travis-ci.org/magiclabs/alchemy_cms) [![Code Climate](https://codeclimate.com/github/magiclabs/alchemy_cms.png)](https://codeclimate.com/github/magiclabs/alchemy_cms) [![Coverage Status](https://coveralls.io/repos/magiclabs/alchemy_cms/badge.png?branch=2.8-stable)](https://coveralls.io/r/magiclabs/alchemy_cms)
5
5
 
6
6
  About
7
7
  -----
@@ -67,7 +67,7 @@ Add to existing Rails project
67
67
 
68
68
  In your Gemfile:
69
69
 
70
- gem 'alchemy_cms', github: 'magiclabs/alchemy_cms', branch: '2.7-stable'
70
+ gem 'alchemy_cms', github: 'magiclabs/alchemy_cms', branch: '2.8-stable'
71
71
 
72
72
  Run in terminal:
73
73
 
@@ -133,4 +133,4 @@ Authors
133
133
  License
134
134
  -------
135
135
 
136
- * BSD: <https://raw.github.com/magiclabs/alchemy_cms/2.7-stable/LICENSE>
136
+ * BSD: <https://raw.github.com/magiclabs/alchemy_cms/2.8-stable/LICENSE>
@@ -200,19 +200,17 @@ module Alchemy
200
200
  @sorting = true
201
201
  end
202
202
 
203
- # Receives a JSON object representing a language tree to be ordered
204
- # and updates all pages in that language structure to their correct indexes
205
203
  def order
206
- neworder = JSON.parse(params[:set])
207
- rootpage = Page.language_root_for(session[:language_id])
208
-
209
- tree = create_tree(neworder, rootpage)
204
+ @page_root = Page.language_root_for(session[:language_id])
210
205
 
211
- Alchemy::Page.transaction do
212
- tree.each do |key, node|
213
- dbitem = Page.find(key)
214
- dbitem.update_node!(node)
215
- end
206
+ # Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
207
+ neworder = JSON.parse(params[:set])
208
+ prev_item = nil
209
+ neworder.each do |item|
210
+ dbitem = Page.find(item['id'])
211
+ prev_item.nil? ? dbitem.move_to_child_of(@page_root) : dbitem.move_to_right_of(prev_item)
212
+ sort_children(item, dbitem) unless item['children'].nil?
213
+ prev_item = dbitem.reload
216
214
  end
217
215
 
218
216
  flash[:notice] = _t("Pages order saved")
@@ -242,85 +240,6 @@ module Alchemy
242
240
 
243
241
  private
244
242
 
245
- # Returns the current left index and the aggregated hash of tree nodes indexed by page id visited so far
246
- #
247
- # Visits a batch of children nodes, assigns them the correct ordering indexes and spuns recursively the same
248
- # procedure on their children, if any
249
- #
250
- # @param [Array]
251
- # An array of children nodes to be visited
252
- # @param [Integer]
253
- # The lft attribute that should be given to the first node in the array
254
- # @param [Integer]
255
- # The page id of the parent of this batch of children nodes
256
- # @param [Integer]
257
- # The depth at which these children reside
258
- # @param [Hash]
259
- # A Hash of TreeNode's indexed by their page ids
260
- # @param [String]
261
- # The url for the parent node of these children
262
- # @param [Boolean]
263
- # Whether these children reside in a restricted branch according to their ancestors
264
- #
265
- def visit_nodes(nodes, my_left, parent, depth, tree, url, restricted)
266
- nodes.each do |item|
267
- my_right = my_left + 1
268
- my_restricted = item['restricted'] || restricted
269
- urls = process_url(url, item)
270
-
271
- if item['children']
272
- my_right, tree = visit_nodes(item['children'], my_left + 1, item['id'], depth + 1, tree, urls[:children_path], my_restricted)
273
- end
274
-
275
- tree[item['id']] = TreeNode.new(my_left, my_right, parent, depth, urls[:my_urlname], my_restricted)
276
- my_left = my_right + 1
277
- end
278
-
279
- [my_left, tree]
280
- end
281
-
282
- # Returns a Hash of TreeNode's indexed by their page ids
283
- #
284
- # Grabs the array representing a tree structure of pages passed as a parameter,
285
- # visits it and creates a map of TreeNodes indexed by page id featuring Nested Set
286
- # ordering information consisting of the left, right, depth and parent_id indexes as
287
- # well as a node's url and restricted status
288
- #
289
- # @param [Array]
290
- # An Array representing a tree of Alchemy::Page's
291
- # @param [Alchemy::Page]
292
- # The root page for the language being ordered
293
- #
294
- def create_tree(items, rootpage)
295
- _, tree = visit_nodes(items, rootpage.lft + 1, rootpage.id, rootpage.depth + 1, {}, "", rootpage.restricted)
296
- tree
297
- end
298
-
299
- # Returns a pair, the path that a given tree node should take, and the path its children should take
300
- #
301
- # This function will add a node's own slug into their ancestor's path
302
- # in order to create the full URL of a node
303
- #
304
- # NOTE: external and invisible pages are not part of the full path of their children
305
- #
306
- # @param [String]
307
- # The node's ancestors path
308
- # @param [Hash]
309
- # A children node
310
- #
311
- def process_url(ancestors_path, item)
312
- default_urlname = (ancestors_path.blank? ? "" : "#{ancestors_path}/") + item['slug']
313
-
314
- pair = {my_urlname: default_urlname, children_path: default_urlname}
315
-
316
- if item['external'] == true || item['visible'] == false
317
- # children ignore an ancestor in their path if external or invisible
318
- pair[:children_path] = ancestors_path
319
- end
320
-
321
- pair
322
- end
323
-
324
243
  def load_page
325
244
  @page = Page.find(params[:id])
326
245
  end
@@ -329,6 +248,17 @@ module Alchemy
329
248
  request.raw_post.split('&').map { |i| i = {i.split('=')[0].gsub(/[^0-9]/, '') => i.split('=')[1]} }
330
249
  end
331
250
 
251
+ # Taken from https://github.com/matenia/jQuery-Awesome-Nested-Set-Drag-and-Drop
252
+ def sort_children(element, dbitem)
253
+ prevchild = nil
254
+ element['children'].each do |child|
255
+ childitem = Page.find(child['id'])
256
+ prevchild.nil? ? childitem.move_to_child_of(dbitem) : childitem.move_to_right_of(prevchild)
257
+ sort_children(child, childitem) unless child['children'].nil?
258
+ prevchild = childitem
259
+ end
260
+ end
261
+
332
262
  def redirect_path_after_page_create
333
263
  if @page.redirects_to_external?
334
264
  admin_pages_path
@@ -84,52 +84,6 @@ module Alchemy
84
84
  end
85
85
  end
86
86
 
87
- # Sets the language for rendering pages in pages controller.
88
- #
89
- def set_language(lang = nil)
90
- if lang
91
- @language = lang.is_a?(Language) ? lang : load_language_from(lang)
92
- else
93
- # find the best language and remember it for later
94
- @language = load_language_from_params ||
95
- load_language_from_session ||
96
- load_language_default
97
- end
98
-
99
- # store language in session
100
- store_language_in_session(@language)
101
-
102
- # switch locale to selected language
103
- ::I18n.locale = @language.code
104
- end
105
-
106
- def load_language_from_params
107
- if params[:lang].present?
108
- Language.find_by_code(params[:lang])
109
- end
110
- end
111
-
112
- def load_language_from_session
113
- if session[:language_id].present?
114
- Language.find_by_id(session[:language_id])
115
- end
116
- end
117
-
118
- def load_language_from(language_code_or_id)
119
- Language.find_by_id(language_code_or_id) || Language.find_by_code(language_code_or_id)
120
- end
121
-
122
- def load_language_default
123
- Language.get_default || raise(DefaultLanguageNotFoundError)
124
- end
125
-
126
- def store_language_in_session(language)
127
- if language && language.id
128
- session[:language_id] = language.id
129
- session[:language_code] = language.code
130
- end
131
- end
132
-
133
87
  def store_location
134
88
  session[:redirect_path] = request.path
135
89
  end
@@ -45,6 +45,7 @@ module Alchemy
45
45
  # Should the window show overflowing content?
46
46
  #
47
47
  def link_to_overlay_window(content, url, options={}, html_options={})
48
+ ActiveSupport::Deprecation.warn("Used deprecated link_to_overlay_window helper. It will be removed in Alchemy v3.0. Please use link_to_dialog instead.")
48
49
  default_options = {
49
50
  :modal => true,
50
51
  :overflow => true,
@@ -139,6 +140,7 @@ module Alchemy
139
140
  # The label for the cancel button
140
141
  #
141
142
  def link_to_confirmation_window(link_string = "", message = "", url = "", html_options = {})
143
+ ActiveSupport::Deprecation.warn("Used deprecated link_to_confirmation_window helper. It will be removed in Alchemy v3.0. Please use link_to_confirm_dialog instead.")
142
144
  link_to(link_string, url,
143
145
  html_options.merge(
144
146
  'data-alchemy-confirm-delete' => {
@@ -22,6 +22,7 @@ module Alchemy
22
22
  # * editor_options (Hash) - Will be passed to the render_essence_editor partial renderer
23
23
  #
24
24
  def render_essence_editor_by_type(element, essence_type, options = {}, editor_options = {})
25
+ ActiveSupport::Deprecation.warn("Used deprecated render_essence_editor_by_type helper. It will be removed in Alchemy v3.0. You can use render_essence_editor_by_name instead.")
25
26
  return warning('Element is nil', _t(:no_element_given)) if element.blank?
26
27
  return warning('EssenceType is blank', _t("No EssenceType given")) if essence_type.blank?
27
28
  defaults = {
@@ -76,6 +77,7 @@ module Alchemy
76
77
  # Otherwise the pages are ordered by their position in the nested set.
77
78
  #
78
79
  def page_selector(element, content_name, options = {}, select_options = {})
80
+ ActiveSupport::Deprecation.warn("Used deprecated page_selector helper. It will be removed in Alchemy v3.0. Please use a select_tag with pages_for_select instead.")
79
81
  default_options = {
80
82
  :page_attribute => :id,
81
83
  :global => false,
@@ -213,6 +213,7 @@ module Alchemy
213
213
  # @note When passing a String for options :from_page, it must be a page_layout name.
214
214
  #
215
215
  def all_elements_by_name(name, options = {})
216
+ ActiveSupport::Deprecation.warn("Used deprecated all_elements_by_name helper. It will be removed in Alchemy v3.0. Please build the relevant behavior on your own.")
216
217
  warning('options[:language] option not allowed any more in all_elements_by_name helper') unless options[:language].blank?
217
218
  options = {
218
219
  count: :all,
@@ -244,6 +245,7 @@ module Alchemy
244
245
  # The id of the Page the element is associated with
245
246
  #
246
247
  def element_from_page(options = {})
248
+ ActiveSupport::Deprecation.warn("Used deprecated element_from_page helper. It will be removed in Alchemy v3.0. Please build the relevant behavior on your own.")
247
249
  default_options = {
248
250
  page_urlname: "",
249
251
  page_id: nil,
@@ -263,6 +265,7 @@ module Alchemy
263
265
 
264
266
  # Renders all element partials from given cell.
265
267
  def render_cell_elements(cell)
268
+ ActiveSupport::Deprecation.warn("Used deprecated render_cell_elements helper. It will be removed in Alchemy v3.0. You can use render_elements(from_cell: cell) instead.")
266
269
  return warning("No cell given.") if cell.blank?
267
270
  render_elements({:from_cell => cell})
268
271
  end
@@ -60,6 +60,7 @@ module Alchemy
60
60
  # <%= render_essence_view_by_type(element, "EssencePicture", 1, {:image_size => "120x80", :crop => true}) %>
61
61
  #
62
62
  def render_essence_view_by_type(element, type, position = 1, options = {}, html_options = {})
63
+ ActiveSupport::Deprecation.warn("Used deprecated render_essence_view_by_type helper. It will be removed in Alchemy v3.0. You can use render_essence_view_by_name instead.")
63
64
  if element.blank?
64
65
  warning('Element is nil')
65
66
  return ""
@@ -33,12 +33,12 @@ module Alchemy
33
33
  end
34
34
 
35
35
  def language_switches(options={})
36
- ActiveSupport::Deprecation.warn("Used deprecated language_switches helper. Please use language_links instead.")
36
+ ActiveSupport::Deprecation.warn("Used deprecated language_switches helper. It will be removed in Alchemy v3.0. You can use language_links instead.")
37
37
  language_links(options)
38
38
  end
39
39
 
40
40
  def language_switcher(options={})
41
- ActiveSupport::Deprecation.warn("Used deprecated language_switcher helper. Please use language_links instead.")
41
+ ActiveSupport::Deprecation.warn("Used deprecated language_switcher helper. It will be removed in Alchemy v3.0. You can use language_links instead.")
42
42
  language_links(options)
43
43
  end
44
44
 
@@ -411,6 +411,7 @@ module Alchemy
411
411
 
412
412
  # Renders a menubar for logged in users that are visiting a page.
413
413
  def alchemy_menu_bar
414
+ ActiveSupport::Deprecation.warn('Used deprecated alchemy_menu_bar helper. It will be removed in Alchemy v3.0. You can use `render "/alchemy/menubar"` instead.')
414
415
  return if @preview_mode
415
416
  if permitted_to?(:edit, :alchemy_admin_pages)
416
417
  menu_bar_string = ""
@@ -25,7 +25,7 @@ module Alchemy
25
25
  # <%= link_to '&raquo order now', page_path_for(:page_layout => 'orderform', :product_id => element.id) %>
26
26
  #
27
27
  def page_path_for(options={})
28
- ActiveSupport::Deprecation.warn("Used deprecated page_path_for helper. Please use show_alchemy_page_path instead.")
28
+ ActiveSupport::Deprecation.warn("Used deprecated page_path_for helper. It will be removed in Alchemy v3.0. You can use show_alchemy_page_path instead.")
29
29
  return warning("No page_layout, or urlname given. I got #{options.inspect} ") if options[:page_layout].blank? && options[:urlname].blank?
30
30
  if options[:urlname].blank?
31
31
  page = Page.find_by_page_layout(options[:page_layout])
@@ -298,25 +298,6 @@ module Alchemy
298
298
  set_language_code
299
299
  end
300
300
 
301
- # Updates an Alchemy::Page based on a new ordering to be applied to it
302
- #
303
- # Note: Page's urls should not be updated (and a legacy URL created) if nesting is OFF
304
- # or if a page is external or if the URL is the same
305
- #
306
- # @param [TreeNode]
307
- # A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
308
- #
309
- def update_node!(node)
310
- hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
311
-
312
- if Config.get(:url_nesting) && !self.redirects_to_external? && self.urlname != node.url
313
- LegacyPageUrl.create(page_id: self.id, urlname: self.urlname)
314
- hash.merge!(urlname: node.url)
315
- end
316
-
317
- self.class.update_all(hash, {id: self.id})
318
- end
319
-
320
301
  private
321
302
 
322
303
  # Returns the next or previous page on the same level or nil.
@@ -27,7 +27,7 @@ module Alchemy
27
27
 
28
28
  # Returns true or false if the pages layout_description for config/alchemy/page_layouts.yml contains redirects_to_external: true
29
29
  def redirects_to_external?
30
- !!definition["redirects_to_external"]
30
+ definition["redirects_to_external"]
31
31
  end
32
32
 
33
33
  def has_controller?
@@ -6,7 +6,7 @@ $('#element_<%= @element.id %>').hide(200, function() {
6
6
  $('#element_trash_button .icon').addClass('full');
7
7
  Alchemy.PreviewWindow.refresh();
8
8
  <% @element.contents.essence_richtexts.each do |content| %>
9
- tinymce.get('tinymce_<%= content.id %>').remove();
9
+ tinymce.get('contents_content_<%= content.id %>_body').remove();
10
10
  <% end %>
11
11
  <%= update_essence_select_elements(@page, @element) -%>
12
12
  });
@@ -1,4 +1,4 @@
1
- <li id="page_<%= page.id %>" class="page_level_<%= "#{page.level} #{page.page_layout}" %>" data-slug="<%= page.slug %>" data-restricted="<%= page.restricted? %>" data-visible="<%= page.visible? %>" data-external="<%= page.redirects_to_external? %>">
1
+ <li id="page_<%= page.id %>" class="page_level_<%= "#{page.level} #{page.page_layout}" %>">
2
2
  <div class="sitemap_page<%= page.locked ? ' locked' : '' %>" name="<%= page.name %>">
3
3
  <div class="sitemap_left_images">
4
4
  <%= sitemap_folder_link(page) unless page.level == 1 || page.children.blank? || @sorting %>
@@ -19,6 +19,7 @@ require 'alchemy/essence'
19
19
  require 'alchemy/ferret/search'
20
20
  require 'alchemy/filetypes'
21
21
  require 'alchemy/i18n'
22
+ require 'alchemy/language_helpers'
22
23
  require 'alchemy/logger'
23
24
  require 'alchemy/modules'
24
25
  require 'alchemy/mount_point'
@@ -73,5 +74,9 @@ module Alchemy
73
74
  Alchemy::Auth::Engine.get_instance.load(File.join(File.dirname(__FILE__), '../..', 'config/authorization_rules.rb'))
74
75
  end
75
76
 
77
+ config.to_prepare do
78
+ ApplicationController.send(:include, Alchemy::LanguageHelpers)
79
+ end
80
+
76
81
  end
77
82
  end
@@ -0,0 +1,55 @@
1
+ module Alchemy
2
+ module LanguageHelpers
3
+ def self.included(controller)
4
+ controller.send(:before_filter, :set_language)
5
+ end
6
+
7
+ private
8
+
9
+ # Sets the language for rendering pages in pages controller.
10
+ #
11
+ def set_language(lang = nil)
12
+ if lang
13
+ @language = lang.is_a?(Language) ? lang : load_language_from(lang)
14
+ else
15
+ # find the best language and remember it for later
16
+ @language = load_language_from_params ||
17
+ load_language_from_session ||
18
+ load_language_default
19
+ end
20
+
21
+ # store language in session
22
+ store_language_in_session(@language)
23
+
24
+ # switch locale to selected language
25
+ ::I18n.locale = @language.code
26
+ end
27
+
28
+ def load_language_from_params
29
+ if params[:lang].present?
30
+ Language.find_by_code(params[:lang])
31
+ end
32
+ end
33
+
34
+ def load_language_from_session
35
+ if session[:language_id].present?
36
+ Language.find_by_id(session[:language_id])
37
+ end
38
+ end
39
+
40
+ def load_language_from(language_code_or_id)
41
+ Language.find_by_id(language_code_or_id) || Language.find_by_code(language_code_or_id)
42
+ end
43
+
44
+ def load_language_default
45
+ Language.get_default || raise(DefaultLanguageNotFoundError)
46
+ end
47
+
48
+ def store_language_in_session(language)
49
+ if language && language.id
50
+ session[:language_id] = language.id
51
+ session[:language_code] = language.code
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,7 +1,9 @@
1
1
  module Alchemy
2
- VERSION = "2.7.5"
2
+
3
+ VERSION = "2.8.1"
3
4
 
4
5
  def self.version
5
6
  VERSION
6
7
  end
8
+
7
9
  end
@@ -55,95 +55,6 @@ module Alchemy
55
55
  end
56
56
  end
57
57
 
58
- describe '#order' do
59
- let(:page_1) { FactoryGirl.create(:page, visible: true) }
60
- let(:page_2) { FactoryGirl.create(:page, visible: true) }
61
- let(:page_3) { FactoryGirl.create(:page, visible: true) }
62
- let(:page_item_1) { {id: page_1.id, slug: page_1.slug, restricted: false, external: page_1.redirects_to_external?, visible: page_1.visible?, children: [page_item_2]} }
63
- let(:page_item_2) { {id: page_2.id, slug: page_2.slug, restricted: false, external: page_2.redirects_to_external?, visible: page_2.visible?, children: [page_item_3]} }
64
- let(:page_item_3) { {id: page_3.id, slug: page_3.slug, restricted: false, external: page_3.redirects_to_external?, visible: page_3.visible? } }
65
- let(:set_of_pages) { [page_item_1] }
66
-
67
- it "stores the new order" do
68
- xhr :post, :order, set: set_of_pages.to_json
69
- page_1.reload
70
- expect(page_1.descendants).to eq([page_2, page_3])
71
- end
72
-
73
- context 'with url nesting enabled' do
74
- before { Alchemy::Config.stub(get: true) }
75
-
76
- it "updates the pages urlnames" do
77
- xhr :post, :order, set: set_of_pages.to_json
78
- [page_1, page_2, page_3].map(&:reload)
79
- expect(page_1.urlname).to eq("#{page_1.slug}")
80
- expect(page_2.urlname).to eq("#{page_1.slug}/#{page_2.slug}")
81
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_2.slug}/#{page_3.slug}")
82
- end
83
-
84
- context 'with invisible page in tree' do
85
- let(:page_item_2) do
86
- {
87
- id: page_2.id,
88
- slug: page_2.slug,
89
- children: [page_item_3],
90
- visible: false
91
- }
92
- end
93
-
94
- it "does not use this pages slug in urlnames of descendants" do
95
- xhr :post, :order, set: set_of_pages.to_json
96
- [page_1, page_2, page_3].map(&:reload)
97
- expect(page_1.urlname).to eq("#{page_1.slug}")
98
- expect(page_2.urlname).to eq("#{page_1.slug}/#{page_2.slug}")
99
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_3.slug}")
100
- end
101
- end
102
-
103
- context 'with external page in tree' do
104
- let(:page_item_2) do
105
- {
106
- id: page_2.id,
107
- slug: page_2.slug,
108
- children: [page_item_3],
109
- external: true
110
- }
111
- end
112
-
113
- it "does not use this pages slug in urlnames of descendants" do
114
- xhr :post, :order, set: set_of_pages.to_json
115
- [page_1, page_2, page_3].map(&:reload)
116
- expect(page_3.urlname).to eq("#{page_1.slug}/#{page_3.slug}")
117
- end
118
- end
119
-
120
- context 'with restricted page in tree' do
121
- let(:page_2) { FactoryGirl.create(:page, restricted: true) }
122
- let(:page_item_2) do
123
- {
124
- id: page_2.id,
125
- slug: page_2.slug,
126
- children: [page_item_3],
127
- restricted: true
128
- }
129
- end
130
-
131
- it "updates restricted status of descendants" do
132
- xhr :post, :order, set: set_of_pages.to_json
133
- page_3.reload
134
- expect(page_3.restricted).to be_true
135
- end
136
- end
137
-
138
- it "creates legacy urls" do
139
- xhr :post, :order, set: set_of_pages.to_json
140
- [page_2, page_3].map(&:reload)
141
- expect(page_2.legacy_urls.size).to eq(1)
142
- expect(page_3.legacy_urls.size).to eq(1)
143
- end
144
- end
145
- end
146
-
147
58
  describe "#configure" do
148
59
  render_views
149
60
 
@@ -1117,124 +1117,6 @@ module Alchemy
1117
1117
  end
1118
1118
  end
1119
1119
 
1120
- describe "#update_node!" do
1121
-
1122
- let(:original_url) { "sample-url" }
1123
- let(:page) { FactoryGirl.create(:page, :language => language, :parent_id => language_root.id, :urlname => original_url, restricted: false) }
1124
- let(:node) { TreeNode.new(10, 11, 12, 13, "another-url", true) }
1125
-
1126
- context "when nesting is enabled" do
1127
- before { Alchemy::Config.stub(:get).with(:url_nesting) { true } }
1128
-
1129
- context "when page is not external" do
1130
-
1131
- before { page.stub(redirects_to_external?: false)}
1132
-
1133
- it "should update all attributes" do
1134
- page.update_node!(node)
1135
- page.reload
1136
- expect(page.lft).to eq(node.left)
1137
- expect(page.rgt).to eq(node.right)
1138
- expect(page.parent_id).to eq(node.parent)
1139
- expect(page.depth).to eq(node.depth)
1140
- expect(page.urlname).to eq(node.url)
1141
- expect(page.restricted).to eq(node.restricted)
1142
- end
1143
-
1144
- context "when url is the same" do
1145
- let(:node) { TreeNode.new(10, 11, 12, 13, original_url, true) }
1146
-
1147
- it "should not create a legacy url" do
1148
- page.update_node!(node)
1149
- page.reload
1150
- expect(page.legacy_urls.size).to eq(0)
1151
- end
1152
- end
1153
-
1154
- context "when url is not the same" do
1155
- it "should create a legacy url" do
1156
- page.update_node!(node)
1157
- page.reload
1158
- expect(page.legacy_urls.size).to eq(1)
1159
- end
1160
- end
1161
- end
1162
-
1163
- context "when page is external" do
1164
-
1165
- before { page.stub(redirects_to_external?: true) }
1166
-
1167
- it "should update all attributes except url" do
1168
- page.update_node!(node)
1169
- page.reload
1170
- expect(page.lft).to eq(node.left)
1171
- expect(page.rgt).to eq(node.right)
1172
- expect(page.parent_id).to eq(node.parent)
1173
- expect(page.depth).to eq(node.depth)
1174
- expect(page.urlname).to eq(original_url)
1175
- expect(page.restricted).to eq(node.restricted)
1176
- end
1177
-
1178
- it "should not create a legacy url" do
1179
- page.update_node!(node)
1180
- page.reload
1181
- expect(page.legacy_urls.size).to eq(0)
1182
- end
1183
- end
1184
- end
1185
-
1186
- context "when nesting is disabled" do
1187
- before { Alchemy::Config.stub(:get).with(:url_nesting) { false } }
1188
-
1189
- context "when page is not external" do
1190
-
1191
- before { page.stub(redirects_to_external?: false)}
1192
-
1193
- it "should update all attributes except url" do
1194
- page.update_node!(node)
1195
- page.reload
1196
- expect(page.lft).to eq(node.left)
1197
- expect(page.rgt).to eq(node.right)
1198
- expect(page.parent_id).to eq(node.parent)
1199
- expect(page.depth).to eq(node.depth)
1200
- expect(page.urlname).to eq(original_url)
1201
- expect(page.restricted).to eq(node.restricted)
1202
- end
1203
-
1204
- it "should not create a legacy url" do
1205
- page.update_node!(node)
1206
- page.reload
1207
- expect(page.legacy_urls.size).to eq(0)
1208
- end
1209
-
1210
- end
1211
-
1212
- context "when page is external" do
1213
-
1214
- before { page.stub(redirects_to_external?: true) }
1215
-
1216
- before { Alchemy::Config.stub(get: true) }
1217
-
1218
- it "should update all attributes except url" do
1219
- page.update_node!(node)
1220
- page.reload
1221
- expect(page.lft).to eq(node.left)
1222
- expect(page.rgt).to eq(node.right)
1223
- expect(page.parent_id).to eq(node.parent)
1224
- expect(page.depth).to eq(node.depth)
1225
- expect(page.urlname).to eq(original_url)
1226
- expect(page.restricted).to eq(node.restricted)
1227
- end
1228
-
1229
- it "should not create a legacy url" do
1230
- page.update_node!(node)
1231
- page.reload
1232
- expect(page.legacy_urls.size).to eq(0)
1233
- end
1234
- end
1235
- end
1236
- end
1237
-
1238
1120
  describe '#slug' do
1239
1121
  context "with parents path saved in urlname" do
1240
1122
  let(:page) { FactoryGirl.build(:page, urlname: 'root/parent/my-name')}
data/spec/spec_helper.rb CHANGED
@@ -33,11 +33,6 @@ Capybara.default_selector = :css
33
33
  Capybara.register_driver(:rack_test_translated_header) do |app|
34
34
  Capybara::RackTest::Driver.new(app, :headers => { 'HTTP_ACCEPT_LANGUAGE' => 'de' })
35
35
  end
36
- if ENV['CI']
37
- Capybara.register_driver :poltergeist do |app|
38
- Capybara::Poltergeist::Driver.new(app, timeout: 60)
39
- end
40
- end
41
36
  Capybara.javascript_driver = :poltergeist
42
37
 
43
38
  # Load support files
@@ -53,32 +48,15 @@ RSpec.configure do |config|
53
48
  config.include Devise::TestHelpers, :type => :controller
54
49
  config.include Alchemy::Specs::ControllerHelpers, :type => :controller
55
50
  config.include Alchemy::Specs::IntegrationHelpers, :type => :feature
56
- config.use_transactional_fixtures = false
57
-
51
+ config.use_transactional_fixtures = true
52
+ # Make sure the database is clean and ready for test
58
53
  config.before(:suite) do
59
- DatabaseCleaner.clean_with(:truncation)
54
+ truncate_all_tables
60
55
  Alchemy::Seeder.seed!
61
56
  end
62
-
63
- # All specs are running in transactions, but feature specs not.
57
+ # Ensuring that the locale is always resetted to :en before running any tests
64
58
  config.before(:each) do
65
59
  Alchemy::Site.current = nil
66
60
  ::I18n.locale = :en
67
- if example.metadata[:type] == :feature
68
- DatabaseCleaner.strategy = :truncation
69
- else
70
- DatabaseCleaner.strategy = :transaction
71
- end
72
- DatabaseCleaner.start
73
- end
74
-
75
- # After each spec the database gets cleaned. (via rollback or truncate for feature specs)
76
- # After every feature spec the database gets seeded so the next spec can rely on that data.
77
- config.append_after(:each) do
78
- DatabaseCleaner.clean
79
- if example.metadata[:type] == :feature
80
- Alchemy::Seeder.stub(:puts)
81
- Alchemy::Seeder.seed!
82
- end
83
61
  end
84
62
  end
@@ -60,20 +60,6 @@ module Alchemy
60
60
  FactoryGirl.create(:admin_user)
61
61
  end
62
62
 
63
- # Capybara actions to create a new element.
64
- #
65
- # You can pass the name of the desired element, or just use the default "Article".
66
- #
67
- def create_element!(name = 'Article')
68
- within '.alchemy-elements-window' do
69
- click_link Alchemy::I18n.t('New Element')
70
- end
71
- within '.new_alchemy_element' do
72
- select(name, from: 'element[name]')
73
- click_button 'Add'
74
- end
75
- end
76
-
77
63
  end
78
64
 
79
65
  end
@@ -0,0 +1,31 @@
1
+ # https://gist.github.com/mperham/3049152
2
+ # Fixes Capybara database connection issues
3
+ class ActiveRecord::Base
4
+ mattr_accessor :shared_connection
5
+ @@shared_connection = nil
6
+
7
+ def self.connection
8
+ @@shared_connection || ConnectionPool::Wrapper.new(:size => 1) { retrieve_connection }
9
+ end
10
+ end
11
+ ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection
12
+
13
+ # fast truncation of all tables that need truncations (select is 10x faster then truncate)
14
+ # http://grosser.it/2012/07/03/rubyactiverecord-fastest-way-to-truncate-test-database/
15
+ def truncate_all_tables
16
+ config = ActiveRecord::Base.configurations[::Rails.env]
17
+ connection = ActiveRecord::Base.connection
18
+ connection.disable_referential_integrity do
19
+ connection.tables.each do |table_name|
20
+ next if connection.select_value("SELECT count(*) FROM #{table_name}") == 0
21
+ case config["adapter"]
22
+ when "mysql2", "postgresql"
23
+ connection.execute("TRUNCATE #{table_name}")
24
+ when "sqlite3"
25
+ connection.execute("DELETE FROM #{table_name}")
26
+ connection.execute("DELETE FROM sqlite_sequence where name='#{table_name}'")
27
+ end
28
+ end
29
+ connection.execute("VACUUM") if config["adapter"] == "sqlite3"
30
+ end
31
+ end
@@ -255,14 +255,8 @@
255
255
 
256
256
  function _recursiveItems(li) {
257
257
  var id = ($(li).attr(o.attribute || 'id') || '').match(o.expression || (/(.+)[-=_](.+)/));
258
-
259
- var restricted = $(li).data("restricted");
260
- var slug = $(li).data("slug");
261
- var external = $(li).data("external");
262
- var visible = $(li).data("visible");
263
-
264
258
  if (id) {
265
- var item = {"id": id[2], "slug": slug, "restricted": restricted, "external": external, "visible": visible};
259
+ var item = {"id":id[2]};
266
260
  if ($(li).children(o.listType).children('li').length > 0) {
267
261
  item.children = [];
268
262
  $(li).children(o.listType).children('li').each(function () {
@@ -397,4 +391,4 @@
397
391
  }));
398
392
 
399
393
  $.ui.nestedSortable.prototype.options = $.extend({}, $.ui.sortable.prototype.options, $.ui.nestedSortable.prototype.options);
400
- })(jQuery);
394
+ })(jQuery);
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.5
4
+ version: 2.8.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -12,7 +12,7 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2014-06-12 00:00:00.000000000 Z
15
+ date: 2014-04-23 00:00:00.000000000 Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rails
@@ -551,7 +551,6 @@ files:
551
551
  - app/models/alchemy/site.rb
552
552
  - app/models/alchemy/site/layout.rb
553
553
  - app/models/alchemy/tag.rb
554
- - app/models/alchemy/tree_node.rb
555
554
  - app/models/alchemy/user.rb
556
555
  - app/sweepers/alchemy/content_sweeper.rb
557
556
  - app/sweepers/alchemy/pages_sweeper.rb
@@ -787,6 +786,7 @@ files:
787
786
  - lib/alchemy/filetypes.rb
788
787
  - lib/alchemy/i18n.rb
789
788
  - lib/alchemy/kaminari/scoped_pagination_url_helper.rb
789
+ - lib/alchemy/language_helpers.rb
790
790
  - lib/alchemy/logger.rb
791
791
  - lib/alchemy/modules.rb
792
792
  - lib/alchemy/mount_point.rb
@@ -918,8 +918,6 @@ files:
918
918
  - spec/dummy/public/stylesheets/.gitkeep
919
919
  - spec/dummy/script/rails
920
920
  - spec/fast_specs.rb
921
- - spec/features/admin/element_create_feature_spec.rb
922
- - spec/features/admin/element_trash_feature_spec.rb
923
921
  - spec/features/admin/link_overlay_spec.rb
924
922
  - spec/features/admin/modules_integration_spec.rb
925
923
  - spec/features/admin/pages_controller_spec.rb
@@ -991,6 +989,7 @@ files:
991
989
  - spec/support/alchemy/controller_hacks.rb
992
990
  - spec/support/alchemy/controller_helpers.rb
993
991
  - spec/support/alchemy/integration_helpers.rb
992
+ - spec/support/alchemy/test_tweaks.rb
994
993
  - spec/support/ci/install_phantomjs
995
994
  - spec/support/factories.rb
996
995
  - spec/support/image with spaces.png
@@ -1211,8 +1210,6 @@ test_files:
1211
1210
  - spec/dummy/public/stylesheets/.gitkeep
1212
1211
  - spec/dummy/script/rails
1213
1212
  - spec/fast_specs.rb
1214
- - spec/features/admin/element_create_feature_spec.rb
1215
- - spec/features/admin/element_trash_feature_spec.rb
1216
1213
  - spec/features/admin/link_overlay_spec.rb
1217
1214
  - spec/features/admin/modules_integration_spec.rb
1218
1215
  - spec/features/admin/pages_controller_spec.rb
@@ -1284,6 +1281,7 @@ test_files:
1284
1281
  - spec/support/alchemy/controller_hacks.rb
1285
1282
  - spec/support/alchemy/controller_helpers.rb
1286
1283
  - spec/support/alchemy/integration_helpers.rb
1284
+ - spec/support/alchemy/test_tweaks.rb
1287
1285
  - spec/support/ci/install_phantomjs
1288
1286
  - spec/support/factories.rb
1289
1287
  - spec/support/image with spaces.png
@@ -1,4 +0,0 @@
1
- module Alchemy
2
- class TreeNode < Struct.new(:left, :right, :parent, :depth, :url, :restricted)
3
- end
4
- end
@@ -1,18 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe 'element create feature', js: true do
4
- let(:a_page) { FactoryGirl.create(:page) }
5
-
6
- before do
7
- authorize_as_admin
8
- visit edit_admin_page_path(a_page)
9
- expect(page).to have_no_selector('.alchemy-elements-window .element_editor')
10
- end
11
-
12
- it "adds a new element to the list" do
13
- create_element!
14
- expect(page).to have_no_selector(".spinner") # wait until spinner disappears
15
- expect(page).to have_selector(".element_editor", count: 1)
16
- end
17
- end
18
-
@@ -1,21 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "element trash feature", js: true do
4
- let(:a_page) { FactoryGirl.create(:page) }
5
-
6
- before do
7
- authorize_as_admin
8
- visit edit_admin_page_path(a_page)
9
- create_element! # We want to trash an article element later because it contains a richtext essence
10
- expect(page).to have_no_selector(".spinner") # wait until spinner disappears
11
- end
12
-
13
- it "removes an element from the list" do
14
- expect(page).to have_selector(".element_editor", count: 1)
15
- within ".alchemy-elements-window .element_editor:first" do
16
- click_link Alchemy::I18n.t("trash element")
17
- end
18
- expect(page).to have_content Alchemy::I18n.t('Element trashed')
19
- expect(page).to have_no_selector(".element_editor")
20
- end
21
- end