lucy_cms 0.0.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.
- data/Gemfile +19 -0
- data/Gemfile.lock +88 -0
- data/LICENSE +24 -0
- data/README.md +161 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/app/controllers/application_controller.rb +5 -0
- data/app/controllers/cms_admin/base_controller.rb +43 -0
- data/app/controllers/cms_admin/layouts_controller.rb +66 -0
- data/app/controllers/cms_admin/pages_controller.rb +111 -0
- data/app/controllers/cms_admin/sessions_controller.rb +25 -0
- data/app/controllers/cms_admin/sites_controller.rb +69 -0
- data/app/controllers/cms_admin/snippets_controller.rb +62 -0
- data/app/controllers/cms_admin/upload_dirs_controller.rb +79 -0
- data/app/controllers/cms_admin/users_controller.rb +129 -0
- data/app/controllers/cms_content_controller.rb +51 -0
- data/app/models/cms_block.rb +28 -0
- data/app/models/cms_layout.rb +118 -0
- data/app/models/cms_page.rb +163 -0
- data/app/models/cms_site.rb +38 -0
- data/app/models/cms_snippet.rb +70 -0
- data/app/models/cms_upload.rb +19 -0
- data/app/models/cms_upload_dir.rb +11 -0
- data/app/models/cms_user.rb +93 -0
- data/app/views/cms_admin/layouts/_form.html.erb +10 -0
- data/app/views/cms_admin/layouts/_index_branch.html.erb +24 -0
- data/app/views/cms_admin/layouts/edit.html.erb +6 -0
- data/app/views/cms_admin/layouts/index.html.erb +6 -0
- data/app/views/cms_admin/layouts/new.html.erb +6 -0
- data/app/views/cms_admin/pages/_form.html.erb +37 -0
- data/app/views/cms_admin/pages/_form_blocks.html.erb +7 -0
- data/app/views/cms_admin/pages/_index_branch.html.erb +40 -0
- data/app/views/cms_admin/pages/edit.html.erb +5 -0
- data/app/views/cms_admin/pages/form_blocks.js.erb +2 -0
- data/app/views/cms_admin/pages/index.html.erb +6 -0
- data/app/views/cms_admin/pages/new.html.erb +5 -0
- data/app/views/cms_admin/pages/toggle_branch.js.erb +11 -0
- data/app/views/cms_admin/sessions/new.html.erb +12 -0
- data/app/views/cms_admin/sites/_form.html.erb +16 -0
- data/app/views/cms_admin/sites/edit.html.erb +6 -0
- data/app/views/cms_admin/sites/new.html.erb +6 -0
- data/app/views/cms_admin/sites/setup.html.erb +16 -0
- data/app/views/cms_admin/snippets/_form.html.erb +4 -0
- data/app/views/cms_admin/snippets/edit.html.erb +6 -0
- data/app/views/cms_admin/snippets/index.html.erb +23 -0
- data/app/views/cms_admin/snippets/new.html.erb +6 -0
- data/app/views/cms_admin/upload_dirs/_file.html.erb +15 -0
- data/app/views/cms_admin/upload_dirs/_form.html.erb +2 -0
- data/app/views/cms_admin/upload_dirs/conflict.html.erb +12 -0
- data/app/views/cms_admin/upload_dirs/index.html.erb +23 -0
- data/app/views/cms_admin/upload_dirs/new.html.erb +6 -0
- data/app/views/cms_admin/upload_dirs/show.html.erb +26 -0
- data/app/views/cms_admin/upload_dirs/uploads_destroy.js.erb +3 -0
- data/app/views/cms_admin/users/_form.html.erb +9 -0
- data/app/views/cms_admin/users/_index_branch.html.erb +16 -0
- data/app/views/cms_admin/users/change_password.html.erb +14 -0
- data/app/views/cms_admin/users/edit.html.erb +17 -0
- data/app/views/cms_admin/users/index.html.erb +6 -0
- data/app/views/cms_admin/users/new.html.erb +14 -0
- data/app/views/layouts/cms_admin.html.erb +52 -0
- data/config/application.rb +48 -0
- data/config/boot.rb +13 -0
- data/config/database.yml +22 -0
- data/config/environment.rb +5 -0
- data/config/environments/development.rb +22 -0
- data/config/environments/production.rb +49 -0
- data/config/environments/test.rb +35 -0
- data/config/initializers/LucyCMS.rb +37 -0
- data/config/initializers/mime_types.rb +5 -0
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +45 -0
- data/config.ru +4 -0
- data/db/cms_seeds/example.local/layouts/default.yml +8 -0
- data/db/cms_seeds/example.local/layouts/nested.yml +6 -0
- data/db/cms_seeds/example.local/pages/child/subchild.yml +14 -0
- data/db/cms_seeds/example.local/pages/child.yml +10 -0
- data/db/cms_seeds/example.local/pages/index.yml +11 -0
- data/db/cms_seeds/example.local/snippets/example.yml +4 -0
- data/db/migrate/01_create_cms.rb +114 -0
- data/db/seeds.rb +7 -0
- data/lib/LucyCMS/acts_as_tree.rb +102 -0
- data/lib/LucyCMS/cms_tag/field_datetime.rb +26 -0
- data/lib/LucyCMS/cms_tag/field_integer.rb +26 -0
- data/lib/LucyCMS/cms_tag/field_string.rb +26 -0
- data/lib/LucyCMS/cms_tag/field_text.rb +26 -0
- data/lib/LucyCMS/cms_tag/helper.rb +20 -0
- data/lib/LucyCMS/cms_tag/page_datetime.rb +22 -0
- data/lib/LucyCMS/cms_tag/page_integer.rb +22 -0
- data/lib/LucyCMS/cms_tag/page_rich_text.rb +22 -0
- data/lib/LucyCMS/cms_tag/page_string.rb +22 -0
- data/lib/LucyCMS/cms_tag/page_text.rb +22 -0
- data/lib/LucyCMS/cms_tag/partial.rb +21 -0
- data/lib/LucyCMS/cms_tag/snippet.rb +22 -0
- data/lib/LucyCMS/cms_tag.rb +119 -0
- data/lib/LucyCMS/configuration.rb +36 -0
- data/lib/LucyCMS/controller_methods.rb +42 -0
- data/lib/LucyCMS/engine.rb +12 -0
- data/lib/LucyCMS/form_builder.rb +129 -0
- data/lib/LucyCMS/rails_extensions.rb +22 -0
- data/lib/LucyCMS/site_form_builder.rb +129 -0
- data/lib/LucyCMS/view_hooks.rb +30 -0
- data/lib/LucyCMS/view_methods.rb +68 -0
- data/lib/LucyCMS.rb +40 -0
- data/lib/generators/README +17 -0
- data/lib/generators/cms_generator.rb +44 -0
- data/lib/tasks/LucyCMS.rake +283 -0
- data/lucy_cms.gemspec +100 -0
- data/public/404.html +26 -0
- data/public/422.html +26 -0
- data/public/500.html +26 -0
- data/public/favicon.ico +0 -0
- data/public/images/LucyCMS/arrow_bottom.gif +0 -0
- data/public/images/LucyCMS/arrow_right.gif +0 -0
- data/public/images/LucyCMS/icon_folder.png +0 -0
- data/public/images/LucyCMS/icon_layout.gif +0 -0
- data/public/images/LucyCMS/icon_move.gif +0 -0
- data/public/images/LucyCMS/icon_regular.gif +0 -0
- data/public/images/LucyCMS/icon_snippet.gif +0 -0
- data/public/images/LucyCMS/icon_upload.png +0 -0
- data/public/images/LucyCMS/icon_user.jpg +0 -0
- data/public/javascripts/LucyCMS/cms.js +204 -0
- data/public/javascripts/LucyCMS/codemirror/codemirror.css +102 -0
- data/public/javascripts/LucyCMS/codemirror/codemirror.js +23 -0
- data/public/javascripts/LucyCMS/codemirror/codemirror_base.js +88 -0
- data/public/javascripts/LucyCMS/codemirror/parse_css.js +4 -0
- data/public/javascripts/LucyCMS/codemirror/parse_html_mixed.js +3 -0
- data/public/javascripts/LucyCMS/codemirror/parse_js.js +12 -0
- data/public/javascripts/LucyCMS/codemirror/parse_xml.js +7 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_75_dadada_1x400.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_222222_256x240.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_2e83ff_256x240.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_454545_256x240.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_888888_256x240.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/images/ui-icons_cd0a0a_256x240.png +0 -0
- data/public/javascripts/LucyCMS/jquery-ui/jquery-ui.css +362 -0
- data/public/javascripts/LucyCMS/jquery-ui/jquery-ui.js +190 -0
- data/public/javascripts/LucyCMS/jquery.js +154 -0
- data/public/javascripts/LucyCMS/plupload/plupload.full.min.js +1 -0
- data/public/javascripts/LucyCMS/plupload/plupload.html5.min.js +1 -0
- data/public/javascripts/LucyCMS/plupload/plupload.min.js +1 -0
- data/public/javascripts/LucyCMS/rails.js +132 -0
- data/public/javascripts/LucyCMS/tiny_mce/jquery.tinymce.js +1 -0
- data/public/javascripts/LucyCMS/tiny_mce/langs/en.js +170 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/about.htm +54 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/anchor.htm +26 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/charmap.htm +52 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/color_picker.htm +73 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/editor_template.js +1 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/image.htm +80 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/img/icons.gif +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/about.js +72 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/anchor.js +37 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/charmap.js +335 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/color_picker.js +253 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/image.js +245 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/link.js +156 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/js/source_editor.js +56 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/langs/en.js +62 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/langs/en_dlg.js +51 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/link.htm +58 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/content.css +36 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/dialog.css +117 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/skins/default/ui.css +213 -0
- data/public/javascripts/LucyCMS/tiny_mce/themes/advanced/source_editor.htm +25 -0
- data/public/javascripts/LucyCMS/tiny_mce/tiny_mce.js +1 -0
- data/public/javascripts/LucyCMS/tiny_mce/tiny_mce_popup.js +5 -0
- data/public/robots.txt +5 -0
- data/public/stylesheets/LucyCMS/content.css +196 -0
- data/public/stylesheets/LucyCMS/form.css +125 -0
- data/public/stylesheets/LucyCMS/reset.css +1 -0
- data/public/stylesheets/LucyCMS/site_form.css +82 -0
- data/public/stylesheets/LucyCMS/structure.css +125 -0
- data/public/stylesheets/LucyCMS/typography.css +25 -0
- data/script/rails +6 -0
- data/test/cms_seeds/test.host/layouts/broken.yml +1 -0
- data/test/cms_seeds/test.host/layouts/default.yml +3 -0
- data/test/cms_seeds/test.host/layouts/nested.yml +4 -0
- data/test/cms_seeds/test.host/pages/broken.yml +1 -0
- data/test/cms_seeds/test.host/pages/child/subchild.yml +10 -0
- data/test/cms_seeds/test.host/pages/child.yml +10 -0
- data/test/cms_seeds/test.host/pages/index.yml +10 -0
- data/test/cms_seeds/test.host/snippets/broken.yml +1 -0
- data/test/cms_seeds/test.host/snippets/default.yml +3 -0
- data/test/fixtures/cms_blocks.yml +12 -0
- data/test/fixtures/cms_layouts.yml +36 -0
- data/test/fixtures/cms_pages.yml +39 -0
- data/test/fixtures/cms_sites.yml +3 -0
- data/test/fixtures/cms_snippets.yml +5 -0
- data/test/fixtures/cms_upload_dirs.yml +9 -0
- data/test/fixtures/cms_uploads.yml +4 -0
- data/test/fixtures/cms_users.yml +11 -0
- data/test/fixtures/files/invalid_file.gif +9 -0
- data/test/fixtures/files/valid_image.jpg +0 -0
- data/test/fixtures/views/_nav_hook.html.erb +1 -0
- data/test/fixtures/views/_nav_hook_2.html.erb +1 -0
- data/test/functional/cms_admin/layouts_controller_test.rb +103 -0
- data/test/functional/cms_admin/pages_controller_test.rb +334 -0
- data/test/functional/cms_admin/sites_controller_test.rb +99 -0
- data/test/functional/cms_admin/snippets_controller_test.rb +102 -0
- data/test/functional/cms_admin/uploads_controller_test.rb +26 -0
- data/test/functional/cms_content_controller_test.rb +134 -0
- data/test/integration/rake_tasks_test.rb +65 -0
- data/test/integration/render_cms_seed_test.rb +34 -0
- data/test/integration/render_cms_test.rb +81 -0
- data/test/integration/sites_test.rb +63 -0
- data/test/integration/view_hooks_test.rb +33 -0
- data/test/test_helper.rb +86 -0
- data/test/unit/cms_block_test.rb +43 -0
- data/test/unit/cms_configuration_test.rb +17 -0
- data/test/unit/cms_layout_test.rb +146 -0
- data/test/unit/cms_page_test.rb +257 -0
- data/test/unit/cms_site_test.rb +41 -0
- data/test/unit/cms_snippet_test.rb +77 -0
- data/test/unit/cms_tag_test.rb +206 -0
- data/test/unit/cms_tags/field_datetime_test.rb +34 -0
- data/test/unit/cms_tags/field_integer_test.rb +33 -0
- data/test/unit/cms_tags/field_string_test.rb +34 -0
- data/test/unit/cms_tags/field_text_test.rb +32 -0
- data/test/unit/cms_tags/helper_test.rb +38 -0
- data/test/unit/cms_tags/page_datetime_test.rb +34 -0
- data/test/unit/cms_tags/page_integer_test.rb +33 -0
- data/test/unit/cms_tags/page_rich_text.rb +33 -0
- data/test/unit/cms_tags/page_string_test.rb +33 -0
- data/test/unit/cms_tags/page_text_test.rb +34 -0
- data/test/unit/cms_tags/partial_test.rb +44 -0
- data/test/unit/cms_tags/snippet_test.rb +33 -0
- data/test/unit/cms_upload_dir_test.rb +8 -0
- data/test/unit/cms_upload_test.rb +26 -0
- data/test/unit/cms_user_test.rb +8 -0
- data/test/unit/view_methods_test.rb +21 -0
- metadata +488 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
class CmsLayoutTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
def test_fixtures_validity
|
|
6
|
+
CmsLayout.all.each do |layout|
|
|
7
|
+
assert layout.valid?, layout.errors.full_messages.to_s
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_validations
|
|
12
|
+
layout = CmsLayout.create
|
|
13
|
+
assert layout.errors.present?
|
|
14
|
+
assert_has_errors_on layout, [:label, :slug, :content]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_validation_of_tag_presence
|
|
18
|
+
layout = CmsLayout.create(:content => 'some text')
|
|
19
|
+
assert_has_errors_on layout, :content
|
|
20
|
+
|
|
21
|
+
layout = CmsLayout.create(:content => '{cms:snippet:blah}')
|
|
22
|
+
assert_has_errors_on layout, :content
|
|
23
|
+
|
|
24
|
+
layout = cms_sites(:default).cms_layouts.new(
|
|
25
|
+
:label => 'test',
|
|
26
|
+
:slug => 'test',
|
|
27
|
+
:content => '{{cms:page:blah}}'
|
|
28
|
+
)
|
|
29
|
+
assert layout.valid?
|
|
30
|
+
|
|
31
|
+
layout = cms_sites(:default).cms_layouts.new(
|
|
32
|
+
:label => 'test',
|
|
33
|
+
:slug => 'test',
|
|
34
|
+
:content => '{{cms:field:blah}}'
|
|
35
|
+
)
|
|
36
|
+
assert layout.valid?
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def test_creation
|
|
40
|
+
assert_difference 'CmsLayout.count' do
|
|
41
|
+
layout = cms_sites(:default).cms_layouts.create(
|
|
42
|
+
:label => 'New Layout',
|
|
43
|
+
:slug => 'new-layout',
|
|
44
|
+
:content => '{{cms:page:content}}',
|
|
45
|
+
:css => 'css',
|
|
46
|
+
:js => 'js'
|
|
47
|
+
)
|
|
48
|
+
assert_equal 'New Layout', layout.label
|
|
49
|
+
assert_equal 'new-layout', layout.slug
|
|
50
|
+
assert_equal '{{cms:page:content}}', layout.content
|
|
51
|
+
assert_equal 'css', layout.css
|
|
52
|
+
assert_equal 'js', layout.js
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def test_options_for_select
|
|
57
|
+
assert_equal ['Default Layout', 'Nested Layout', '. . Child Layout'],
|
|
58
|
+
CmsLayout.options_for_select(cms_sites(:default)).collect{|t| t.first}
|
|
59
|
+
assert_equal ['Default Layout', 'Nested Layout'],
|
|
60
|
+
CmsLayout.options_for_select(cms_sites(:default), cms_layouts(:child)).collect{|t| t.first}
|
|
61
|
+
assert_equal ['Default Layout'],
|
|
62
|
+
CmsLayout.options_for_select(cms_sites(:default), cms_layouts(:nested)).collect{|t| t.first}
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_app_layouts_for_select
|
|
66
|
+
assert_equal ['cms_admin.html.erb'], CmsLayout.app_layouts_for_select
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def test_merged_content_with_same_child_content
|
|
70
|
+
parent_layout = cms_layouts(:nested)
|
|
71
|
+
assert_equal "{{cms:page:header}}\n{{cms:page:content}}", parent_layout.content
|
|
72
|
+
assert_equal "{{cms:page:header}}\n{{cms:page:content}}", parent_layout.merged_content
|
|
73
|
+
|
|
74
|
+
child_layout = cms_layouts(:child)
|
|
75
|
+
assert_equal parent_layout, child_layout.parent
|
|
76
|
+
assert_equal "{{cms:page:left_column}}\n{{cms:page:right_column}}", child_layout.content
|
|
77
|
+
assert_equal "{{cms:page:header}}\n{{cms:page:left_column}}\n{{cms:page:right_column}}", child_layout.merged_content
|
|
78
|
+
|
|
79
|
+
child_layout.update_attribute(:content, '{{cms:page:content}}')
|
|
80
|
+
assert_equal "{{cms:page:header}}\n{{cms:page:content}}", child_layout.merged_content
|
|
81
|
+
|
|
82
|
+
parent_layout.update_attribute(:content, '{{cms:page:whatever}}')
|
|
83
|
+
child_layout.reload
|
|
84
|
+
assert_equal '{{cms:page:content}}', child_layout.merged_content
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_load_from_file
|
|
88
|
+
assert !CmsLayout.load_from_file(cms_sites(:default), 'default')
|
|
89
|
+
|
|
90
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
91
|
+
|
|
92
|
+
assert !CmsLayout.load_from_file(cms_sites(:default), 'bogus')
|
|
93
|
+
|
|
94
|
+
assert layout = CmsLayout.load_from_file(cms_sites(:default), 'default')
|
|
95
|
+
assert_equal 'Default Layout', layout.label
|
|
96
|
+
assert_equal '<html>{{cms:page:content}}</html>', layout.content
|
|
97
|
+
|
|
98
|
+
assert layout = CmsLayout.load_from_file(cms_sites(:default), 'nested')
|
|
99
|
+
assert_equal 'Nested Layout', layout.label
|
|
100
|
+
assert_equal '<div>{{cms:page:content}}</div>', layout.content
|
|
101
|
+
assert_equal '<html><div>{{cms:page:content}}</div></html>', layout.merged_content
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def test_load_from_file_broken
|
|
105
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
106
|
+
error_message = "Failed to load from #{LucyCMS.configuration.seed_data_path}/test.host/layouts/broken.yml"
|
|
107
|
+
assert_exception_raised RuntimeError, error_message do
|
|
108
|
+
CmsLayout.load_from_file(cms_sites(:default), 'broken')
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def test_load_for_slug
|
|
113
|
+
assert layout = CmsLayout.load_for_slug!(cms_sites(:default), 'default')
|
|
114
|
+
assert !layout.new_record?
|
|
115
|
+
db_content = layout.content
|
|
116
|
+
|
|
117
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
118
|
+
assert layout = CmsLayout.load_for_slug!(cms_sites(:default), 'default')
|
|
119
|
+
assert layout.new_record?
|
|
120
|
+
file_content = layout.content
|
|
121
|
+
assert_not_equal db_content, file_content
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def test_load_for_slug_exceptions
|
|
125
|
+
assert_exception_raised ActiveRecord::RecordNotFound, 'CmsLayout with slug: not_found cannot be found' do
|
|
126
|
+
CmsLayout.load_for_slug!(cms_sites(:default), 'not_found')
|
|
127
|
+
end
|
|
128
|
+
assert !CmsLayout.load_for_slug(cms_sites(:default), 'not_found')
|
|
129
|
+
|
|
130
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
131
|
+
assert_exception_raised ActiveRecord::RecordNotFound, 'CmsLayout with slug: not_found cannot be found' do
|
|
132
|
+
CmsLayout.load_for_slug!(cms_sites(:default), 'not_found')
|
|
133
|
+
end
|
|
134
|
+
assert !CmsLayout.load_for_slug(cms_sites(:default), 'not_found')
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_update_forces_page_content_reload
|
|
138
|
+
layout = cms_layouts(:default)
|
|
139
|
+
page = cms_pages(:default)
|
|
140
|
+
assert_equal layout, page.cms_layout
|
|
141
|
+
layout.update_attribute(:content, 'updated {{cms:page:default_page_text:text}} updated')
|
|
142
|
+
page.reload
|
|
143
|
+
assert_equal "updated default_page_text_content_a\ndefault_snippet_content\ndefault_page_text_content_b updated", page.content
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
end
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
class CmsPageTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
def test_fixtures_validity
|
|
6
|
+
CmsPage.all.each do |page|
|
|
7
|
+
assert page.valid?, page.errors.full_messages.to_s
|
|
8
|
+
assert_equal page.read_attribute(:content), page.content(true)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_validations
|
|
13
|
+
page = CmsPage.new
|
|
14
|
+
page.save
|
|
15
|
+
assert page.invalid?
|
|
16
|
+
assert_has_errors_on page, [:cms_layout, :slug, :label]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_validation_of_parent_presence
|
|
20
|
+
page = cms_sites(:default).cms_pages.new(new_params)
|
|
21
|
+
assert !page.parent
|
|
22
|
+
assert page.valid?, page.errors.full_messages.to_s
|
|
23
|
+
assert_equal cms_pages(:default), page.parent
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_validation_of_parent_relationship
|
|
27
|
+
page = cms_pages(:default)
|
|
28
|
+
assert !page.parent
|
|
29
|
+
page.parent = page
|
|
30
|
+
assert page.invalid?
|
|
31
|
+
assert_has_errors_on page, :parent_id
|
|
32
|
+
page.parent = cms_pages(:child)
|
|
33
|
+
assert page.invalid?
|
|
34
|
+
assert_has_errors_on page, :parent_id
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def test_validation_of_target_page
|
|
38
|
+
page = cms_pages(:child)
|
|
39
|
+
page.target_page = cms_pages(:default)
|
|
40
|
+
page.save!
|
|
41
|
+
assert_equal cms_pages(:default), page.target_page
|
|
42
|
+
page.target_page = page
|
|
43
|
+
assert page.invalid?
|
|
44
|
+
assert_has_errors_on page, :target_page_id
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_creation
|
|
48
|
+
assert_difference ['CmsPage.count', 'CmsBlock.count'] do
|
|
49
|
+
page = cms_sites(:default).cms_pages.create!(
|
|
50
|
+
:label => 'test',
|
|
51
|
+
:slug => 'test',
|
|
52
|
+
:parent_id => cms_pages(:default).id,
|
|
53
|
+
:cms_layout_id => cms_layouts(:default).id,
|
|
54
|
+
:cms_blocks_attributes => [
|
|
55
|
+
{ :label => 'test',
|
|
56
|
+
:content => 'test' }
|
|
57
|
+
]
|
|
58
|
+
)
|
|
59
|
+
assert page.is_published?
|
|
60
|
+
assert_equal 1, page.position
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_initialization_of_full_path
|
|
65
|
+
page = CmsPage.new
|
|
66
|
+
assert_equal '/', page.full_path
|
|
67
|
+
|
|
68
|
+
page = CmsPage.new(new_params)
|
|
69
|
+
assert page.invalid?
|
|
70
|
+
assert_has_errors_on page, :cms_site_id
|
|
71
|
+
|
|
72
|
+
page = cms_sites(:default).cms_pages.new(new_params(:parent => cms_pages(:default)))
|
|
73
|
+
assert page.valid?
|
|
74
|
+
assert_equal '/test-page', page.full_path
|
|
75
|
+
|
|
76
|
+
page = cms_sites(:default).cms_pages.new(new_params(:parent => cms_pages(:child)))
|
|
77
|
+
assert page.valid?
|
|
78
|
+
assert_equal '/child-page/test-page', page.full_path
|
|
79
|
+
|
|
80
|
+
CmsPage.destroy_all
|
|
81
|
+
page = cms_sites(:default).cms_pages.new(new_params)
|
|
82
|
+
assert page.valid?
|
|
83
|
+
assert_equal '/', page.full_path
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_sync_child_pages
|
|
87
|
+
page = cms_pages(:child)
|
|
88
|
+
page_1 = cms_sites(:default).cms_pages.create!(new_params(:parent => page, :slug => 'test-page-1'))
|
|
89
|
+
page_2 = cms_sites(:default).cms_pages.create!(new_params(:parent => page, :slug => 'test-page-2'))
|
|
90
|
+
page_3 = cms_sites(:default).cms_pages.create!(new_params(:parent => page_2, :slug => 'test-page-3'))
|
|
91
|
+
page_4 = cms_sites(:default).cms_pages.create!(new_params(:parent => page_1, :slug => 'test-page-4'))
|
|
92
|
+
assert_equal '/child-page/test-page-1', page_1.full_path
|
|
93
|
+
assert_equal '/child-page/test-page-2', page_2.full_path
|
|
94
|
+
assert_equal '/child-page/test-page-2/test-page-3', page_3.full_path
|
|
95
|
+
assert_equal '/child-page/test-page-1/test-page-4', page_4.full_path
|
|
96
|
+
|
|
97
|
+
page.update_attributes!(:slug => 'updated-page')
|
|
98
|
+
assert_equal '/updated-page', page.full_path
|
|
99
|
+
page_1.reload; page_2.reload; page_3.reload; page_4.reload
|
|
100
|
+
assert_equal '/updated-page/test-page-1', page_1.full_path
|
|
101
|
+
assert_equal '/updated-page/test-page-2', page_2.full_path
|
|
102
|
+
assert_equal '/updated-page/test-page-2/test-page-3', page_3.full_path
|
|
103
|
+
assert_equal '/updated-page/test-page-1/test-page-4', page_4.full_path
|
|
104
|
+
|
|
105
|
+
page_2.update_attributes!(:parent => page_1)
|
|
106
|
+
page_1.reload; page_2.reload; page_3.reload; page_4.reload
|
|
107
|
+
assert_equal '/updated-page/test-page-1', page_1.full_path
|
|
108
|
+
assert_equal '/updated-page/test-page-1/test-page-2', page_2.full_path
|
|
109
|
+
assert_equal '/updated-page/test-page-1/test-page-2/test-page-3', page_3.full_path
|
|
110
|
+
assert_equal '/updated-page/test-page-1/test-page-4', page_4.full_path
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def test_children_count_updating
|
|
114
|
+
page_1 = cms_pages(:default)
|
|
115
|
+
page_2 = cms_pages(:child)
|
|
116
|
+
assert_equal 1, page_1.children_count
|
|
117
|
+
assert_equal 0, page_2.children_count
|
|
118
|
+
|
|
119
|
+
page_3 = cms_sites(:default).cms_pages.create!(new_params(:parent => page_2))
|
|
120
|
+
page_1.reload; page_2.reload
|
|
121
|
+
assert_equal 1, page_1.children_count
|
|
122
|
+
assert_equal 1, page_2.children_count
|
|
123
|
+
assert_equal 0, page_3.children_count
|
|
124
|
+
|
|
125
|
+
page_3.update_attributes!(:parent => page_1)
|
|
126
|
+
page_1.reload; page_2.reload
|
|
127
|
+
assert_equal 2, page_1.children_count
|
|
128
|
+
assert_equal 0, page_2.children_count
|
|
129
|
+
|
|
130
|
+
page_3.destroy
|
|
131
|
+
page_1.reload; page_2.reload
|
|
132
|
+
assert_equal 1, page_1.children_count
|
|
133
|
+
assert_equal 0, page_2.children_count
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def test_cascading_destroy
|
|
137
|
+
assert_difference 'CmsPage.count', -2 do
|
|
138
|
+
cms_pages(:default).destroy
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def test_options_for_select
|
|
143
|
+
assert_equal ['Default Page', '. . Child Page'],
|
|
144
|
+
CmsPage.options_for_select(cms_sites(:default)).collect{|t| t.first }
|
|
145
|
+
assert_equal ['Default Page'],
|
|
146
|
+
CmsPage.options_for_select(cms_sites(:default), cms_pages(:child)).collect{|t| t.first }
|
|
147
|
+
assert_equal [],
|
|
148
|
+
CmsPage.options_for_select(cms_sites(:default), cms_pages(:default))
|
|
149
|
+
|
|
150
|
+
page = CmsPage.new(new_params(:parent => cms_pages(:default)))
|
|
151
|
+
assert_equal ['Default Page', '. . Child Page'],
|
|
152
|
+
CmsPage.options_for_select(cms_sites(:default), page).collect{|t| t.first }
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_load_from_file
|
|
156
|
+
assert !CmsPage.load_from_file(cms_sites(:default), '/')
|
|
157
|
+
|
|
158
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
159
|
+
|
|
160
|
+
assert !CmsPage.load_from_file(cms_sites(:default), '/bogus')
|
|
161
|
+
|
|
162
|
+
assert page = CmsPage.load_from_file(cms_sites(:default), '/')
|
|
163
|
+
assert_equal 'Default Page', page.label
|
|
164
|
+
assert_equal 1, page.cms_blocks.size
|
|
165
|
+
assert page.cms_layout
|
|
166
|
+
assert_equal '<html>Default Page Content</html>', page.content
|
|
167
|
+
|
|
168
|
+
assert page = CmsPage.load_from_file(cms_sites(:default), '/child')
|
|
169
|
+
assert_equal 1, page.cms_blocks.size
|
|
170
|
+
assert page.cms_layout
|
|
171
|
+
assert_equal '<html>Child Page Content</html>', page.content
|
|
172
|
+
|
|
173
|
+
assert page = CmsPage.load_from_file(cms_sites(:default), '/child/subchild')
|
|
174
|
+
assert_equal 1, page.cms_blocks.size
|
|
175
|
+
assert page.cms_layout
|
|
176
|
+
assert_equal 'Nested Layout', page.cms_layout.label
|
|
177
|
+
assert_equal '<html><div>Sub Child Page Content Content for Default Snippet</div></html>', page.content
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def test_load_from_file_broken
|
|
181
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
182
|
+
error_message = "Failed to load from #{LucyCMS.configuration.seed_data_path}/test.host/pages/broken.yml"
|
|
183
|
+
assert_exception_raised RuntimeError, error_message do
|
|
184
|
+
CmsPage.load_from_file(cms_sites(:default), '/broken')
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def test_load_for_full_path
|
|
189
|
+
assert page = CmsPage.load_for_full_path!(cms_sites(:default), '/')
|
|
190
|
+
assert !page.new_record?
|
|
191
|
+
db_content = page.content
|
|
192
|
+
|
|
193
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
194
|
+
assert page = CmsPage.load_for_full_path!(cms_sites(:default), '/')
|
|
195
|
+
assert page.new_record?
|
|
196
|
+
file_content = page.content
|
|
197
|
+
assert_not_equal db_content, file_content
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_load_for_full_path_exceptions
|
|
201
|
+
assert_exception_raised ActiveRecord::RecordNotFound, 'CmsPage with path: /invalid_page cannot be found' do
|
|
202
|
+
CmsPage.load_for_full_path!(cms_sites(:default), '/invalid_page')
|
|
203
|
+
end
|
|
204
|
+
assert !CmsPage.load_for_full_path(cms_sites(:default), '/invalid_page')
|
|
205
|
+
|
|
206
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
207
|
+
assert_exception_raised ActiveRecord::RecordNotFound, 'CmsPage with path: /invalid_page cannot be found' do
|
|
208
|
+
CmsPage.load_for_full_path!(cms_sites(:default), '/invalid_page')
|
|
209
|
+
end
|
|
210
|
+
assert !CmsPage.load_for_full_path(cms_sites(:default), '/invalid_page')
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def test_cms_blocks_attributes_accessor
|
|
214
|
+
page = cms_pages(:default)
|
|
215
|
+
assert_equal page.cms_blocks.count, page.cms_blocks_attributes.size
|
|
216
|
+
assert_equal 'default_field_text', page.cms_blocks_attributes.first[:label]
|
|
217
|
+
assert_equal 'default_field_text_content', page.cms_blocks_attributes.first[:content]
|
|
218
|
+
assert page.cms_blocks_attributes.first[:id]
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def test_content_caching
|
|
222
|
+
page = cms_pages(:default)
|
|
223
|
+
assert_equal page.read_attribute(:content), page.content
|
|
224
|
+
assert_equal page.read_attribute(:content), page.content(true)
|
|
225
|
+
|
|
226
|
+
page.update_attribute(:content, 'changed')
|
|
227
|
+
assert_equal page.read_attribute(:content), page.content
|
|
228
|
+
assert_equal page.read_attribute(:content), page.content(true)
|
|
229
|
+
assert_not_equal 'changed', page.read_attribute(:content)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def test_scope_published
|
|
233
|
+
assert_equal 2, CmsPage.published.count
|
|
234
|
+
cms_pages(:child).update_attribute(:is_published, false)
|
|
235
|
+
assert_equal 1, CmsPage.published.count
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def test_root?
|
|
239
|
+
assert cms_pages(:default).root?
|
|
240
|
+
assert !cms_pages(:child).root?
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
def test_url
|
|
244
|
+
assert_equal 'http://test.host/', cms_pages(:default).url
|
|
245
|
+
assert_equal 'http://test.host/child-page', cms_pages(:child).url
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
protected
|
|
249
|
+
|
|
250
|
+
def new_params(options = {})
|
|
251
|
+
{
|
|
252
|
+
:label => 'Test Page',
|
|
253
|
+
:slug => 'test-page',
|
|
254
|
+
:cms_layout => cms_layouts(:default)
|
|
255
|
+
}.merge(options)
|
|
256
|
+
end
|
|
257
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
class CmsSiteTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
def test_fixtures_validity
|
|
6
|
+
CmsSite.all.each do |site|
|
|
7
|
+
assert site.valid?, site.errors.full_messages.to_s
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_validation
|
|
12
|
+
site = CmsSite.new
|
|
13
|
+
assert site.invalid?
|
|
14
|
+
assert_has_errors_on site, [:label, :hostname]
|
|
15
|
+
|
|
16
|
+
site = CmsSite.new(:label => 'My Site', :hostname => 'http://mysite.com')
|
|
17
|
+
assert site.invalid?
|
|
18
|
+
assert_has_errors_on site, :hostname
|
|
19
|
+
|
|
20
|
+
site = CmsSite.new(:label => 'My Site', :hostname => 'mysite.com')
|
|
21
|
+
assert site.valid?
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def test_cascading_destroy
|
|
25
|
+
assert_difference 'CmsSite.count', -1 do
|
|
26
|
+
assert_difference 'CmsLayout.count', -3 do
|
|
27
|
+
assert_difference 'CmsPage.count', -2 do
|
|
28
|
+
assert_difference 'CmsSnippet.count', -1 do
|
|
29
|
+
cms_sites(:default).destroy
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_options_for_select
|
|
37
|
+
assert_equal 1, CmsSite.options_for_select.size
|
|
38
|
+
assert_equal 'Default Site (test.host)', CmsSite.options_for_select[0][0]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
require File.expand_path('../test_helper', File.dirname(__FILE__))
|
|
2
|
+
|
|
3
|
+
class CmsSnippetTest < ActiveSupport::TestCase
|
|
4
|
+
|
|
5
|
+
def test_fixtures_validity
|
|
6
|
+
CmsSnippet.all.each do |snippet|
|
|
7
|
+
assert snippet.valid?, snippet.errors.full_messages.to_s
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_validations
|
|
12
|
+
snippet = CmsSnippet.new
|
|
13
|
+
snippet.save
|
|
14
|
+
assert snippet.invalid?
|
|
15
|
+
assert_has_errors_on snippet, [:label, :slug]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def test_method_content
|
|
19
|
+
assert_equal cms_snippets(:default).content, CmsSnippet.content_for('default')
|
|
20
|
+
assert_equal '', CmsSnippet.content_for('nonexistent_snippet')
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_load_from_file
|
|
24
|
+
assert !CmsSnippet.load_from_file(cms_sites(:default), 'default')
|
|
25
|
+
|
|
26
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
27
|
+
|
|
28
|
+
assert !CmsSnippet.load_from_file(cms_sites(:default), 'bogus')
|
|
29
|
+
|
|
30
|
+
assert snippet = CmsSnippet.load_from_file(cms_sites(:default), 'default')
|
|
31
|
+
assert_equal 'Default Snippet', snippet.label
|
|
32
|
+
assert_equal 'Content for Default Snippet', snippet.content
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_load_from_file_broken
|
|
36
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
37
|
+
error_message = "Failed to load from #{LucyCMS.configuration.seed_data_path}/test.host/snippets/broken.yml"
|
|
38
|
+
assert_exception_raised RuntimeError, error_message do
|
|
39
|
+
CmsSnippet.load_from_file(cms_sites(:default), 'broken')
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def test_load_for_slug
|
|
44
|
+
assert snippet = CmsSnippet.load_for_slug!(cms_sites(:default), 'default')
|
|
45
|
+
assert !snippet.new_record?
|
|
46
|
+
db_content = snippet.content
|
|
47
|
+
|
|
48
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
49
|
+
assert snippet = CmsSnippet.load_for_slug!(cms_sites(:default), 'default')
|
|
50
|
+
assert snippet.new_record?
|
|
51
|
+
file_content = snippet.content
|
|
52
|
+
assert_not_equal db_content, file_content
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def test_load_for_slug_exceptions
|
|
56
|
+
assert_exception_raised ActiveRecord::RecordNotFound, 'CmsSnippet with slug: not_found cannot be found' do
|
|
57
|
+
CmsSnippet.load_for_slug!(cms_sites(:default), 'not_found')
|
|
58
|
+
end
|
|
59
|
+
assert !CmsSnippet.load_for_slug(cms_sites(:default), 'not_found')
|
|
60
|
+
|
|
61
|
+
LucyCMS.configuration.seed_data_path = File.expand_path('../cms_seeds', File.dirname(__FILE__))
|
|
62
|
+
assert_exception_raised ActiveRecord::RecordNotFound, 'CmsSnippet with slug: not_found cannot be found' do
|
|
63
|
+
CmsSnippet.load_for_slug!(cms_sites(:default), 'not_found')
|
|
64
|
+
end
|
|
65
|
+
assert !CmsSnippet.load_for_slug(cms_sites(:default), 'not_found')
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def test_update_forces_page_content_reload
|
|
69
|
+
snippet = cms_snippets(:default)
|
|
70
|
+
page = cms_pages(:default)
|
|
71
|
+
assert_match snippet.content, page.content
|
|
72
|
+
snippet.update_attribute(:content, 'new_snippet_content')
|
|
73
|
+
page.reload
|
|
74
|
+
assert_match /new_snippet_content/, page.content
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
end
|