spontaneous 0.2.0.alpha2 → 0.2.0.alpha3
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 +3 -40
- data/Rakefile +29 -41
- data/Readme.markdown +21 -8
- data/application/css/add_alias_dialogue.css.scss +79 -0
- data/application/css/{v2.scss → core.css.scss} +537 -550
- data/application/css/{definitions.scss → definitions.css.scss} +121 -33
- data/application/css/dialogue.css.scss +409 -0
- data/application/css/{editing.scss → editing.css.scss} +25 -262
- data/application/css/font.css.scss +8 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_222222_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_228ef1_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ef8c08_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffd27a_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/images/ui-icons_ffffff_256x240.png +0 -0
- data/application/css/jquery-ui-1.8.21.custom/ui-lightness.css.scss +565 -0
- data/application/css/{login.scss → login.css.scss} +4 -4
- data/application/css/meta.css.scss +331 -0
- data/application/css/{popover.scss → popover.css.scss} +9 -8
- data/application/css/{schema_error.scss → schema_error.css.scss} +4 -4
- data/application/css/spontaneous.css +5 -0
- data/application/css/unsupported.css.scss +42 -0
- data/application/js/add_alias_dialogue.js +72 -10
- data/application/js/ajax.js +50 -16
- data/application/js/compatibility.js +19 -15
- data/application/js/content.js +39 -36
- data/application/js/content_area.js +53 -5
- data/application/js/dialogue.js +17 -0
- data/application/js/dom.js +1 -1
- data/application/js/edit_panel.js +23 -8
- data/application/js/extensions.js +7 -2
- data/application/js/field_preview.js +2 -1
- data/application/js/field_types/date_field.js +11 -8
- data/application/js/field_types/file_field.js +188 -9
- data/application/js/field_types/image_field.js +46 -29
- data/application/js/field_types/markdown_field.js +57 -14
- data/application/js/field_types/select_field.js +72 -0
- data/application/js/field_types/string_field.js +8 -0
- data/application/js/field_types/webvideo_field.js +8 -0
- data/application/js/init.js +1 -7
- data/application/js/location.js +41 -13
- data/application/js/login.js +3 -0
- data/application/js/meta_view/user_admin.js +543 -0
- data/application/js/meta_view.js +1 -0
- data/application/js/metadata.js +20 -0
- data/application/js/page.js +17 -3
- data/application/js/page_browser.js +40 -30
- data/application/js/page_entry.js +4 -0
- data/application/js/panel/root_menu.js +66 -0
- data/application/js/popover.js +2 -2
- data/application/js/preview.js +1 -1
- data/application/js/publish.js +138 -30
- data/application/js/services.js +43 -0
- data/application/js/sharded_upload.js +2 -2
- data/application/js/spontaneous.js +64 -5
- data/application/js/state.js +20 -9
- data/application/js/top_bar.js +273 -150
- data/application/js/types.js +20 -15
- data/application/js/upload.js +1 -2
- data/application/js/user.js +18 -4
- data/application/js/vendor/date.js +104 -0
- data/application/js/vendor/jquery-ui-1.8.18.custom.min.js +356 -0
- data/application/js/views/box_view.js +15 -8
- data/application/js/views/page_piece_view.js +11 -8
- data/application/js/views/page_view.js +21 -3
- data/application/js/views/piece_view.js +19 -10
- data/application/js/views.js +3 -0
- data/application/static/chromelogo-200x52-45c7cbc93be080bea342df5fcda2ef8b.png +0 -0
- data/application/static/dot-texture-9eea29e4ac7ad9a772285252078ec127.png +0 -0
- data/application/static/editing-textarea-resize-s-b5af62365eb7e19ea4beccf7242d508e.png +0 -0
- data/application/static/editing-texture-1-42b06a3439752490988f30f2a06d5e7c.png +0 -0
- data/application/static/font/fontawesome-webfont-5c5c21100a346972a82c34c5e96ffcfe.ttf +0 -0
- data/application/static/loop_alt1-white-7894b458528e92216196cae26b4c2c96.svg +12 -0
- data/application/static/spontaneous-states-e91ec89db525c62da0105b97cdd781ce.png +0 -0
- data/application/views/index.erb +2 -2
- data/application/views/login.erb +4 -8
- data/application/views/schema_modification_error.html.erb +1 -4
- data/application/views/unsupported.erb +9 -7
- data/bin/spot +1 -1
- data/db/migrations/20110209152710_users_and_groups.rb +10 -10
- data/db/migrations/20120305112647_site_modification_time.rb +11 -0
- data/db/migrations/20120418153903_add_ownership_of_content.rb +14 -0
- data/db/migrations/20120423175416_add_pending_modifications.rb +21 -0
- data/db/migrations/20120525164947_add_field_versions.rb +27 -0
- data/lib/sequel/plugins/scoped_table_name.rb +10 -1
- data/lib/spontaneous/asset/file.rb +25 -0
- data/lib/spontaneous/asset/source.rb +28 -0
- data/lib/spontaneous/asset.rb +75 -0
- data/lib/spontaneous/box.rb +6 -4
- data/lib/spontaneous/capistrano/deploy.rb +47 -0
- data/lib/spontaneous/capistrano/sync.rb +81 -0
- data/lib/spontaneous/capistrano.rb +13 -0
- data/lib/spontaneous/change.rb +60 -68
- data/lib/spontaneous/cli/assets.rb +29 -0
- data/lib/spontaneous/cli/base.rb +0 -48
- data/lib/spontaneous/cli/console.rb +1 -1
- data/lib/spontaneous/cli/server.rb +6 -4
- data/lib/spontaneous/cli/site.rb +28 -17
- data/lib/spontaneous/cli/user.rb +107 -0
- data/lib/spontaneous/cli.rb +100 -4
- data/lib/spontaneous/collections/entry_set.rb +2 -2
- data/lib/spontaneous/collections/field_set.rb +48 -22
- data/lib/spontaneous/collections/prototype_set.rb +20 -13
- data/lib/spontaneous/constants.rb +3 -0
- data/lib/spontaneous/content.rb +22 -5
- data/lib/spontaneous/errors.rb +3 -3
- data/lib/spontaneous/extensions/array.rb +12 -0
- data/lib/spontaneous/extensions/enumerable.rb +30 -0
- data/lib/spontaneous/extensions/nil.rb +3 -1
- data/lib/spontaneous/extensions/string.rb +16 -0
- data/lib/spontaneous/field_types/date_field.rb +45 -2
- data/lib/spontaneous/field_types/field.rb +42 -9
- data/lib/spontaneous/field_types/file_field.rb +68 -0
- data/lib/spontaneous/field_types/image_field.rb +63 -0
- data/lib/spontaneous/field_types/select_field.rb +109 -0
- data/lib/spontaneous/field_types/string_field.rb +6 -1
- data/lib/spontaneous/field_types/webvideo_field.rb +85 -27
- data/lib/spontaneous/field_types.rb +1 -1
- data/lib/spontaneous/field_version.rb +8 -0
- data/lib/spontaneous/generators/page.rb +1 -1
- data/lib/spontaneous/generators/site/Capfile.tt +1 -4
- data/lib/spontaneous/generators/site/Gemfile.tt +13 -6
- data/lib/spontaneous/generators/site/config/deploy.rb.tt +28 -0
- data/lib/spontaneous/generators/site/config/environments/production.rb.tt +7 -2
- data/lib/spontaneous/generators/site.rb +1 -0
- data/lib/spontaneous/json.rb +34 -11
- data/lib/spontaneous/layout.rb +22 -0
- data/lib/spontaneous/media/file.rb +4 -0
- data/lib/spontaneous/output/assets/compression.rb +58 -0
- data/lib/spontaneous/output/assets.rb +32 -0
- data/lib/spontaneous/output/context.rb +179 -0
- data/lib/spontaneous/output/format/html.rb +5 -0
- data/lib/spontaneous/output/format/plain.rb +5 -0
- data/lib/spontaneous/output/format.rb +180 -0
- data/lib/spontaneous/output/helpers/classes_helper.rb +18 -0
- data/lib/spontaneous/{render/helpers/html_helper.rb → output/helpers/conditional_comment_helper.rb} +3 -12
- data/lib/spontaneous/output/helpers/script_helper.rb +73 -0
- data/lib/spontaneous/output/helpers/stylesheet_helper.rb +61 -0
- data/lib/spontaneous/output/helpers.rb +28 -0
- data/lib/spontaneous/output/template/engine.rb +59 -0
- data/lib/spontaneous/output/template/renderer.rb +153 -0
- data/lib/spontaneous/output/template.rb +21 -0
- data/lib/spontaneous/output.rb +163 -0
- data/lib/spontaneous/page.rb +2 -1
- data/lib/spontaneous/paths.rb +6 -1
- data/lib/spontaneous/permissions/access_key.rb +5 -5
- data/lib/spontaneous/permissions/user.rb +81 -35
- data/lib/spontaneous/permissions/user_level.rb +26 -22
- data/lib/spontaneous/plugins/aliases.rb +76 -12
- data/lib/spontaneous/plugins/allowed_types.rb +60 -18
- data/lib/spontaneous/plugins/application/paths.rb +0 -28
- data/lib/spontaneous/plugins/application/system.rb +35 -0
- data/lib/spontaneous/plugins/boxes.rb +4 -0
- data/lib/spontaneous/plugins/content_groups.rb +16 -0
- data/lib/spontaneous/plugins/entries.rb +50 -30
- data/lib/spontaneous/plugins/fields.rb +15 -0
- data/lib/spontaneous/plugins/layouts.rb +8 -2
- data/lib/spontaneous/plugins/modifications.rb +228 -0
- data/lib/spontaneous/plugins/page/formats.rb +67 -42
- data/lib/spontaneous/plugins/page/request.rb +10 -0
- data/lib/spontaneous/plugins/page/site_timestamps.rb +28 -0
- data/lib/spontaneous/plugins/paths.rb +15 -3
- data/lib/spontaneous/plugins/publishing.rb +124 -45
- data/lib/spontaneous/plugins/render.rb +13 -8
- data/lib/spontaneous/plugins/schema_hierarchy.rb +18 -6
- data/lib/spontaneous/plugins/site/helpers.rb +53 -0
- data/lib/spontaneous/plugins/site/hooks.rb +50 -0
- data/lib/spontaneous/plugins/site/map.rb +1 -1
- data/lib/spontaneous/plugins/site/paths.rb +13 -0
- data/lib/spontaneous/plugins/site/publishing.rb +6 -2
- data/lib/spontaneous/plugins/site/{revisions.rb → state.rb} +5 -1
- data/lib/spontaneous/plugins/site/storage.rb +4 -0
- data/lib/spontaneous/plugins/site/url.rb +15 -0
- data/lib/spontaneous/plugins/site_map.rb +13 -3
- data/lib/spontaneous/plugins/styles.rb +5 -1
- data/lib/spontaneous/plugins/visibility.rb +39 -12
- data/lib/spontaneous/prototypes/box_prototype.rb +4 -0
- data/lib/spontaneous/prototypes/field_prototype.rb +15 -10
- data/lib/spontaneous/publishing/event_client.rb +46 -0
- data/lib/spontaneous/publishing/immediate.rb +81 -44
- data/lib/spontaneous/publishing/simultaneous.rb +23 -6
- data/lib/spontaneous/publishing.rb +4 -3
- data/lib/spontaneous/rack/around_back.rb +1 -5
- data/lib/spontaneous/rack/around_front.rb +4 -4
- data/lib/spontaneous/rack/around_preview.rb +4 -3
- data/lib/spontaneous/rack/assets.rb +81 -54
- data/lib/spontaneous/rack/authentication.rb +0 -1
- data/lib/spontaneous/rack/back.rb +160 -72
- data/lib/spontaneous/rack/cookie_authentication.rb +2 -2
- data/lib/spontaneous/rack/css.rb +18 -15
- data/lib/spontaneous/rack/event_source.rb +9 -21
- data/lib/spontaneous/rack/fiber_pool.rb +26 -0
- data/lib/spontaneous/rack/front.rb +12 -4
- data/lib/spontaneous/rack/helpers.rb +35 -13
- data/lib/spontaneous/rack/js.rb +41 -0
- data/lib/spontaneous/rack/public.rb +34 -44
- data/lib/spontaneous/rack/sse.rb +18 -0
- data/lib/spontaneous/rack/static.rb +3 -0
- data/lib/spontaneous/rack/user_admin.rb +100 -0
- data/lib/spontaneous/rack/user_helpers.rb +1 -1
- data/lib/spontaneous/rack.rb +6 -2
- data/lib/spontaneous/schema.rb +31 -4
- data/lib/spontaneous/search/index.rb +19 -3
- data/lib/spontaneous/search/results.rb +1 -1
- data/lib/spontaneous/sequel.rb +17 -0
- data/lib/spontaneous/site.rb +11 -4
- data/lib/spontaneous/state.rb +11 -0
- data/lib/spontaneous/storage/cloud.rb +4 -0
- data/lib/spontaneous/storage/local.rb +11 -0
- data/lib/spontaneous/style.rb +2 -2
- data/lib/spontaneous/tasks/database.rake +21 -22
- data/lib/spontaneous/utils/database/mysql_dumper.rb +4 -0
- data/lib/spontaneous/utils/database/postgres_dumper.rb +78 -0
- data/lib/spontaneous/utils/database.rb +6 -3
- data/lib/spontaneous/utils/smart_quotes.rb +499 -0
- data/lib/spontaneous/utils/smush_it.rb +66 -0
- data/lib/spontaneous/utils.rb +3 -1
- data/lib/spontaneous/version.rb +2 -2
- data/lib/spontaneous.rb +25 -29
- data/spontaneous.gemspec +186 -106
- data/test/experimental/test_features.rb +1 -1
- data/test/fixtures/asset_pipeline/application/css/basic.css.scss +4 -0
- data/test/fixtures/asset_pipeline/application/css/complex.css.scss.erb +6 -0
- data/test/fixtures/asset_pipeline/application/css/simple.css +3 -0
- data/test/fixtures/asset_pipeline/application/css/spontaneous.css +7 -0
- data/test/fixtures/asset_pipeline/application/css/subdir/complex.css.scss.erb +6 -0
- data/test/fixtures/asset_pipeline/application/css/subdir/library.css.scss +1 -0
- data/test/fixtures/asset_pipeline/application/css/subdir/simple.css +3 -0
- data/test/fixtures/asset_pipeline/application/js/basic.js.coffee +1 -0
- data/test/fixtures/asset_pipeline/application/js/complex.js.coffee.erb +1 -0
- data/test/fixtures/asset_pipeline/application/js/login.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/require.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/simple.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/spontaneous.js +5 -0
- data/test/fixtures/asset_pipeline/application/js/subdir/complex.js.coffee.erb +1 -0
- data/test/fixtures/asset_pipeline/application/js/subdir/library.js.coffee +1 -0
- data/test/fixtures/asset_pipeline/application/js/subdir/simple.js +1 -0
- data/test/fixtures/asset_pipeline/application/js/vendor/jquery.js +1 -0
- data/test/fixtures/asset_pipeline/application/static/dot-texture.png +0 -0
- data/test/fixtures/asset_pipeline/application/static/subdir/px.gif +0 -0
- data/test/fixtures/assets/public1/css/a.scss +1 -0
- data/test/fixtures/assets/public1/js/a.js +1 -0
- data/test/fixtures/assets/public1/js/m.coffee +1 -0
- data/test/fixtures/assets/public2/css/b.scss +1 -0
- data/test/fixtures/assets/public2/css/c.css +1 -0
- data/test/fixtures/assets/public2/js/b.js +1 -0
- data/test/fixtures/assets/public2/js/c.js +1 -0
- data/test/fixtures/assets/public2/js/n.coffee +1 -0
- data/test/fixtures/back/config/user_levels.yml +3 -0
- data/test/fixtures/back/public/js/coffeescript.coffee +1 -0
- data/test/fixtures/back/templates/layouts/standard.css.cut +1 -0
- data/test/fixtures/back/templates/layouts/standard.js.cut +1 -0
- data/test/fixtures/example_application/config/database.yml +4 -4
- data/test/fixtures/helpers/templates/layouts/standard.html.cut +1 -0
- data/test/fixtures/helpers/templates/layouts/standard.mobile.cut +1 -0
- data/test/fixtures/images/vimlogo.pdf +0 -0
- data/test/fixtures/outputs/templates/layouts/standard.atom.cut +1 -0
- data/test/fixtures/permissions/config/user_levels.yml +6 -3
- data/test/fixtures/serialisation/class_hash.yaml.erb +1 -0
- data/test/fixtures/serialisation/root_hash.yaml.erb +2 -2
- data/test/fixtures/templates/extended/grandparent.html.cut +7 -7
- data/test/fixtures/templates/extended/main.html.cut +5 -5
- data/test/fixtures/templates/extended/parent.html.cut +8 -8
- data/test/fixtures/templates/extended/partial_with_locals.html.cut +1 -1
- data/test/fixtures/templates/extended/with_includes.html.cut +6 -6
- data/test/fixtures/templates/extended/with_includes_and_locals.html.cut +6 -7
- data/test/fixtures/templates/layouts/entries.html.cut +4 -4
- data/test/fixtures/templates/layouts/standard.html.cut +1 -0
- data/test/fixtures/templates/layouts/variables.html.cut +1 -1
- data/test/fixtures/templates/publishing/templates/layouts/static.html.cut +1 -1
- data/test/fixtures/templates/publishing/templates/layouts/static.rtf.cut +1 -0
- data/test/fixtures/templates/template_class/complex_template.html.cut +2 -2
- data/test/fixtures/templates/template_class/complex_template.pdf.cut +2 -2
- data/test/fixtures/templates/template_class/default_template_style.html.cut +1 -1
- data/test/fixtures/templates/template_class/images_with_template.html.cut +2 -2
- data/test/fixtures/templates/template_class/slots_template.html.cut +2 -2
- data/test/fixtures/templates/template_class/slots_template.pdf.cut +2 -2
- data/test/fixtures/user_manager/config/user_levels.yml +9 -0
- data/test/functional/test_application.rb +7 -7
- data/test/functional/test_back.rb +352 -97
- data/test/functional/test_front.rb +71 -20
- data/test/functional/test_user_manager.rb +284 -0
- data/test/javascript/env.js +13505 -0
- data/test/javascript/test_markdown.rb +43 -3
- data/test/support/custom_matchers.rb +3 -2
- data/test/test_helper.rb +50 -9
- data/test/test_javascript.rb +13 -13
- data/test/ui_helper.rb +1 -1
- data/test/unit/test_alias.rb +79 -8
- data/test/unit/test_asset_bundler.rb +220 -0
- data/test/unit/test_assets.rb +213 -0
- data/test/unit/test_async.rb +55 -0
- data/test/unit/test_authentication.rb +52 -39
- data/test/unit/test_boxes.rb +20 -15
- data/test/unit/test_changesets.rb +261 -0
- data/test/unit/test_content.rb +73 -33
- data/test/unit/test_content_inheritance.rb +18 -18
- data/test/unit/test_extensions.rb +26 -0
- data/test/unit/test_fields.rb +303 -16
- data/test/unit/test_formats.rb +267 -34
- data/test/unit/test_helpers.rb +79 -2
- data/test/unit/test_images.rb +10 -0
- data/test/unit/test_layouts.rb +21 -13
- data/test/unit/test_modifications.rb +648 -0
- data/test/unit/test_page.rb +6 -2
- data/test/unit/test_permissions.rb +101 -27
- data/test/unit/test_piece.rb +4 -4
- data/test/unit/test_plugins.rb +3 -2
- data/test/unit/test_publishing.rb +332 -0
- data/test/unit/test_render.rb +118 -67
- data/test/unit/test_revisions.rb +546 -0
- data/test/unit/test_schema.rb +83 -1
- data/test/unit/test_search.rb +59 -0
- data/test/unit/test_serialisation.rb +2 -47
- data/test/unit/test_site.rb +217 -108
- data/test/unit/test_storage.rb +26 -0
- data/test/unit/test_structure.rb +2 -2
- data/test/unit/test_styles.rb +90 -75
- data/test/unit/test_table_scoping.rb +21 -17
- data/test/unit/test_templates.rb +75 -69
- data/test/{slow → unit}/test_visibility.rb +78 -22
- metadata +528 -221
- data/application/css/add_alias_dialogue.scss +0 -27
- data/application/css/min/14c2a35812c443001b15d8b12a4780f88c678035.css +0 -1
- data/application/css/min/565d4c25e82148acb01c45c8d675b37a08676d77.css +0 -1
- data/application/css/min/84dbe894ea96eafd321c30823d630817bfc4b03b.css +0 -1
- data/application/css/spontaneous.scss +0 -111
- data/application/css/unsupported.scss +0 -16
- data/application/css/variables.scss +0 -80
- data/application/js/min/2a0c2962537a3181fedfff5c92596ba6d3122dc9.js +0 -3
- data/application/js/min/4cf1c493d3379ecba5287758c61238034c0893f9.js +0 -2
- data/application/js/min/78ac6b99d96750bb6b9f9aad4cb9cd91cd03f391.js +0 -3
- data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +0 -2
- data/application/js/min/c8efb9b9f7c3f6613fcebc6be60f605b6570a382.js +0 -90
- data/application/static/diagonal-texture.png +0 -0
- data/application/static/editing-0-noise.png +0 -0
- data/application/static/editing-1-noise.png +0 -0
- data/application/static/editing-texture-1.png +0 -0
- data/application/static/editing-texture.png +0 -0
- data/application/static/editing-toolbar-shadow-bottom.png +0 -0
- data/application/static/editing-toolbar-shadow-top.png +0 -0
- data/application/static/inner-glow.png +0 -0
- data/application/static/item-buttons-highlight.png +0 -0
- data/application/static/item-buttons.png +0 -0
- data/application/static/paper-texture-dark.png +0 -0
- data/application/static/plus_alt.svg +0 -8
- data/application/static/select-arrow-root.png +0 -0
- data/application/static/slot-up-arrow.png +0 -0
- data/application/static/spontaneous.png +0 -0
- data/lib/cutaneous/context_helper.rb +0 -187
- data/lib/cutaneous/preview_context.rb +0 -32
- data/lib/cutaneous/preview_renderer.rb +0 -10
- data/lib/cutaneous/publish_context.rb +0 -10
- data/lib/cutaneous/publish_renderer.rb +0 -14
- data/lib/cutaneous/publish_template.rb +0 -62
- data/lib/cutaneous/publish_token_parser.rb +0 -8
- data/lib/cutaneous/renderer.rb +0 -124
- data/lib/cutaneous/request_context.rb +0 -9
- data/lib/cutaneous/request_renderer.rb +0 -15
- data/lib/cutaneous/request_template.rb +0 -11
- data/lib/cutaneous/request_token_parser.rb +0 -9
- data/lib/cutaneous/token_parser.rb +0 -125
- data/lib/cutaneous.rb +0 -48
- data/lib/spontaneous/render/context_base.rb +0 -143
- data/lib/spontaneous/render/development_renderer.rb +0 -14
- data/lib/spontaneous/render/engine.rb +0 -19
- data/lib/spontaneous/render/format/html.rb +0 -5
- data/lib/spontaneous/render/format.rb +0 -75
- data/lib/spontaneous/render/helpers/script_helper.rb +0 -17
- data/lib/spontaneous/render/helpers/stylesheet_helper.rb +0 -16
- data/lib/spontaneous/render/helpers.rb +0 -14
- data/lib/spontaneous/render/preview_context.rb +0 -8
- data/lib/spontaneous/render/preview_renderer.rb +0 -24
- data/lib/spontaneous/render/publish_context.rb +0 -22
- data/lib/spontaneous/render/published_renderer.rb +0 -53
- data/lib/spontaneous/render/publishing_renderer.rb +0 -16
- data/lib/spontaneous/render/render_cache.rb +0 -26
- data/lib/spontaneous/render/renderer.rb +0 -50
- data/lib/spontaneous/render/request_context.rb +0 -8
- data/lib/spontaneous/render.rb +0 -214
- data/test/experimental/test_cutaneous.rb +0 -309
- data/test/fixtures/application/css/test.less +0 -5
- data/test/slow/test_publishing.rb +0 -1006
- /data/application/css/{developer.scss → developer.css.scss} +0 -0
- /data/application/js/vendor/{jquery-1.7.1.min.js → jquery.js} +0 -0
- /data/application/static/{location-arrow.png → location-arrow-c1c1d3ca472481c61a0a5f8cb289d743.png} +0 -0
- /data/application/static/{missing.png → missing-911ce6dbd9f4602e0f3fbcd7e78846a2.png} +0 -0
- /data/application/static/{orange-down-arrow.png → orange-down-arrow-395ae1929e8662b2ff0977daf12c35bb.png} +0 -0
- /data/application/static/{page-browser-next.png → page-browser-next-ce781a242c23b980b99b9db7abc20b05.png} +0 -0
- /data/application/static/{plus-box.png → plus-box-dcde74a1e496f68298c9b443caa1c5d5.png} +0 -0
- /data/application/static/{select-arrow.png → select-arrow-6e7dd3745b00e934b0d7a3250c46558b.png} +0 -0
- /data/application/static/{slot-down-arrow.png → slot-down-arrow-59ad5f5ee5b52a7ebd00bca4b3104194.png} +0 -0
- /data/application/static/{splash.png → splash-65b493a714df9b8b3ab170103401b53d.png} +0 -0
- /data/application/static/{spot.png → spot-71fab1d2f065034f5fc15e7bea2ad36c.png} +0 -0
- /data/application/static/{spot.svg → spot-8505041082d8d3bbe8d34c29dddb3b7d.svg} +0 -0
- /data/application/static/{texture.png → texture-03f7627e8264b1d607113ab32c593a58.png} +0 -0
|
@@ -15,10 +15,12 @@ class FrontTest < MiniTest::Spec
|
|
|
15
15
|
def self.startup
|
|
16
16
|
@site_root = Dir.mktmpdir
|
|
17
17
|
FileUtils.cp_r(File.expand_path("../../fixtures/public/templates", __FILE__), @site_root)
|
|
18
|
+
Spontaneous::Output.write_compiled_scripts = true
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
def self.shutdown
|
|
21
22
|
teardown_site
|
|
23
|
+
Spontaneous::Output.write_compiled_scripts = false
|
|
22
24
|
end
|
|
23
25
|
|
|
24
26
|
def setup
|
|
@@ -58,6 +60,10 @@ class FrontTest < MiniTest::Spec
|
|
|
58
60
|
last_request.env['rack.session']
|
|
59
61
|
end
|
|
60
62
|
|
|
63
|
+
def formats(format_list)
|
|
64
|
+
format_list.map { |f| Page.format_for(f) }
|
|
65
|
+
end
|
|
66
|
+
|
|
61
67
|
context "Public pages" do
|
|
62
68
|
setup do
|
|
63
69
|
|
|
@@ -65,7 +71,6 @@ class FrontTest < MiniTest::Spec
|
|
|
65
71
|
Site.publishing_method = :immediate
|
|
66
72
|
State.delete
|
|
67
73
|
Content.delete
|
|
68
|
-
Change.delete
|
|
69
74
|
|
|
70
75
|
class ::SitePage < Spontaneous::Page
|
|
71
76
|
layout :default
|
|
@@ -142,7 +147,7 @@ class FrontTest < MiniTest::Spec
|
|
|
142
147
|
end
|
|
143
148
|
|
|
144
149
|
should "honor the format of the request" do
|
|
145
|
-
@about.class.
|
|
150
|
+
@about.class.outputs :html, :pdf
|
|
146
151
|
get '/about.pdf'
|
|
147
152
|
assert last_response.ok?
|
|
148
153
|
last_response.body.should == "/about.pdf\n"
|
|
@@ -150,7 +155,7 @@ class FrontTest < MiniTest::Spec
|
|
|
150
155
|
end
|
|
151
156
|
|
|
152
157
|
should "provide the default format of the page if none is explicitly given" do
|
|
153
|
-
@about.class.
|
|
158
|
+
@about.class.outputs :rss, :html
|
|
154
159
|
get '/about'
|
|
155
160
|
assert last_response.ok?
|
|
156
161
|
last_response.content_type.should == ::Rack::Mime.mime_type('.rss') + ";charset=utf-8"
|
|
@@ -158,7 +163,7 @@ class FrontTest < MiniTest::Spec
|
|
|
158
163
|
end
|
|
159
164
|
|
|
160
165
|
should "return a custom content type if one is defined" do
|
|
161
|
-
@about.class.
|
|
166
|
+
@about.class.outputs [:html, {:mimetype => "application/xhtml+xml"}]
|
|
162
167
|
get '/about'
|
|
163
168
|
assert last_response.ok?
|
|
164
169
|
last_response.content_type.should == "application/xhtml+xml;charset=utf-8"
|
|
@@ -171,10 +176,16 @@ class FrontTest < MiniTest::Spec
|
|
|
171
176
|
assert last_response.status == 404
|
|
172
177
|
end
|
|
173
178
|
|
|
179
|
+
should "raise a 404 when accessing a private format" do
|
|
180
|
+
@about.class.outputs [:html, {:mimetype => "application/xhtml+xml"}], [:rss, {:private => true}]
|
|
181
|
+
get '/about.rss'
|
|
182
|
+
assert last_response.status == 404
|
|
183
|
+
end
|
|
184
|
+
|
|
174
185
|
context "Dynamic pages" do
|
|
175
186
|
setup do
|
|
176
|
-
Page.stubs(:path).with("/about").returns(about)
|
|
177
|
-
Page.stubs(:path).with("/news").returns(news)
|
|
187
|
+
Spontaneous::Page.stubs(:path).with("/about").returns(about)
|
|
188
|
+
Spontaneous::Page.stubs(:path).with("/news").returns(news)
|
|
178
189
|
end
|
|
179
190
|
|
|
180
191
|
should "default to static behaviour" do
|
|
@@ -254,7 +265,7 @@ class FrontTest < MiniTest::Spec
|
|
|
254
265
|
show "#news"
|
|
255
266
|
end
|
|
256
267
|
post '/about'
|
|
257
|
-
assert last_response.status == 200
|
|
268
|
+
assert last_response.status == 200, "Expected status 200 but recieved #{last_response.status}"
|
|
258
269
|
last_response.body.should == "/news.html\n"
|
|
259
270
|
end
|
|
260
271
|
|
|
@@ -276,6 +287,30 @@ class FrontTest < MiniTest::Spec
|
|
|
276
287
|
last_response.body.should == "/about.html\n"
|
|
277
288
|
last_response.headers["X-Works"].should == "Yes"
|
|
278
289
|
end
|
|
290
|
+
|
|
291
|
+
should "allow passing of template params & a page to the render call" do
|
|
292
|
+
SitePage.layout do
|
|
293
|
+
"{{ teeth }}"
|
|
294
|
+
end
|
|
295
|
+
SitePage.request do
|
|
296
|
+
render page, :teeth => "white"
|
|
297
|
+
end
|
|
298
|
+
get '/about'
|
|
299
|
+
assert last_response.status == 200
|
|
300
|
+
last_response.body.should == "white"
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
should "give access to the request params within the controller" do
|
|
304
|
+
SitePage.layout { "{{ params[:horse] }}*{{ equine }}" }
|
|
305
|
+
SitePage.request :post do
|
|
306
|
+
value = params[:horse]
|
|
307
|
+
render page, :equine => value
|
|
308
|
+
end
|
|
309
|
+
post '/about', :horse => "dancing"
|
|
310
|
+
assert last_response.status == 200
|
|
311
|
+
last_response.body.should == "dancing*dancing"
|
|
312
|
+
end
|
|
313
|
+
|
|
279
314
|
# should "handle anything that responds to #render(format)" do
|
|
280
315
|
# show = mock()
|
|
281
316
|
# show.stubs(:render).returns("mocked")
|
|
@@ -367,38 +402,44 @@ class FrontTest < MiniTest::Spec
|
|
|
367
402
|
|
|
368
403
|
context "caching" do
|
|
369
404
|
setup do
|
|
370
|
-
Spontaneous::
|
|
371
|
-
@cache_file = "#{Spontaneous.revision_dir(1)}/
|
|
405
|
+
Spontaneous::Output.cache_templates = true
|
|
406
|
+
@cache_file = "#{Spontaneous.revision_dir(1)}/dynamic/dynamic.html.rb"
|
|
407
|
+
Spontaneous::Output.write_compiled_scripts = true
|
|
372
408
|
end
|
|
373
409
|
|
|
374
410
|
teardown do
|
|
375
|
-
Spontaneous::
|
|
411
|
+
Spontaneous::Output.cache_templates = true
|
|
376
412
|
end
|
|
377
413
|
|
|
378
414
|
should "use pre-rendered versions of the templates" do
|
|
379
415
|
dummy_content = 'cached-version/#{session[\'user_id\']}'
|
|
380
|
-
dummy_template = File.join(@site.revision_root, "
|
|
416
|
+
dummy_template = File.join(@site.revision_root, "current/dynamic/dynamic.html.cut")
|
|
381
417
|
File.open(dummy_template, 'w') { |f| f.write(dummy_content) }
|
|
382
|
-
Spontaneous::Render.stubs(:output_path).returns(dummy_template)
|
|
418
|
+
# Spontaneous::Render.stubs(:output_path).returns(dummy_template)
|
|
383
419
|
get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
|
|
384
420
|
last_response.body.should == "cached-version/42"
|
|
385
421
|
end
|
|
386
422
|
|
|
387
423
|
should "cache templates as ruby files" do
|
|
388
|
-
|
|
424
|
+
dummy_content = 'cached-version/#{session[\'user_id\']}'
|
|
425
|
+
dummy_template = File.join(@site.revision_root, "current/dynamic/index.html.cut")
|
|
426
|
+
Spontaneous::Output.renderer.write_compiled_scripts = true
|
|
427
|
+
File.open(dummy_template, 'w') { |f| f.write(dummy_content) }
|
|
389
428
|
FileUtils.rm(@cache_file) if File.exists?(@cache_file)
|
|
390
429
|
File.exists?(@cache_file).should be_false
|
|
391
430
|
get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
|
|
392
|
-
|
|
431
|
+
|
|
393
432
|
File.exists?(@cache_file).should be_true
|
|
394
|
-
File.open(@cache_file, 'w') { |f| f.write('
|
|
433
|
+
File.open(@cache_file, 'w') { |f| f.write('@__buf << %Q`@cache_filed-version/#{params[\'wendy\']}`;')}
|
|
434
|
+
# Force compiled file to have a later timestamp
|
|
435
|
+
File.utime(Time.now, Time.now + 1, @cache_file)
|
|
395
436
|
get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
|
|
396
437
|
last_response.body.should == "@cache_filed-version/peter"
|
|
397
438
|
FileUtils.rm(@cache_file)
|
|
398
439
|
end
|
|
399
440
|
|
|
400
441
|
should "not cache templates if caching turned off" do
|
|
401
|
-
Spontaneous::
|
|
442
|
+
Spontaneous::Output.cache_templates = false
|
|
402
443
|
FileUtils.rm(@cache_file) if File.exists?(@cache_file)
|
|
403
444
|
File.exists?(@cache_file).should be_false
|
|
404
445
|
get '/dynamic', {'wendy' => 'peter'}, 'rack.session' => { 'user_id' => 42 }
|
|
@@ -447,6 +488,7 @@ class FrontTest < MiniTest::Spec
|
|
|
447
488
|
end
|
|
448
489
|
end
|
|
449
490
|
|
|
491
|
+
Page.stubs(:path).with("/").returns(root)
|
|
450
492
|
Page.stubs(:path).with("/about").returns(about)
|
|
451
493
|
Page.stubs(:path).with("/about/now").returns(subpage)
|
|
452
494
|
end
|
|
@@ -464,6 +506,13 @@ class FrontTest < MiniTest::Spec
|
|
|
464
506
|
last_response.body.should == about.render
|
|
465
507
|
end
|
|
466
508
|
|
|
509
|
+
should "work on the homepage" do
|
|
510
|
+
get "/@comments"
|
|
511
|
+
assert last_response.ok?
|
|
512
|
+
last_response.body.should == "Success"
|
|
513
|
+
end
|
|
514
|
+
|
|
515
|
+
|
|
467
516
|
should "be recognised" do
|
|
468
517
|
get "/about/@comments"
|
|
469
518
|
assert last_response.ok?
|
|
@@ -512,15 +561,17 @@ class FrontTest < MiniTest::Spec
|
|
|
512
561
|
end
|
|
513
562
|
|
|
514
563
|
should "pass the format onto the page if the action returns it to the render call" do
|
|
515
|
-
about.
|
|
516
|
-
about.
|
|
517
|
-
|
|
564
|
+
about.class.outputs :html, :xml
|
|
565
|
+
about.class.layout do
|
|
566
|
+
"${path}.${__format}"
|
|
567
|
+
end
|
|
518
568
|
get "/about/@comments/page.xml"
|
|
519
569
|
assert last_response.ok?
|
|
520
570
|
last_response.body.should == "/about.xml"
|
|
521
571
|
end
|
|
522
572
|
|
|
523
573
|
should "use the format within the action if required" do
|
|
574
|
+
about.class.outputs :html, :xml
|
|
524
575
|
get "/about/@comments/format.xml"
|
|
525
576
|
assert last_response.ok?
|
|
526
577
|
last_response.body.should == "xml"
|
|
@@ -612,4 +663,4 @@ class FrontTest < MiniTest::Spec
|
|
|
612
663
|
end
|
|
613
664
|
end
|
|
614
665
|
end
|
|
615
|
-
end
|
|
666
|
+
end
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
2
|
+
|
|
3
|
+
require File.expand_path('../../test_helper', __FILE__)
|
|
4
|
+
|
|
5
|
+
# set :environment, :test
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class UserAdminTest < MiniTest::Spec
|
|
9
|
+
include ::Rack::Test::Methods
|
|
10
|
+
|
|
11
|
+
def self.site_root
|
|
12
|
+
@site_root
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.startup
|
|
16
|
+
S::Permissions::User.delete
|
|
17
|
+
@site_root = Dir.mktmpdir
|
|
18
|
+
app_root = File.expand_path('../../fixtures/user_manager', __FILE__)
|
|
19
|
+
FileUtils.cp_r(app_root + "/", @site_root)
|
|
20
|
+
@site_root += "/user_manager"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def self.shutdown
|
|
24
|
+
teardown_site
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def app
|
|
28
|
+
Spontaneous::Rack::Back.application
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def setup
|
|
32
|
+
@site = setup_site(self.class.site_root)
|
|
33
|
+
Spot::Permissions::UserLevel.reset!
|
|
34
|
+
Spot::Permissions::UserLevel.init!
|
|
35
|
+
@editor_user = create_user("editor", S::Permissions[:editor])
|
|
36
|
+
@admin_user = create_user("admin", S::Permissions[:admin])
|
|
37
|
+
@root_user = create_user("root", S::Permissions[:root])
|
|
38
|
+
|
|
39
|
+
assert @editor_user.level == S::Permissions[:editor]
|
|
40
|
+
assert @admin_user.level == S::Permissions[:admin]
|
|
41
|
+
assert @root_user.level == S::Permissions[:root]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def teardown
|
|
45
|
+
S::Permissions::User.delete
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def create_user(name, level)
|
|
49
|
+
user = Permissions::User.create({
|
|
50
|
+
:name => "#{name.capitalize}",
|
|
51
|
+
:email => "#{name}@example.org",
|
|
52
|
+
:login => name,
|
|
53
|
+
:password => "#{name}_password"
|
|
54
|
+
})
|
|
55
|
+
user.update(:level => level)
|
|
56
|
+
user
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def login_user(user, params={})
|
|
60
|
+
post "/@spontaneous/login", {"user[login]" => user.login, "user[password]" => user.password}.merge(params)
|
|
61
|
+
@user = user
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def auth_post(path, params={})
|
|
65
|
+
key = @user.access_keys.first
|
|
66
|
+
post(path, params.merge("__key" => key.key_id))
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def auth_put(path, params={})
|
|
70
|
+
key = @user.access_keys.first
|
|
71
|
+
put(path, params.merge("__key" => key.key_id))
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def auth_get(path, params={})
|
|
75
|
+
key = @user.access_keys.first
|
|
76
|
+
get(path, params.merge("__key" => key.key_id))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def auth_del(path, params = {})
|
|
80
|
+
key = @user.access_keys.first
|
|
81
|
+
delete(path, params.merge("__key" => key.key_id))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
context "Access to User admin" do
|
|
86
|
+
should "be denied to unauthorised requests" do
|
|
87
|
+
get "/@spontaneous/users"
|
|
88
|
+
assert last_response.status == 401, "Expected 401 but got #{ last_response.status }"
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
should "be denied to users without the admin flag" do
|
|
92
|
+
login_user(@editor_user)
|
|
93
|
+
auth_get "/@spontaneous/users"
|
|
94
|
+
assert last_response.status == 403, "Expected 403 but got #{ last_response.status }"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
should "be granted to users with the admin flag" do
|
|
98
|
+
login_user(@admin_user)
|
|
99
|
+
auth_get "/@spontaneous/users"
|
|
100
|
+
assert last_response.status == 200, "Expected 200 but got #{ last_response.status }"
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
should "be granted to root users" do
|
|
104
|
+
login_user(@root_user)
|
|
105
|
+
auth_get "/@spontaneous/users"
|
|
106
|
+
assert last_response.status == 200, "Expected 200 but got #{ last_response.status }"
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
context "User application" do
|
|
111
|
+
setup do
|
|
112
|
+
login_user(@admin_user)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
should "return serialised list of current users" do
|
|
116
|
+
auth_get "/@spontaneous/users"
|
|
117
|
+
result = S::JSON.parse last_response.body
|
|
118
|
+
result.should == S::Permissions::User.export(@user)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
should "allow user details to be updated" do
|
|
122
|
+
auth_put "/@spontaneous/users/#{@editor_user.id}", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org" }
|
|
123
|
+
assert last_response.ok?, "Recieved a #{ last_response.status } instead of a 200"
|
|
124
|
+
@editor_user.reload.login.should == "robert"
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
should "allow a users level to be changed" do
|
|
128
|
+
auth_put "/@spontaneous/users/#{@editor_user.id}", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org", "user[level]" => "admin" }
|
|
129
|
+
assert last_response.ok?, "Recieved a #{ last_response.status } instead of a 200"
|
|
130
|
+
@editor_user.reload.level.should == @admin_user.level
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
should "reject updates that change the level above the current user's" do
|
|
134
|
+
level = @editor_user.level
|
|
135
|
+
auth_put "/@spontaneous/users/#{@editor_user.id}", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org", "user[level]" => "root" }
|
|
136
|
+
assert last_response.status == 403, "Recieved a #{ last_response.status } instead of a 403"
|
|
137
|
+
@editor_user.reload.level.should == level
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
should "reject an update with a conflicting login" do
|
|
141
|
+
auth_put "/@spontaneous/users/#{@editor_user.id}", { "user[name]" => "Robert Something", "user[login]" => "admin", "user[email]" => "robert@example.org" }
|
|
142
|
+
assert last_response.status == 422, "Recieved a #{ last_response.status } instead of a 422"
|
|
143
|
+
@editor_user.reload.login.should == "editor"
|
|
144
|
+
result = S::JSON.parse last_response.body
|
|
145
|
+
result.must_be_instance_of Hash
|
|
146
|
+
result[:login].should_not be_nil
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
should "reject an update with an invalid email" do
|
|
150
|
+
email = @editor_user.email
|
|
151
|
+
auth_put "/@spontaneous/users/#{@editor_user.id}", { "user[name]" => "Robert Something", "user[login]" => "editor", "user[email]" => "robert" }
|
|
152
|
+
assert last_response.status == 422, "Recieved a #{ last_response.status } instead of a 422"
|
|
153
|
+
@editor_user.reload.email.should == email
|
|
154
|
+
result = S::JSON.parse last_response.body
|
|
155
|
+
result.must_be_instance_of Hash
|
|
156
|
+
result[:email].should_not be_nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
should "ignore changes to the salt" do
|
|
160
|
+
salt = @editor_user.salt
|
|
161
|
+
auth_put "/@spontaneous/users/#{@editor_user.id}", { "user[name]" => "Robert Something", "user[login]" => "editor", "user[email]" => "robert@example.com", "user[salt]" => "123456" }
|
|
162
|
+
assert last_response.ok?
|
|
163
|
+
@editor_user.reload.salt.should == salt
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
should "allow updating of the user's password" do
|
|
167
|
+
new_pass = "123467890"
|
|
168
|
+
auth_put "/@spontaneous/users/password/#{@editor_user.id}", { "password" => new_pass }
|
|
169
|
+
assert last_response.ok?, "Recieved status #{ last_response.status} instead of 200"
|
|
170
|
+
key = Spontaneous::Permissions::User.authenticate(@editor_user.login, new_pass, "127.0.0.1")
|
|
171
|
+
key.should_not be_nil
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
should "reject & return error for invalid passwords" do
|
|
175
|
+
new_pass = "1234"
|
|
176
|
+
auth_put "/@spontaneous/users/password/#{@editor_user.id}", { "password" => new_pass }
|
|
177
|
+
assert last_response.status == 422, "Recieved a #{ last_response.status } instead of a 422"
|
|
178
|
+
key = Spontaneous::Permissions::User.authenticate(@editor_user.login, new_pass, "127.0.0.1")
|
|
179
|
+
key.should be_nil
|
|
180
|
+
result = S::JSON.parse last_response.body
|
|
181
|
+
result.must_be_instance_of Hash
|
|
182
|
+
result[:password].should_not be_nil
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
should "not allow changing details of users with higher level" do
|
|
186
|
+
auth_put "/@spontaneous/users/#{@root_user.id}", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org" }
|
|
187
|
+
assert last_response.status == 403, "Recieved a #{ last_response.status } instead of a 403"
|
|
188
|
+
@root_user.reload.login.should == "root"
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# should "allow admins to reset their password"
|
|
192
|
+
should "enable a force-logout of a user by deleting their keys" do
|
|
193
|
+
3.times do |n|
|
|
194
|
+
@editor_user.generate_access_key("203.99.33.#{n}")
|
|
195
|
+
end
|
|
196
|
+
@editor_user.access_keys.length.should == 3
|
|
197
|
+
auth_del "/@spontaneous/users/keys/#{@editor_user.id}"
|
|
198
|
+
assert last_response.ok?, "Recieved status #{ last_response.status} instead of 200"
|
|
199
|
+
@editor_user.reload.access_keys.length.should == 0
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
should "not allow logging out of user with higher level" do
|
|
203
|
+
3.times do |n|
|
|
204
|
+
@root_user.generate_access_key("203.99.33.#{n}")
|
|
205
|
+
end
|
|
206
|
+
@root_user.access_keys.length.should == 3
|
|
207
|
+
auth_del "/@spontaneous/users/keys/#{@root_user.id}"
|
|
208
|
+
assert last_response.status == 403, "Recieved a #{ last_response.status } instead of a 403"
|
|
209
|
+
@root_user.reload.access_keys.length.should == 3
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
should "allow you to disable a user" do
|
|
213
|
+
@editor_user.disabled?.should be_false
|
|
214
|
+
auth_put "/@spontaneous/users/disable/#{@editor_user.id}"
|
|
215
|
+
assert last_response.ok?
|
|
216
|
+
@editor_user.reload.disabled?.should be_true
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
should "allow you to re-enable a user" do
|
|
220
|
+
@editor_user.disabled?.should be_false
|
|
221
|
+
@editor_user.disable!
|
|
222
|
+
auth_put "/@spontaneous/users/enable/#{@editor_user.id}"
|
|
223
|
+
assert last_response.ok?
|
|
224
|
+
@editor_user.reload.disabled?.should be_false
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
should "not allow you to disable a user with a higher user level" do
|
|
228
|
+
@root_user.disabled?.should be_false
|
|
229
|
+
auth_put "/@spontaneous/users/disable/#{@root_user.id}"
|
|
230
|
+
assert last_response.status == 403, "Recieved a #{ last_response.status } instead of a 403"
|
|
231
|
+
@root_user.reload.disabled?.should be_false
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
should "allow for the creation of new users" do
|
|
235
|
+
auth_post "/@spontaneous/users", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org", "user[password]" => "robertpass", "user[level]" => "admin" }
|
|
236
|
+
assert last_response.ok?, "Recieved status #{ last_response.status} instead of 200"
|
|
237
|
+
user = S::Permissions::User[:login => "robert"]
|
|
238
|
+
user.must_be_instance_of S::Permissions::User
|
|
239
|
+
user.name.should == "Robert Something"
|
|
240
|
+
user.email.should == "robert@example.org"
|
|
241
|
+
user.level.should == Spontaneous::Permissions[:admin]
|
|
242
|
+
key = Spontaneous::Permissions::User.authenticate("robert", "robertpass", "127.0.0.1")
|
|
243
|
+
key.must_be_instance_of S::Permissions::AccessKey
|
|
244
|
+
key.user.id.should == user.id
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
should "return user info on account creation" do
|
|
248
|
+
auth_post "/@spontaneous/users", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org", "user[password]" => "robertpass", "user[level]" => "admin" }
|
|
249
|
+
assert last_response.ok?, "Recieved status #{ last_response.status} instead of 200"
|
|
250
|
+
result = S::JSON.parse last_response.body
|
|
251
|
+
result[:id].should_not be_nil
|
|
252
|
+
user = S::Permissions::User[result[:id]]
|
|
253
|
+
result.should == S::Permissions::User.export_user(user)
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
should "not allow creation of users with higher level" do
|
|
257
|
+
users = S::Permissions::User.count
|
|
258
|
+
auth_post "/@spontaneous/users", { "user[name]" => "Robert Something", "user[login]" => "robert", "user[email]" => "robert@example.org", "user[password]" => "robertpass", "user[level]" => "root" }
|
|
259
|
+
assert last_response.status == 403, "Recieved a #{ last_response.status } instead of a 403"
|
|
260
|
+
S::Permissions::User.count.should == users
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
should "return an error if passed invalid user attributes" do
|
|
264
|
+
users = S::Permissions::User.count
|
|
265
|
+
auth_post "/@spontaneous/users", { "user[name]" => "Robert Something", "user[login]" => "admin", "user[email]" => "robert", "user[password]" => "pass", "user[level]" => "editor" }
|
|
266
|
+
assert last_response.status == 422, "Recieved a #{ last_response.status } instead of a 422"
|
|
267
|
+
S::Permissions::User.count.should == users
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
should "allow us to delete a user" do
|
|
271
|
+
auth_del "/@spontaneous/users/#{@editor_user.id}"
|
|
272
|
+
assert last_response.status == 200, "Recieved a #{ last_response.status } instead of a 200"
|
|
273
|
+
user = Spontaneous::Permissions::User[:login => @editor_user.login]
|
|
274
|
+
user.should be_nil
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
should "not allow us to delete a user with a higher user level" do
|
|
278
|
+
auth_del "/@spontaneous/users/#{@root_user.id}"
|
|
279
|
+
assert last_response.status == 403, "Recieved a #{ last_response.status } instead of a 403"
|
|
280
|
+
user = Spontaneous::Permissions::User[:login => @root_user.login]
|
|
281
|
+
user.should_not be_nil
|
|
282
|
+
end
|
|
283
|
+
end
|
|
284
|
+
end
|