zen 0.4.2 → 0.4.3

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 (131) hide show
  1. data/.gems +17 -15
  2. data/.gitignore +1 -1
  3. data/.travis.yml +1 -1
  4. data/MANIFEST +470 -0
  5. data/README.md +5 -3
  6. data/Rakefile +8 -6
  7. data/bin/zen +2 -7
  8. data/guide/asset_management.md +1 -0
  9. data/guide/autosaving_forms.md +1 -0
  10. data/guide/changelog.md +22 -0
  11. data/guide/faq.md +1 -0
  12. data/guide/getting_started.md +1 -0
  13. data/guide/hacking.md +1 -0
  14. data/guide/images/sections/revisions.png +0 -0
  15. data/guide/images/sections/revisions_diff.png +0 -0
  16. data/guide/images/sections/revisions_diff_multiple.png +0 -0
  17. data/guide/installation.md +4 -3
  18. data/guide/javascript.md +1 -0
  19. data/guide/javascript/zen_autosave.md +1 -0
  20. data/guide/javascript/zen_editor.md +1 -0
  21. data/guide/javascript/zen_form.md +1 -0
  22. data/guide/javascript/zen_hash.md +1 -0
  23. data/guide/javascript/zen_htmltable.md +1 -0
  24. data/guide/javascript/zen_tabs.md +1 -0
  25. data/guide/javascript/zen_window.md +1 -0
  26. data/guide/zen_compared.md +1 -0
  27. data/lib/zen.rb +10 -12
  28. data/lib/zen/event.rb +2 -2
  29. data/lib/zen/helper/controller.rb +13 -13
  30. data/lib/zen/helper/message.rb +3 -3
  31. data/lib/zen/helper/search.rb +4 -4
  32. data/lib/zen/helper/stacked_aspect.rb +9 -9
  33. data/lib/zen/html_diff.rb +151 -0
  34. data/lib/zen/language.rb +9 -7
  35. data/lib/zen/language/translation.rb +8 -8
  36. data/lib/zen/markup.rb +1 -1
  37. data/lib/zen/migrator.rb +2 -2
  38. data/lib/zen/model/helper.rb +4 -4
  39. data/lib/zen/model/plugin/events.rb +16 -16
  40. data/lib/zen/package.rb +2 -2
  41. data/lib/zen/package/all.rb +1 -1
  42. data/lib/zen/package/categories/lib/categories/controller/categories.rb +4 -4
  43. data/lib/zen/package/categories/lib/categories/controller/category_groups.rb +4 -4
  44. data/lib/zen/package/categories/lib/categories/helper/category.rb +3 -3
  45. data/lib/zen/package/categories/lib/categories/model/category.rb +9 -9
  46. data/lib/zen/package/categories/lib/categories/model/category_group.rb +9 -9
  47. data/lib/zen/package/comments/lib/comments/controller/comments.rb +4 -4
  48. data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +2 -2
  49. data/lib/zen/package/comments/lib/comments/helper/comment.rb +1 -1
  50. data/lib/zen/package/comments/lib/comments/model/comment.rb +13 -13
  51. data/lib/zen/package/custom_fields/lib/custom_fields/blue_form_parameters.rb +1 -1
  52. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_groups.rb +4 -4
  53. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_types.rb +6 -6
  54. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_fields.rb +5 -5
  55. data/lib/zen/package/custom_fields/lib/custom_fields/helper/custom_field.rb +3 -3
  56. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field.rb +9 -9
  57. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_group.rb +9 -9
  58. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_type.rb +9 -9
  59. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +8 -3
  60. data/lib/zen/package/custom_fields/migrations/1336171490_revisions.rb +41 -0
  61. data/lib/zen/package/dashboard/lib/dashboard/controller/dashboard.rb +6 -6
  62. data/lib/zen/package/dashboard/lib/dashboard/model/widget.rb +3 -3
  63. data/lib/zen/package/dashboard/lib/dashboard/widget.rb +12 -12
  64. data/lib/zen/package/extensions/lib/extensions/controller/extensions.rb +3 -3
  65. data/lib/zen/package/menus/lib/menus/controller/menu_items.rb +5 -5
  66. data/lib/zen/package/menus/lib/menus/controller/menus.rb +4 -4
  67. data/lib/zen/package/menus/lib/menus/helper/menu.rb +4 -4
  68. data/lib/zen/package/menus/lib/menus/model/menu.rb +11 -11
  69. data/lib/zen/package/menus/lib/menus/model/menu_item.rb +10 -10
  70. data/lib/zen/package/menus/lib/menus/public/admin/menus/js/lib/nested_sortables.js +13 -13
  71. data/lib/zen/package/menus/lib/menus/public/admin/menus/js/menu_items.js +1 -1
  72. data/lib/zen/package/sections/lib/sections.rb +19 -0
  73. data/lib/zen/package/sections/lib/sections/controller/revisions.rb +184 -0
  74. data/lib/zen/package/sections/lib/sections/controller/section_entries.rb +5 -5
  75. data/lib/zen/package/sections/lib/sections/controller/sections.rb +9 -6
  76. data/lib/zen/package/sections/lib/sections/helper/revision.rb +124 -0
  77. data/lib/zen/package/sections/lib/sections/helper/section.rb +17 -15
  78. data/lib/zen/package/sections/lib/sections/helper/section_frontend.rb +104 -6
  79. data/lib/zen/package/sections/lib/sections/language/en/revisions.rb +34 -0
  80. data/lib/zen/package/sections/lib/sections/language/en/sections.rb +1 -0
  81. data/lib/zen/package/sections/lib/sections/language/nl/revisions.rb +35 -0
  82. data/lib/zen/package/sections/lib/sections/language/nl/sections.rb +1 -0
  83. data/lib/zen/package/sections/lib/sections/model/revision.rb +76 -0
  84. data/lib/zen/package/sections/lib/sections/model/section.rb +9 -9
  85. data/lib/zen/package/sections/lib/sections/model/section_entry.rb +47 -12
  86. data/lib/zen/package/sections/lib/sections/view/admin/revisions/index.xhtml +89 -0
  87. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/form.xhtml +1 -1
  88. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/index.xhtml +14 -0
  89. data/lib/zen/package/sections/migrations/1335711557_revisions.rb +40 -0
  90. data/lib/zen/package/settings/lib/settings/controller/settings.rb +12 -4
  91. data/lib/zen/package/settings/lib/settings/setting.rb +6 -6
  92. data/lib/zen/package/users/lib/users/controller/user_groups.rb +4 -4
  93. data/lib/zen/package/users/lib/users/controller/users.rb +12 -12
  94. data/lib/zen/package/users/lib/users/helper/access.rb +1 -1
  95. data/lib/zen/package/users/lib/users/helper/acl.rb +4 -4
  96. data/lib/zen/package/users/lib/users/helper/users.rb +2 -2
  97. data/lib/zen/package/users/lib/users/model/permission.rb +1 -1
  98. data/lib/zen/package/users/lib/users/model/user.rb +11 -11
  99. data/lib/zen/package/users/lib/users/model/user_group.rb +9 -9
  100. data/lib/zen/package/users/lib/users/model/user_status.rb +2 -2
  101. data/lib/zen/public/admin/zen/css/general.css +54 -0
  102. data/lib/zen/public/admin/zen/css/messages.css +6 -3
  103. data/lib/zen/public/admin/zen/css/tables.css +10 -0
  104. data/lib/zen/public/admin/zen/images/icons/undo.png +0 -0
  105. data/lib/zen/public/admin/zen/js/lib/autosave.js +8 -8
  106. data/lib/zen/public/admin/zen/js/lib/base.js +2 -2
  107. data/lib/zen/public/admin/zen/js/lib/events.js +2 -2
  108. data/lib/zen/public/admin/zen/js/lib/form.js +7 -7
  109. data/lib/zen/public/admin/zen/js/lib/hash.js +7 -7
  110. data/lib/zen/public/admin/zen/js/lib/tabs.js +3 -3
  111. data/lib/zen/public/admin/zen/js/lib/window.js +1 -1
  112. data/lib/zen/security.rb +2 -2
  113. data/lib/zen/spec/helper.rb +3 -9
  114. data/lib/zen/spec/helper/capybara.rb +4 -4
  115. data/lib/zen/spec/helper/general.rb +1 -1
  116. data/lib/zen/spec/simplecov.rb +1 -5
  117. data/lib/zen/task/build.rake +22 -16
  118. data/lib/zen/task/db.rake +3 -2
  119. data/lib/zen/task/spelling.rake +10 -10
  120. data/lib/zen/task/test.rake +27 -19
  121. data/lib/zen/theme.rb +6 -6
  122. data/lib/zen/version.rb +1 -1
  123. data/spec/zen/all.rb +4 -0
  124. data/spec/zen/package/sections/controller/revisions.rb +235 -0
  125. data/spec/zen/package/sections/model/revision.rb +76 -0
  126. data/zen.gemspec +23 -21
  127. metadata +88 -29
  128. data/lib/zen/model/methods.rb +0 -27
  129. data/lib/zen/task/clean.rake +0 -20
  130. data/lib/zen/task/setup.rake +0 -4
  131. data/pkg/.gitkeep +0 -0
@@ -40,35 +40,35 @@ namespace('Zen');
40
40
  *
41
41
  * hash.getHash(); // => "#!/users/active?limit=10"
42
42
  *
43
- * @since 19-12-2011
43
+ * @since 2011-12-19
44
44
  */
45
45
  Zen.Hash = new Class(
46
46
  {
47
47
  /**
48
48
  * String containing the raw URL hash before it was parsed.
49
49
  *
50
- * @since 19-12-2011
50
+ * @since 2011-12-19
51
51
  */
52
52
  raw_hash: '',
53
53
 
54
54
  /**
55
55
  * Object containing all the parsed hash parameters.
56
56
  *
57
- * @since 19-12-2011
57
+ * @since 2011-12-19
58
58
  */
59
59
  params: {},
60
60
 
61
61
  /**
62
62
  * Array containing all the hash segments.
63
63
  *
64
- * @since 19-12-2011
64
+ * @since 2011-12-19
65
65
  */
66
66
  segments: [],
67
67
 
68
68
  /**
69
69
  * Creates a new instance of the class, sets the raw hash and parses it.
70
70
  *
71
- * @since 19-12-2011
71
+ * @since 2011-12-19
72
72
  * @param {string} hash The URL hash to parse.
73
73
  */
74
74
  initialize: function(hash)
@@ -79,7 +79,7 @@ Zen.Hash = new Class(
79
79
  /**
80
80
  * Parses the supplied hash and stores the results in ``this.params``.
81
81
  *
82
- * @since 19-12-2011
82
+ * @since 2011-12-19
83
83
  * @param {string} hash The hash to parse.
84
84
  */
85
85
  parse: function(hash)
@@ -140,7 +140,7 @@ Zen.Hash = new Class(
140
140
  * Returns a string containing the hash URL for the current segments and
141
141
  * parameters.
142
142
  *
143
- * @since 19-12-2011
143
+ * @since 2011-12-19
144
144
  * @return {string}
145
145
  */
146
146
  getHash: function()
@@ -100,7 +100,7 @@ Zen.Tabs = new Class(
100
100
  * Binds various events to show the right tab fields when a tab is clicked
101
101
  * or when the URL hash is changed.
102
102
  *
103
- * @since 21-12-2011
103
+ * @since 2011-12-21
104
104
  */
105
105
  addEvents: function()
106
106
  {
@@ -134,7 +134,7 @@ Zen.Tabs = new Class(
134
134
  * Determines the default tab field to display based on the option
135
135
  * ``this.options.default`` or the current hash URL.
136
136
  *
137
- * @since 21-12-2011
137
+ * @since 2011-12-21
138
138
  */
139
139
  displayDefault: function()
140
140
  {
@@ -164,7 +164,7 @@ Zen.Tabs = new Class(
164
164
  /**
165
165
  * Activates the tab field for the given ID.
166
166
  *
167
- * @since 21-12-2011
167
+ * @since 2011-12-21
168
168
  * @param {string} id The ID of the tab field to show.
169
169
  */
170
170
  toggleTab: function(id)
@@ -105,7 +105,7 @@ Zen.Window = new Class(
105
105
  /**
106
106
  * The background overlay for the current window.
107
107
  *
108
- * @since 18-12-2011
108
+ * @since 2011-12-18
109
109
  */
110
110
  overlay: null,
111
111
 
@@ -3,7 +3,7 @@ module Zen
3
3
  # Module for dealing with various security related actions such as sanitizing
4
4
  # user input/output.
5
5
  #
6
- # @since 07-01-2012
6
+ # @since 2012-01-07
7
7
  #
8
8
  module Security
9
9
  class << self
@@ -21,7 +21,7 @@ module Zen
21
21
  #
22
22
  # Zen::Input.sanitize(input) # => "Hello \#\{puts 10\}"
23
23
  #
24
- # @since 03-01-2012
24
+ # @since 2012-01-03
25
25
  # @param [String] input The input string to sanitize.
26
26
  # @param [TrueClass|FalseClass] clean_html When set to true certain HTML
27
27
  # elements will be removed using Loofah.
@@ -1,12 +1,6 @@
1
- require 'ramaze'
2
- require 'stringio'
3
-
4
- Ramaze.setup(:verbose => false) do
5
- gem 'capybara', ['>= 1.1.1']
6
- gem 'bacon' , ['>= 1.1.0']
7
- gem 'webmock' , ['>= 1.6.4']
8
- end
9
-
1
+ require 'capybara'
2
+ require 'bacon'
3
+ require 'webmock'
10
4
  require 'capybara/dsl'
11
5
  require 'ramaze/spec/bacon'
12
6
 
@@ -4,7 +4,7 @@ module Zen
4
4
  ##
5
5
  # Module providing various helper methods for Capybara based tests.
6
6
  #
7
- # @since 18-02-2012
7
+ # @since 2012-02-18
8
8
  #
9
9
  module Capybara
10
10
  ##
@@ -30,7 +30,7 @@ module Zen
30
30
  ##
31
31
  # Automatically saves a form with the given ID.
32
32
  #
33
- # @since 18-02-2012
33
+ # @since 2012-02-18
34
34
  # @param [String] id The ID of the form.
35
35
  #
36
36
  def autosave_form(id)
@@ -50,7 +50,7 @@ module Zen
50
50
  ##
51
51
  # Switches Capybara's driver to the default Javascript driver.
52
52
  #
53
- # @since 18-02-2012
53
+ # @since 2012-02-18
54
54
  #
55
55
  def enable_javascript
56
56
  WebMock.disable!
@@ -63,7 +63,7 @@ module Zen
63
63
  ##
64
64
  # Switches Capybara's driver back to the default driver.
65
65
  #
66
- # @since 18-02-2012
66
+ # @since 2012-02-18
67
67
  #
68
68
  def disable_javascript
69
69
  ::Capybara.use_default_driver
@@ -4,7 +4,7 @@ module Zen
4
4
  ##
5
5
  # Module providing general spec helpers.
6
6
  #
7
- # @since 18-02-2012
7
+ # @since 2012-02-18
8
8
  #
9
9
  module General
10
10
  ##
@@ -1,8 +1,4 @@
1
- require 'ramaze'
2
-
3
- Ramaze.setup(:verbose => false) do
4
- gem 'simplecov', ['>= 0.4.2']
5
- end
1
+ require 'simplecov'
6
2
 
7
3
  SimpleCov.configure do
8
4
  root __DIR__('../../../')
@@ -1,23 +1,29 @@
1
1
  namespace :build do
2
- desc 'Build the YARD docs'
3
- task :doc => ['clean:yard'] do
4
- root = File.expand_path('../../../../', __FILE__)
5
- Dir.chdir(root)
2
+ desc 'Generates the Manifest'
3
+ task :manifest do
4
+ files = `git ls-files`.split("\n").sort
5
+ handle = File.open(File.expand_path('../../../../MANIFEST', __FILE__), 'w')
6
6
 
7
- sh('yard doc')
7
+ handle.write(files.join("\n"))
8
+ handle.close
8
9
  end
9
10
 
10
- desc 'Builds a new Gem'
11
- task :gem do
12
- root = File.expand_path('../../../../', __FILE__)
13
- name = "#{Zen::Gemspec.name}-#{Zen::Gemspec.version.version}.gem"
14
- path = File.join(root, name)
15
- pkg = File.join(root, 'pkg', name)
16
-
17
- # Build and install the gem
18
- sh('gem', 'build', File.join(root, 'zen.gemspec'))
19
- sh('mv' , path, pkg)
20
- sh('gem', 'install', pkg)
11
+ desc 'Generates a .gems file for RVM'
12
+ task :gems do
13
+ handle = File.open(File.expand_path('../../../../.gems', __FILE__), 'w')
14
+ run_deps = ['# Runtime Dependencies']
15
+ dev_deps = ['# Development Dependencies']
16
+
17
+ GEMSPEC.dependencies.each do |gem|
18
+ if gem.type == :runtime
19
+ run_deps << gem.name + ' -v ' + gem.requirement.to_s.gsub('~> ', '')
20
+ else
21
+ dev_deps << gem.name
22
+ end
23
+ end
24
+
25
+ handle.write(run_deps.sort.join("\n") + "\n\n" + dev_deps.sort.join("\n"))
26
+ handle.close
21
27
  end
22
28
 
23
29
  desc 'Build a list of changes'
@@ -77,8 +77,9 @@ namespace :db do
77
77
 
78
78
  if group.nil?
79
79
  group = Users::Model::UserGroup.new(
80
- :name => 'Administrators',
81
- :slug => 'administrators', :super_group => true
80
+ :name => 'Administrators',
81
+ :slug => 'administrators',
82
+ :super_group => true
82
83
  ).save
83
84
  end
84
85
 
@@ -1,22 +1,22 @@
1
- # Task that checks the documentation for spelling errors using Raspell/Aspell.
2
- # This task requires Aspell to be installed along with an English dictionary. On
3
- # Arch Linux these can be installed as following:
1
+ # Task that checks the documentation for spelling errors using Aspell. This
2
+ # task requires Aspell to be installed along with an English dictionary. On Arch
3
+ # Linux these can be installed as following:
4
4
  #
5
5
  # $ sudo pacman -S aspell aspell-en
6
6
  #
7
7
  desc 'Search docs for spelling errors'
8
8
  task :spelling do
9
- require 'raspell'
9
+ require 'ffi/aspell'
10
10
  require 'ripper'
11
11
 
12
- speller = Aspell.new1(
13
- 'lang' => 'en',
12
+ speller = FFI::Aspell::Speller.new(
13
+ 'en',
14
14
  'personal' => File.expand_path('../../../../.aspell.en.pws', __FILE__),
15
- 'ignore-case' => 'true'
15
+ 'ignore-case' => true
16
16
  )
17
17
 
18
18
  base_dir = File.expand_path('../../../..', __FILE__)
19
- files = Dir['lib/zen/**/*.rb']
19
+ files = Dir['lib/zen/**/*.rb'] + Dir['guide/**/*.md']
20
20
  exclude_lines = [/^#\s*@/, /^#\s{2,}/, /^#\s*!\[/, /^#\s*\[/]
21
21
  exclude_patterns = [/\d+/, /_+/, /^`/]
22
22
 
@@ -68,8 +68,8 @@ task :spelling do
68
68
 
69
69
  next if skip == true
70
70
 
71
- unless speller.check(word)
72
- suggested = speller.suggest(word)[0]
71
+ unless speller.correct?(word)
72
+ suggested = speller.suggestions(word)[0]
73
73
 
74
74
  if suggested
75
75
  errors << {
@@ -1,40 +1,50 @@
1
1
  namespace :test do
2
- spec_dir = File.expand_path('../../../../spec', __FILE__)
3
- command = 'rake db:delete; rake db:migrate; rake db:test_user; ' \
4
- 'ruby zen/all.rb'
5
-
6
- desc 'Run specifications'
2
+ desc 'Run test using default settings'
7
3
  task :default do
8
- Dir.chdir(spec_dir)
4
+ Dir.chdir(File.expand_path('../../../../spec', __FILE__))
5
+
6
+ sh('rake db:delete')
7
+ sh('rake db:migrate')
8
+ sh('rake db:test_user')
9
9
 
10
- sh(command)
10
+ # Hack to prevent Simplecov from generating code coverage while migrating
11
+ # the database.
12
+ if ENV['_COVERAGE']
13
+ ENV['_COVERAGE'] = nil
14
+ ENV['COVERAGE'] = '1'
15
+ end
16
+
17
+ sh('ruby zen/all.rb')
11
18
  end
12
19
 
13
- desc 'Runs specifications using MySQL'
20
+ desc 'Run tests using MySQL'
14
21
  task :mysql do
15
- Dir.chdir(spec_dir)
16
-
17
22
  ENV['DATABASE'] = 'zen_dev'
18
23
  ENV['ADAPTER'] = 'mysql2'
19
24
  ENV['USERNAME'] = 'zen'
20
25
 
21
- sh(command)
26
+ Rake::Task['test:default'].invoke
22
27
  end
23
28
 
24
- desc 'Runs specifications using PostgreSQL'
29
+ desc 'Run tests using PostgreSQL'
25
30
  task :postgres do
26
- Dir.chdir(spec_dir)
27
-
28
31
  ENV['DATABASE'] = 'zen_dev'
29
32
  ENV['ADAPTER'] = 'postgres'
30
33
  ENV['USERNAME'] = 'zen'
31
34
 
32
- sh(command)
35
+ Rake::Task['test:default'].invoke
36
+ end
37
+
38
+ desc 'Generates code coverage'
39
+ task :coverage do
40
+ ENV['_COVERAGE'] = '1'
41
+
42
+ Rake::Task['test:default'].invoke
33
43
  end
34
44
 
35
45
  # Task that ensures that the various Travis CI tests each use their own
36
46
  # database based on the Ruby version.
37
- desc 'Runs the tests for Travis CI'
47
+ desc 'Run tests for Travis CI'
38
48
  task :travis do
39
49
  suffix = '_' + RUBY_VERSION.gsub('.', '_')
40
50
 
@@ -48,8 +58,6 @@ namespace :test do
48
58
  end
49
59
  end
50
60
 
51
- Dir.chdir(spec_dir)
52
-
53
- sh(command)
61
+ Rake::Task['test:default'].invoke
54
62
  end
55
63
  end
@@ -97,7 +97,7 @@ module Zen
97
97
  #
98
98
  # <div class="note deprecated">
99
99
  # <p>
100
- # <strong>Warning</strong>: Most likely your template will use files
100
+ # <strong>Warning:</strong> Most likely your template will use files
101
101
  # such as CSS and Javascript files. It's important to store these
102
102
  # under their own namespace similar to assets used in the backend to
103
103
  # prevent any collisions.
@@ -257,7 +257,7 @@ module Zen
257
257
  #
258
258
  # <div class="note deprecated">
259
259
  # <p>
260
- # <strong>Warning</strong>: Don't run custom SQL queries inside your
260
+ # <strong>Warning:</strong> Don't run custom SQL queries inside your
261
261
  # templates, create a helper, regular class or module if you want to
262
262
  # retrieve custom data.
263
263
  # </p>
@@ -291,7 +291,7 @@ module Zen
291
291
  #
292
292
  # <div class="note todo">
293
293
  # <p>
294
- # <strong>Note</strong>: The variables set in the partial method are
294
+ # <strong>Note:</strong> The variables set in the partial method are
295
295
  # available as instance variables, not regular variables.
296
296
  # </p>
297
297
  # </div>
@@ -376,7 +376,7 @@ module Zen
376
376
  ##
377
377
  # Creates a new instance of the theme.
378
378
  #
379
- # @since 12-02-2012
379
+ # @since 2012-02-12
380
380
  #
381
381
  def initialize
382
382
  @env = OpenStruct.new
@@ -396,7 +396,7 @@ module Zen
396
396
  # Returns the name of the theme as either plain text or an anchor tag if the
397
397
  # URL attribute is set.
398
398
  #
399
- # @since 19-11-2011
399
+ # @since 2011-11-19
400
400
  # @return [String]
401
401
  #
402
402
  def formatted_name
@@ -430,7 +430,7 @@ module Zen
430
430
  # Returns the name of the default template group or "default" if no custom
431
431
  # name is set.
432
432
  #
433
- # @since 22-11-2011
433
+ # @since 2011-11-22
434
434
  # @return [String]
435
435
  #
436
436
  def default_template_group
@@ -1,4 +1,4 @@
1
1
  module Zen
2
2
  # :nodoc:
3
- VERSION = '0.4.2'
3
+ VERSION = '0.4.3'
4
4
  end
@@ -1,5 +1,9 @@
1
1
  require File.expand_path('../../helper', __FILE__)
2
2
 
3
+ puts "# Ruby version: #{RUBY_VERSION}p#{RUBY_PATCHLEVEL}"
4
+ puts "# Database adapter: #{Zen.database.adapter_scheme}"
5
+ puts "# Database: #{ENV['DATABASE'] || 'SQLite3'}"
6
+
3
7
  Dir.glob(__DIR__ + '/**/*.rb').each do |t|
4
8
  require(t) if File.basename(t) != 'all.rb'
5
9
  end
@@ -0,0 +1,235 @@
1
+ require File.expand_path('../../../../../helper', __FILE__)
2
+
3
+ describe 'Sections::Controller::Revisions' do
4
+ behaves_like :capybara
5
+
6
+ textbox_id = CustomFields::Model::CustomFieldType[:name => 'textbox'].id
7
+ checkbox_id = CustomFields::Model::CustomFieldType[:name => 'checkbox'].id
8
+ section = Sections::Model::Section.create(
9
+ :name => 'Spec section',
10
+ :comment_allow => true,
11
+ :comment_require_account => true,
12
+ :comment_moderate => true,
13
+ :comment_format => 'plain'
14
+ )
15
+
16
+ group = CustomFields::Model::CustomFieldGroup.create(:name => 'Spec fields')
17
+
18
+ field = CustomFields::Model::CustomField.create(
19
+ :name => 'Spec field',
20
+ :sort_order => 0,
21
+ :format => 'markdown',
22
+ :required => true,
23
+ :text_editor => false,
24
+ :custom_field_group_id => group.id,
25
+ :custom_field_type_id => textbox_id
26
+ )
27
+
28
+ field_1 = CustomFields::Model::CustomField.create(
29
+ :name => 'Spec checkbox',
30
+ :sort_order => 1,
31
+ :format => 'plain',
32
+ :required => true,
33
+ :text_editor => false,
34
+ :custom_field_group_id => group.id,
35
+ :custom_field_type_id => checkbox_id,
36
+ :possible_values => "Yorick Peterse|yorick\nChuck Norris|chuck"
37
+ )
38
+
39
+ section.custom_field_group_pks = [group.id]
40
+
41
+ entries_url = Sections::Controller::SectionEntries.r(:index, section.id).to_s
42
+ edit_url = Sections::Controller::SectionEntries.r(:edit, section.id).to_s
43
+ revisions_url = lang('revisions.titles.index')
44
+ restore_url = lang('revisions.labels.restore')
45
+ new_button = lang('section_entries.buttons.new')
46
+ save_button = lang('section_entries.buttons.save')
47
+ compare_button = lang('revisions.buttons.compare')
48
+ title_field = lang('section_entries.labels.title')
49
+
50
+ it 'Create a new revision each time a section entry is saved' do
51
+ visit(entries_url)
52
+
53
+ click_on(new_button)
54
+
55
+ within '#section_entry_form' do
56
+ fill_in(title_field, :with => 'Entry with revisions')
57
+ fill_in(field.name, :with => 'Original value')
58
+ check("form_custom_field_value_#{field_1.id}_0")
59
+
60
+ click_on(save_button)
61
+ end
62
+
63
+ current_path.should =~ /#{edit_url}\/[0-9]+/
64
+ page.has_selector?('.message.error').should == false
65
+
66
+ 9.times do |number|
67
+ within '#section_entry_form' do
68
+ fill_in(field.name, :with => "Modified #{number}")
69
+
70
+ click_on(save_button)
71
+ end
72
+ end
73
+
74
+ page.find_field(field.name).value.should == 'Modified 8'
75
+
76
+ Sections::Model::SectionEntry[:title => 'Entry with revisions'] \
77
+ .revisions.length.should == 10
78
+ end
79
+
80
+ it 'Compare two different revisions' do
81
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
82
+ url = Sections::Controller::Revisions \
83
+ .r(:index, entry.section_id, entry.id) \
84
+ .to_s
85
+
86
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
87
+ .order(:id.asc) \
88
+ .all
89
+
90
+ visit(entries_url)
91
+ click_on(revisions_url)
92
+
93
+ page.current_path.should == url
94
+ page.all('table tbody tr').count.should == 10
95
+
96
+ choose("old_revision_id_#{revisions[0].id}")
97
+ choose("new_revision_id_#{revisions[1].id}")
98
+
99
+ click_on(compare_button)
100
+
101
+ page.has_selector?('.diff').should == true
102
+ page.has_selector?('.diff .ins').should == true
103
+ page.has_selector?('.diff .del').should == true
104
+ page.has_selector?('.diff .line_number').should == true
105
+
106
+ page.has_content?('Original value').should == true
107
+ page.has_content?('Modified 0').should == true
108
+
109
+ page.find('.diff .del').text.strip.should == '-Original value'
110
+ page.find('.diff .ins').text.strip.should == '+Modified 0'
111
+
112
+ choose("old_revision_id_#{revisions[1].id}")
113
+ choose("new_revision_id_#{revisions[2].id}")
114
+
115
+ click_on(compare_button)
116
+
117
+ page.find('.diff .del').text.strip.should == '-Modified 0'
118
+ page.find('.diff .ins').text.strip.should == '+Modified 1'
119
+ end
120
+
121
+ it 'Compare the same two revisions' do
122
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
123
+ url = Sections::Controller::Revisions \
124
+ .r(:index, entry.section_id, entry.id) \
125
+ .to_s
126
+
127
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
128
+ .order(:id.asc) \
129
+ .all
130
+
131
+ visit(entries_url)
132
+ click_on(revisions_url)
133
+
134
+ page.current_path.should == url
135
+ page.all('table tbody tr').count.should == 10
136
+
137
+ choose("old_revision_id_#{revisions[0].id}")
138
+ choose("new_revision_id_#{revisions[0].id}")
139
+
140
+ click_on(compare_button)
141
+
142
+ page.has_selector?('.diff').should == false
143
+ page.has_content?(lang('revisions.messages.no_differences')).should == true
144
+ end
145
+
146
+ it 'The oldest revision should be removed if the limit is exceeded' do
147
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
148
+ oldest = entry.revisions[-1].id
149
+
150
+ visit(entries_url)
151
+
152
+ click_on('Entry with revisions')
153
+
154
+ 5.times do |number|
155
+ within '#section_entry_form' do
156
+ fill_in(field.name, :with => "Overwritten #{number}")
157
+ click_on(save_button)
158
+ end
159
+ end
160
+
161
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
162
+ .order(:id.asc) \
163
+ .all
164
+
165
+ revisions.length.should == 10
166
+ revisions[0].id.should > oldest
167
+ end
168
+
169
+ it 'Gracefully handle non numeric revision IDs' do
170
+ visit(entries_url)
171
+ visit(Sections::Controller::Revisions.r(:restore, 'a').to_s)
172
+
173
+ page.current_path.should == entries_url
174
+ page.has_selector?('.message.error').should == true
175
+ end
176
+
177
+ it 'Restore a revision and delete newer revisions' do
178
+ visit(entries_url)
179
+ click_on(revisions_url)
180
+
181
+ within 'table tbody tr:last-child' do
182
+ click_on(restore_url)
183
+ end
184
+
185
+ page.has_selector?('.message.success').should == true
186
+ page.all('table tbody tr').count.should == 1
187
+
188
+ Sections::Model::SectionEntry[:title => 'Entry with revisions'] \
189
+ .revisions \
190
+ .length \
191
+ .should == 1
192
+
193
+ visit(entries_url)
194
+ click_on('Entry with revisions')
195
+
196
+ page.find_field(field.name).value.should == 'Modified 4'
197
+ end
198
+
199
+ it 'Compare array based values of two revisions' do
200
+ visit(entries_url)
201
+
202
+ click_on('Entry with revisions')
203
+
204
+ within '#section_entry_form' do
205
+ check("form_custom_field_value_#{field_1.id}_1")
206
+ click_on(save_button)
207
+ end
208
+
209
+ page.has_selector?('.message.error').should == false
210
+
211
+ visit(entries_url)
212
+ click_on(revisions_url)
213
+
214
+ entry = Sections::Model::SectionEntry[:title => 'Entry with revisions']
215
+ revisions = Sections::Model::Revision.filter(:section_entry_id => entry.id) \
216
+ .order(:id.asc) \
217
+ .all
218
+
219
+ choose("old_revision_id_#{revisions[-1].id}")
220
+ choose("new_revision_id_#{revisions[-2].id}")
221
+
222
+ click_on(compare_button)
223
+
224
+ page.has_selector?('.diff .ins').should == false
225
+ page.has_selector?('.diff .del').should == true
226
+
227
+ page.has_content?('yorick').should == true
228
+ page.has_content?('chuck').should == true
229
+ end
230
+
231
+ field.destroy
232
+ field_1.destroy
233
+ group.destroy
234
+ section.destroy
235
+ end