scriptorium 0.6.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +0 -1
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +0 -29
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +0 -19
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +1 -1
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +1 -1
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +1 -1
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +0 -10
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +1 -4
- data/doc/anti-amnesia/20250901-211714-codemirror-integration-and-web-tests.md +172 -0
- data/doc/anti-amnesia/20250902-002402-backup-restore-system.md +126 -0
- data/doc/anti-amnesia/20250907-203339-backup-metadata-implementation.md +66 -0
- data/doc/imported/0001-elixir-conf-2014/metadata.txt +7 -0
- data/doc/imported/0001-elixir-conf-2014/post.html +37 -0
- data/doc/imported/0001-elixir-conf-2014/source.lt3 +22 -0
- data/doc/imported/0002-programmers-and-word-processing/metadata.txt +7 -0
- data/doc/imported/0002-programmers-and-word-processing/post.html +192 -0
- data/doc/imported/0002-programmers-and-word-processing/source.lt3 +146 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/metadata.txt +7 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/post.html +60 -0
- data/doc/imported/0003-how-to-turn-your-brain-sideways/source.lt3 +40 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/metadata.txt +7 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/post.html +42 -0
- data/doc/imported/0004-upcoming-lone-star-ruby-conference/source.lt3 +24 -0
- data/doc/imported/0005-elixir-conf-2015-announced/metadata.txt +7 -0
- data/doc/imported/0005-elixir-conf-2015-announced/post.html +30 -0
- data/doc/imported/0005-elixir-conf-2015-announced/source.lt3 +16 -0
- data/doc/imported/0006-ruby-for-dinosaurs/metadata.txt +7 -0
- data/doc/imported/0006-ruby-for-dinosaurs/post.html +43 -0
- data/doc/imported/0006-ruby-for-dinosaurs/source.lt3 +27 -0
- data/doc/imported/0007-phoenix-isnt-rails/metadata.txt +7 -0
- data/doc/imported/0007-phoenix-isnt-rails/post.html +116 -0
- data/doc/imported/0007-phoenix-isnt-rails/source.lt3 +87 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/metadata.txt +7 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/post.html +129 -0
- data/doc/imported/0008-concerning-the-term-monkeypatching/source.lt3 +92 -0
- data/doc/imported/0009-announcement-coming-soon/metadata.txt +7 -0
- data/doc/imported/0009-announcement-coming-soon/post.html +33 -0
- data/doc/imported/0009-announcement-coming-soon/source.lt3 +19 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/metadata.txt +7 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/post.html +175 -0
- data/doc/imported/0010-immutable-data-ditching-the-wax-tablet/source.lt3 +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/post.html +139 -0
- data/doc/imported/0011-computer-science-as-a-lost-art/source.lt3 +104 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/metadata.txt +7 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/post.html +42 -0
- data/doc/imported/0012-ruby-day-in-turin-italy/source.lt3 +24 -0
- data/doc/imported/0013-rubyday-was-a-success/metadata.txt +7 -0
- data/doc/imported/0013-rubyday-was-a-success/post.html +44 -0
- data/doc/imported/0013-rubyday-was-a-success/source.lt3 +27 -0
- data/doc/imported/0014-working-on-the-blogging-software/metadata.txt +7 -0
- data/doc/imported/0014-working-on-the-blogging-software/post.html +63 -0
- data/doc/imported/0014-working-on-the-blogging-software/source.lt3 +41 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/metadata.txt +7 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/post.html +172 -0
- data/doc/imported/0015-ok-its-not-really-a-lost-art/source.lt3 +134 -0
- data/doc/imported/0016-an-in-operator-for-ruby/metadata.txt +7 -0
- data/doc/imported/0016-an-in-operator-for-ruby/post.html +155 -0
- data/doc/imported/0016-an-in-operator-for-ruby/source.lt3 +106 -0
- data/doc/imported/0017-the-forgotten-mathematician/metadata.txt +7 -0
- data/doc/imported/0017-the-forgotten-mathematician/post.html +161 -0
- data/doc/imported/0017-the-forgotten-mathematician/source.lt3 +119 -0
- data/doc/imported/0018-ruby-puns/metadata.txt +7 -0
- data/doc/imported/0018-ruby-puns/post.html +46 -0
- data/doc/imported/0018-ruby-puns/source.lt3 +28 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/metadata.txt +7 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/post.html +138 -0
- data/doc/imported/0019-custom-exceptions-via-metaprogramming/source.lt3 +101 -0
- data/doc/imported/0020-fffff/metadata.txt +7 -0
- data/doc/imported/0020-fffff/post.html +24 -0
- data/doc/imported/0020-fffff/source.lt3 +12 -0
- data/doc/imported/0021-trying-ror-yet-again/metadata.txt +7 -0
- data/doc/imported/0021-trying-ror-yet-again/post.html +26 -0
- data/doc/imported/0021-trying-ror-yet-again/source.lt3 +12 -0
- data/doc/imported/0023-doctor-sleep/metadata.txt +7 -0
- data/doc/imported/0023-doctor-sleep/post.html +63 -0
- data/doc/imported/0023-doctor-sleep/source.lt3 +44 -0
- data/doc/imported/0024-just-a-test/metadata.txt +7 -0
- data/doc/imported/0024-just-a-test/post.html +24 -0
- data/doc/imported/0024-just-a-test/source.lt3 +12 -0
- data/doc/imported/import_summary.txt +98 -0
- data/doc/livetext-informal-spec.txt +65 -0
- data/doc/myuserdoc/ch-0.lt3 +31 -0
- data/doc/myuserdoc/ch-1.lt3 +37 -0
- data/doc/myuserdoc/ch-10.lt3 +22 -0
- data/doc/myuserdoc/ch-2.lt3 +37 -0
- data/doc/myuserdoc/ch-3.lt3 +19 -0
- data/doc/myuserdoc/ch-4.lt3 +43 -0
- data/doc/myuserdoc/ch-5.lt3 +22 -0
- data/doc/myuserdoc/ch-6.lt3 +19 -0
- data/doc/myuserdoc/ch-7.lt3 +16 -0
- data/doc/myuserdoc/ch-8.lt3 +13 -0
- data/doc/myuserdoc/ch-9.lt3 +19 -0
- data/doc/myuserdoc/tweak.rb +18 -0
- data/doc/{userdoc-toc.txt → myuserdoc/userdoc-toc.txt} +27 -27
- data/doc/old-posts/0001-elixir-conf-2014.lt3 +24 -0
- data/doc/old-posts/0002-programmers-and-word-processing.lt3 +150 -0
- data/doc/old-posts/0003-how-to-turn-your-brain-sideways.lt3 +43 -0
- data/doc/old-posts/0004-upcoming-lone-star-ruby-conference.lt3 +26 -0
- data/doc/old-posts/0005-elixir-conf-2015-announced.lt3 +17 -0
- data/doc/old-posts/0006-ruby-for-dinosaurs.lt3 +30 -0
- data/doc/old-posts/0007-phoenix-isnt-rails.lt3 +90 -0
- data/doc/old-posts/0008-concerning-the-term-monkeypatching.lt3 +105 -0
- data/doc/old-posts/0009-announcement-coming-soon.lt3 +20 -0
- data/doc/old-posts/0010-immutable-data-ditching-the-wax-tablet.lt3 +142 -0
- data/doc/old-posts/0011-computer-science-as-a-lost-art.lt3 +117 -0
- data/doc/old-posts/0012-ruby-day-in-turin-italy.lt3 +26 -0
- data/doc/old-posts/0013-rubyday-was-a-success.lt3 +28 -0
- data/doc/old-posts/0014-working-on-the-blogging-software.lt3 +42 -0
- data/doc/old-posts/0015-ok-its-not-really-a-lost-art.lt3 +137 -0
- data/doc/old-posts/0016-an-in-operator-for-ruby.lt3 +142 -0
- data/doc/old-posts/0017-the-forgotten-mathematician.lt3 +129 -0
- data/doc/old-posts/0018-ruby-puns.lt3 +31 -0
- data/doc/old-posts/0019-custom-exceptions-via-metaprogramming.lt3 +116 -0
- data/doc/old-posts/0021-trying-ror-yet-again.lt3 +35 -0
- data/doc/old-posts/0023-doctor-sleep.lt3 +43 -0
- data/doc/old-posts/0024-just-a-test.lt3 +12 -0
- data/doc/old-posts/0025-trying-another-post.lt3 +12 -0
- data/doc/old-repo +1 -0
- data/doc/reddit_integration.md +2 -2
- data/doc/user.lt3 +0 -3
- data/lib/scriptorium/api.rb +1811 -78
- data/lib/scriptorium/banner_svg.rb +55 -68
- data/lib/scriptorium/contract.rb +3 -2
- data/lib/scriptorium/exceptions.rb +133 -102
- data/lib/scriptorium/helpers.rb +282 -82
- data/lib/scriptorium/post.rb +81 -17
- data/lib/scriptorium/reddit.rb +1 -1
- data/lib/scriptorium/repo.rb +478 -164
- data/lib/scriptorium/standard_files.rb +30 -396
- data/lib/scriptorium/support/common_js/clipboard.js +35 -0
- data/lib/scriptorium/support/common_js/content-loader.js +187 -0
- data/lib/scriptorium/support/common_js/navigation.js +52 -0
- data/lib/scriptorium/support/common_js/syntax-highlighting.js +27 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/social.txt +1 -0
- data/lib/scriptorium/support/highlight/css.txt +2 -0
- data/lib/scriptorium/support/highlight/custom.css +119 -0
- data/lib/scriptorium/support/highlight/js.txt +1 -0
- data/lib/scriptorium/support/post_index/config.txt +15 -0
- data/lib/scriptorium/support/post_index/style.css +55 -0
- data/lib/scriptorium/support/templates/index_entry.lt3 +16 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 → lib/scriptorium/support/templates/initial_post.lt3} +5 -5
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt → lib/scriptorium/support/theme/header.lt3} +1 -1
- data/lib/scriptorium/theme.rb +83 -70
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +194 -149
- data/lib/scriptorium.rb +24 -1
- data/lib/skeleton.rb +4 -1
- data/scriptorium.gemspec +2 -1
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +40 -0
- data/test/banner_svg/unit.rb +267 -35
- data/test/config/deployment.txt +5 -0
- data/test/integration/integration_test.rb +7 -7
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +453 -182
- data/test/manual/banner-tests/test01.html +82 -18
- data/test/manual/banner-tests/test02.html +82 -18
- data/test/manual/banner-tests/test03.html +82 -18
- data/test/manual/banner-tests/test04.html +89 -25
- data/test/manual/banner-tests/test05.html +89 -25
- data/test/manual/banner-tests/test06.html +89 -25
- data/test/manual/banner-tests/test07.html +89 -25
- data/test/manual/banner-tests/test08.html +82 -18
- data/test/manual/banner-tests/test09.html +82 -18
- data/test/manual/banner-tests/test10.html +82 -18
- data/test/manual/banner-tests/test11.html +82 -18
- data/test/manual/banner-tests/test12.html +82 -18
- data/test/manual/banner-tests/test13.html +82 -18
- data/test/manual/banner-tests/test14.html +82 -18
- data/test/manual/banner-tests/test15.html +82 -18
- data/test/manual/banner-tests/test16.html +82 -18
- data/test/manual/banner-tests/test17.html +82 -18
- data/test/manual/banner-tests/test18.html +90 -26
- data/test/manual/banner-tests/test19.html +90 -26
- data/test/manual/banner-tests/test20.html +90 -26
- data/test/manual/banner-tests/test21.html +90 -26
- data/test/manual/banner-tests/test22.html +90 -26
- data/test/manual/banner-tests/test23.html +90 -26
- data/test/manual/banner-tests/test24.html +90 -26
- data/test/manual/banner-tests/test25.html +89 -25
- data/test/manual/banner_environment.rb +15 -2
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/test_banner_features.rb +14 -14
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_syntax_highlighting.rb +60 -40
- data/test/support/preview_utils.rb +88 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +10 -0
- data/test/tui_editor_integration_test.rb +15 -15
- data/test/tui_integration_test.rb +687 -441
- data/test/unit/api.rb +757 -37
- data/test/unit/asset_management.rb +195 -221
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/contract_test.rb +1 -23
- data/test/unit/core.rb +415 -61
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +312 -21
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +36 -42
- data/test/unit/livetext_basic.rb +23 -35
- data/test/unit/livetext_compatibility.rb +7 -14
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/{symlink_test.rb → permalink_copy_test.rb} +47 -49
- data/test/unit/post.rb +91 -26
- data/test/unit/post_index_config_test.rb +258 -0
- data/test/unit/post_state_helpers_test.rb +137 -0
- data/test/unit/read_commented_file_test.rb +8 -6
- data/test/unit/repo.rb +75 -54
- data/test/unit/social_test.rb +41 -44
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +79 -12
- data/test/unit/widgets.rb +8 -8
- data/test/web_integration_test.rb +231 -0
- data/test/web_test_helper.rb +218 -0
- data/test/web_workflow_test.rb +527 -0
- data/ui/tui/bin/scriptorium +885 -415
- data/ui/web/app/app.rb +1398 -176
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +16 -16
- data/ui/web/app/views/advanced_config.erb +8 -2
- data/ui/web/app/views/asset_management.erb +56 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/dashboard.erb +64 -72
- data/ui/web/app/views/deploy_config.erb +3 -0
- data/ui/web/app/views/edit_pages.erb +170 -2
- data/ui/web/app/views/edit_post.erb +130 -9
- data/ui/web/app/views/edit_theme.erb +73 -0
- data/ui/web/app/views/edit_theme_file.erb +74 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +666 -25
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +35 -24
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -5
- metadata +190 -116
- data/assets/back-icon.png +0 -0
- data/assets/icons/facebook.svg +0 -1
- data/assets/icons/github.svg +0 -1
- data/assets/icons/instagram.svg +0 -1
- data/assets/icons/reddit.svg +0 -1
- data/assets/icons/x.svg +0 -1
- data/assets/icons/youtube.svg +0 -1
- data/bin/scriptorium +0 -1511
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +0 -34
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +0 -50
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +0 -73
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +0 -70
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +0 -110
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +0 -73
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +0 -124
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +0 -46
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +0 -97
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +0 -211
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +0 -141
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +0 -211
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +0 -134
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +0 -41
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +0 -49
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +0 -46
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +0 -41
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +0 -256
- data/lib/scriptorium/syntax_highlighter.rb +0 -234
- data/test/manual/deploy_symlink_demo.rb +0 -142
- data/test/manual/symlink_demo.rb +0 -117
- data/test/manual/test2.rb +0 -12
- data/test/manual/test_banner_from_file.rb +0 -150
- data/test/manual/test_banner_in_header.rb +0 -35
- data/test/manual/test_code_highlighting.rb +0 -68
- data/test/manual/test_complex_header.rb +0 -74
- data/test/manual/test_empty_header.rb +0 -32
- data/test/manual/test_radial_custom.rb +0 -58
- data/test/manual/test_radial_large_radius.rb +0 -52
- data/test/manual/test_svg_debug.rb +0 -47
- data/test/pages-demo/config/currentview.txt +0 -1
- data/test/pages-demo/views/demo/config/common.js +0 -57
- data/test/pages-demo/views/demo/config/footer.txt +0 -1
- data/test/pages-demo/views/demo/config/global-head.txt +0 -8
- data/test/pages-demo/views/demo/config/header.txt +0 -1
- data/test/pages-demo/views/demo/config/layout.txt +0 -1
- data/test/pages-demo/views/demo/config/left.txt +0 -1
- data/test/pages-demo/views/demo/config/main.txt +0 -1
- data/test/pages-demo/views/demo/config/right.txt +0 -1
- data/test/pages-demo/views/demo/config.txt +0 -3
- data/test/pages-demo/views/demo/output/panes/footer.html +0 -1
- data/test/pages-demo/views/demo/output/panes/header.html +0 -1
- data/test/pages-demo/views/demo/output/panes/left.html +0 -1
- data/test/pages-demo/views/demo/output/panes/main.html +0 -1
- data/test/pages-demo/views/demo/output/panes/right.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +0 -4
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +0 -8
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +0 -6
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +0 -14
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +0 -13
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +0 -57
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +0 -2
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +0 -9
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +0 -4
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +0 -5
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +0 -7
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +0 -3
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +0 -1
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +0 -1
- data/ui/web/tmp/web_server.pid +0 -1
- /data/{test/pages-demo/views/demo/config/bootstrap_css.txt → lib/scriptorium/support/bootstrap/css.txt} +0 -0
- /data/{test/pages-demo/views/demo/config/bootstrap_js.txt → lib/scriptorium/support/bootstrap/js.txt} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/views/sample → lib/scriptorium/support}/config/reddit.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout → lib/scriptorium/support/templates}/layout.txt +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt → lib/scriptorium/support/theme/footer.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt → lib/scriptorium/support/theme/left.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt → lib/scriptorium/support/theme/main.lt3} +0 -0
- /data/{test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt → lib/scriptorium/support/theme/right.lt3} +0 -0
- /data/test/manual/banner-tests/{config.txt → svg.txt} +0 -0
- /data/test/manual/{test6.rb → test_advanced_widgets.rb} +0 -0
- /data/test/manual/{test1.rb → test_basic_posts.rb} +0 -0
- /data/test/manual/{test4.rb → test_layout_widgets.rb} +0 -0
- /data/test/manual/{test5.rb → test_pagination.rb} +0 -0
- /data/test/manual/{test3.rb → test_random_posts.rb} +0 -0
@@ -0,0 +1,527 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require_relative '../lib/scriptorium'
|
5
|
+
require_relative 'web_test_helper'
|
6
|
+
|
7
|
+
class WebWorkflowTest < Minitest::Test
|
8
|
+
include Scriptorium::Helpers
|
9
|
+
include WebTestHelper
|
10
|
+
|
11
|
+
# Test repository path and web server config are now in WebTestHelper
|
12
|
+
|
13
|
+
def setup
|
14
|
+
cleanup_test_repo
|
15
|
+
# Disable DBC contracts in tests
|
16
|
+
ENV['DBC_DISABLED'] = 'true'
|
17
|
+
|
18
|
+
# rbenv hack to ensure correct Ruby version
|
19
|
+
ENV['PATH'] = "#{ENV['HOME']}/.rbenv/shims:#{ENV['PATH']}"
|
20
|
+
ENV['RBENV_VERSION'] = '3.2.3'
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
cleanup_test_repo
|
25
|
+
stop_web_server
|
26
|
+
end
|
27
|
+
|
28
|
+
# Test complete repository setup workflow via web
|
29
|
+
def test_001_complete_repository_setup
|
30
|
+
start_web_server
|
31
|
+
|
32
|
+
# Step 1: Check initial state (no repository)
|
33
|
+
response = get("/")
|
34
|
+
assert_response_success(response, "Dashboard should load initially")
|
35
|
+
assert_includes_concise response, "No repository loaded", "Should show no repository message"
|
36
|
+
|
37
|
+
# Step 2: Create repository via web form
|
38
|
+
response = post("/create_repo", {})
|
39
|
+
assert_response_redirect(response, "Repository creation should redirect after success")
|
40
|
+
|
41
|
+
# Step 3: Verify repository was created
|
42
|
+
response = get("/")
|
43
|
+
assert_response_success(response, "Dashboard should load after repo creation")
|
44
|
+
assert_includes_concise response, "scriptorium-TEST", "Should show repository name"
|
45
|
+
|
46
|
+
# Complete repository setup workflow working
|
47
|
+
end
|
48
|
+
|
49
|
+
# Test view creation workflow via web
|
50
|
+
def test_002_view_creation_workflow
|
51
|
+
start_web_server
|
52
|
+
|
53
|
+
# Step 1: Create repository first
|
54
|
+
post("/create_repo", {})
|
55
|
+
|
56
|
+
# Step 2: Create view via web form
|
57
|
+
response = post("/create_view", {
|
58
|
+
name: "test-view",
|
59
|
+
title: "Test View",
|
60
|
+
subtitle: "A test view for web testing"
|
61
|
+
})
|
62
|
+
assert_response_redirect(response, "View creation should redirect after success")
|
63
|
+
|
64
|
+
# Step 3: Verify view was created
|
65
|
+
response = get("/")
|
66
|
+
assert_response_success(response, "Dashboard should load after view creation")
|
67
|
+
assert_includes_concise response, "test-view", "Should show created view"
|
68
|
+
|
69
|
+
# View creation workflow working
|
70
|
+
end
|
71
|
+
|
72
|
+
# Test post creation workflow via web
|
73
|
+
def test_003_post_creation_workflow
|
74
|
+
start_web_server
|
75
|
+
|
76
|
+
# Step 1: Setup repository and view
|
77
|
+
post("/create_repo", {})
|
78
|
+
post("/create_view", {
|
79
|
+
name: "test-view",
|
80
|
+
title: "Test View",
|
81
|
+
subtitle: "A test view for web testing"
|
82
|
+
})
|
83
|
+
|
84
|
+
# Step 2: Create post via web form
|
85
|
+
response = post("/create_post", {
|
86
|
+
title: "Test Post via Web",
|
87
|
+
content: "This is a test post created via the web interface."
|
88
|
+
})
|
89
|
+
assert_response_redirect(response, "Post creation should redirect after success")
|
90
|
+
|
91
|
+
# Step 3: Verify post was created
|
92
|
+
response = get("/view/test-view")
|
93
|
+
assert_response_success(response, "View dashboard should load")
|
94
|
+
assert_includes_concise response, "Test Post via Web", "Should show created post"
|
95
|
+
|
96
|
+
# Post creation workflow working
|
97
|
+
end
|
98
|
+
|
99
|
+
# Test post editing workflow via web
|
100
|
+
def test_004_post_editing_workflow
|
101
|
+
start_web_server
|
102
|
+
|
103
|
+
# Step 1: Create a fresh test repository
|
104
|
+
response = post("/create_repo", {})
|
105
|
+
assert_response_redirect(response, "Repository creation should redirect after success")
|
106
|
+
|
107
|
+
# Step 2: Create a test view
|
108
|
+
response = post("/create_view", {
|
109
|
+
name: "test-view",
|
110
|
+
title: "Test View",
|
111
|
+
subtitle: "A test view for web testing"
|
112
|
+
})
|
113
|
+
assert_response_redirect(response, "View creation should redirect after success")
|
114
|
+
|
115
|
+
# Step 3: Create a post via the web interface
|
116
|
+
response = post("/create_post", {
|
117
|
+
title: "Test Post for Editing",
|
118
|
+
content: "Original content of the test post."
|
119
|
+
})
|
120
|
+
assert_response_redirect(response, "Post creation should redirect after success")
|
121
|
+
|
122
|
+
# Step 4: Get the post ID from the redirect
|
123
|
+
# The redirect should be to /view/test-view?edit_post=#{post_num}
|
124
|
+
redirect_location = response['Location']
|
125
|
+
assert_includes redirect_location, "edit_post=", "Should redirect with edit_post parameter"
|
126
|
+
|
127
|
+
# Extract post ID from redirect URL
|
128
|
+
post_id = redirect_location.match(/edit_post=(\d+)/)[1]
|
129
|
+
assert_match(/^\d+$/, post_id, "Post ID should be numeric")
|
130
|
+
|
131
|
+
# Step 5: Edit the post content
|
132
|
+
edited_content = "Updated content with LiveText syntax.\n\n.h1 Updated Title\n\nThis is *bold text and _italic text.\n\n.raw\nRaw content here\n__RAW__\n\n.def test_function\n puts 'Hello World'\n.end"
|
133
|
+
|
134
|
+
response = post("/save_post/#{post_id}", {
|
135
|
+
content: edited_content
|
136
|
+
})
|
137
|
+
assert_response_redirect(response, "Post saving should redirect after success")
|
138
|
+
|
139
|
+
# Step 6: Verify the post was saved by checking the redirect message
|
140
|
+
assert_includes response['Location'], "message=Post saved successfully", "Should show success message"
|
141
|
+
|
142
|
+
# Step 7: Verify the content was actually saved by reading the post file
|
143
|
+
# This tests the actual file writing functionality
|
144
|
+
# The file path uses the 4-digit post number format (e.g., 0001, 0002)
|
145
|
+
post_number = sprintf("%04d", post_id.to_i)
|
146
|
+
post_file_path = "#{WebTestHelper::TEST_REPO_PATH}/posts/#{post_number}/source.lt3"
|
147
|
+
assert File.exist?(post_file_path), "Post source file should exist at #{post_file_path}"
|
148
|
+
|
149
|
+
saved_content = File.read(post_file_path)
|
150
|
+
|
151
|
+
# The write_file helper adds a trailing newline, so we need to account for that
|
152
|
+
expected_content = edited_content + "\n"
|
153
|
+
assert_equal expected_content, saved_content, "Saved content should match edited content (with trailing newline)"
|
154
|
+
|
155
|
+
# Post editing workflow working
|
156
|
+
end
|
157
|
+
|
158
|
+
# Test asset management workflow via web
|
159
|
+
def test_005_asset_management_workflow
|
160
|
+
start_web_server
|
161
|
+
|
162
|
+
# Step 1: Setup repository and view
|
163
|
+
post("/create_repo", {})
|
164
|
+
post("/create_view", {
|
165
|
+
name: "test-view",
|
166
|
+
title: "Test View",
|
167
|
+
subtitle: "A test view for web testing"
|
168
|
+
})
|
169
|
+
|
170
|
+
# Step 2: Access asset management
|
171
|
+
response = get("/asset_management")
|
172
|
+
assert_response_success(response, "Asset management page should load")
|
173
|
+
assert_includes_concise response, "Asset Management", "Should show asset management interface"
|
174
|
+
|
175
|
+
# Step 3: Test asset upload (simulated)
|
176
|
+
# Note: This would require file upload handling in a real test
|
177
|
+
assert_includes_concise response, "upload", "Should have upload functionality"
|
178
|
+
|
179
|
+
# Asset management workflow accessible
|
180
|
+
end
|
181
|
+
|
182
|
+
# Test view configuration workflow via web
|
183
|
+
def test_006_view_configuration_workflow
|
184
|
+
start_web_server
|
185
|
+
|
186
|
+
# Step 1: Setup repository and view
|
187
|
+
post("/create_repo", {})
|
188
|
+
post("/create_view", {
|
189
|
+
name: "test-view",
|
190
|
+
title: "Test View",
|
191
|
+
subtitle: "A test view for web testing"
|
192
|
+
})
|
193
|
+
|
194
|
+
# Step 2: Access view configuration
|
195
|
+
response = get("/configure_view/test-view")
|
196
|
+
assert_response_success(response, "View configuration page should load")
|
197
|
+
assert_includes_concise response, "Configure View", "Should show configuration interface"
|
198
|
+
|
199
|
+
# Step 3: Test configuration saving
|
200
|
+
response = post("/save_view_config/test-view", {
|
201
|
+
view_title: "Updated Test View",
|
202
|
+
view_subtitle: "Updated subtitle",
|
203
|
+
view_theme: "standard"
|
204
|
+
})
|
205
|
+
assert_response_redirect(response, "Configuration save should redirect after success")
|
206
|
+
|
207
|
+
# View configuration workflow working
|
208
|
+
end
|
209
|
+
|
210
|
+
# Test deployment workflow via web
|
211
|
+
def test_007_deployment_workflow
|
212
|
+
start_web_server
|
213
|
+
|
214
|
+
# Step 1: Setup repository and view
|
215
|
+
post("/create_repo", {})
|
216
|
+
post("/create_view", {
|
217
|
+
name: "test-view",
|
218
|
+
title: "Test View",
|
219
|
+
subtitle: "A test view for web testing"
|
220
|
+
})
|
221
|
+
|
222
|
+
# Step 2: Access deployment configuration
|
223
|
+
response = get("/deploy_config")
|
224
|
+
assert_response_success(response, "Deployment config page should load")
|
225
|
+
assert_includes_concise response, "Deployment Configuration", "Should show deployment interface"
|
226
|
+
|
227
|
+
# Step 3: Test deployment configuration saving
|
228
|
+
response = post("/deploy_config", {
|
229
|
+
deploy_config: "proto http\nserver localhost\npath /test",
|
230
|
+
from_deploy: "0"
|
231
|
+
})
|
232
|
+
assert_response_redirect(response, "Deployment config save should redirect after success")
|
233
|
+
|
234
|
+
# Deployment workflow accessible
|
235
|
+
end
|
236
|
+
|
237
|
+
# Test publish/unpublish workflow via web
|
238
|
+
def test_008_publish_unpublish_workflow
|
239
|
+
start_web_server
|
240
|
+
setup_test_environment
|
241
|
+
|
242
|
+
# Create a post
|
243
|
+
response = post("/create_post", { title: "Test Publish Post", content: "Content for publish test" })
|
244
|
+
assert_response_redirect(response, "Should create post successfully")
|
245
|
+
|
246
|
+
# Extract post ID from redirect
|
247
|
+
redirect_location = response['Location']
|
248
|
+
post_id = redirect_location.match(/edit_post=(\d+)/)[1]
|
249
|
+
|
250
|
+
# Initially post should be unpublished
|
251
|
+
post_file = "#{WebTestHelper::TEST_REPO_PATH}/posts/#{sprintf("%04d", post_id.to_i)}/source.lt3"
|
252
|
+
assert File.exist?(post_file), "Post file should exist"
|
253
|
+
|
254
|
+
# Publish the post via web interface
|
255
|
+
response = post("/toggle_post_status/#{post_id}", {})
|
256
|
+
assert_equal 200, response.code.to_i, "Should return 200 for publish"
|
257
|
+
|
258
|
+
# Parse JSON response
|
259
|
+
json_response = JSON.parse(response.body)
|
260
|
+
assert json_response['success'], "Publish should succeed"
|
261
|
+
assert json_response['published'], "Post should be marked as published"
|
262
|
+
|
263
|
+
# Verify the HTML shows the post as published
|
264
|
+
response = get("/view/test-view")
|
265
|
+
assert_response_success(response, "Should load view dashboard")
|
266
|
+
assert_includes_concise response, "Published", "HTML should show 'Published' status"
|
267
|
+
|
268
|
+
# Unpublish the post via web interface
|
269
|
+
response = post("/toggle_post_status/#{post_id}", {})
|
270
|
+
assert_equal 200, response.code.to_i, "Should return 200 for unpublish"
|
271
|
+
|
272
|
+
# Parse JSON response
|
273
|
+
json_response = JSON.parse(response.body)
|
274
|
+
assert json_response['success'], "Unpublish should succeed"
|
275
|
+
refute json_response['published'], "Post should be marked as unpublished"
|
276
|
+
|
277
|
+
# Verify the HTML shows the post as unpublished
|
278
|
+
response = get("/view/test-view")
|
279
|
+
assert_response_success(response, "Should load view dashboard")
|
280
|
+
assert_includes_concise response, "unpublished", "HTML should show 'unpublished' status"
|
281
|
+
end
|
282
|
+
|
283
|
+
# Test delete/restore workflow via web
|
284
|
+
def test_009_delete_restore_workflow
|
285
|
+
start_web_server
|
286
|
+
setup_test_environment
|
287
|
+
|
288
|
+
# Create a post
|
289
|
+
response = post("/create_post", { title: "Test Delete Post", content: "Content for delete test" })
|
290
|
+
assert_response_redirect(response, "Should create post successfully")
|
291
|
+
|
292
|
+
# Extract post ID from redirect
|
293
|
+
redirect_location = response['Location']
|
294
|
+
post_id = redirect_location.match(/edit_post=(\d+)/)[1]
|
295
|
+
|
296
|
+
# Initially post should be visible
|
297
|
+
response = get("/view/test-view")
|
298
|
+
assert_response_success(response, "Should load view dashboard")
|
299
|
+
assert_includes_concise response, "Test Delete Post", "HTML should show post title"
|
300
|
+
refute_includes response.body, "text-decoration: line-through", "Post should not be strikethrough"
|
301
|
+
|
302
|
+
# Delete the post via web interface
|
303
|
+
response = post("/delete_post/#{post_id}", {})
|
304
|
+
assert_response_redirect(response, "Should redirect after delete")
|
305
|
+
|
306
|
+
# Verify the HTML shows the post as deleted (strikethrough)
|
307
|
+
response = get("/view/test-view")
|
308
|
+
assert_response_success(response, "Should load view dashboard")
|
309
|
+
assert_includes_concise response, "Test Delete Post", "HTML should still show post title"
|
310
|
+
assert_includes_concise response, "text-decoration: line-through", "Post should be strikethrough when deleted"
|
311
|
+
|
312
|
+
# Restore the post via web interface
|
313
|
+
response = post("/restore_post/#{post_id}", {})
|
314
|
+
assert_response_redirect(response, "Should redirect after restore")
|
315
|
+
|
316
|
+
# Verify the HTML shows the post as restored (no strikethrough)
|
317
|
+
response = get("/view/test-view")
|
318
|
+
assert_response_success(response, "Should load view dashboard")
|
319
|
+
assert_includes_concise response, "Test Delete Post", "HTML should show post title"
|
320
|
+
refute_includes response.body, "text-decoration: line-through", "Post should not be strikethrough when restored"
|
321
|
+
end
|
322
|
+
|
323
|
+
# Test error handling and edge cases
|
324
|
+
def test_010_error_handling
|
325
|
+
start_web_server
|
326
|
+
|
327
|
+
# Test 1: Access non-existent view
|
328
|
+
response = get("/view/non-existent-view")
|
329
|
+
assert_equal "302", response.code, "Should redirect for non-existent view"
|
330
|
+
|
331
|
+
# Test 2: Access pages without repository
|
332
|
+
response = get("/asset_management")
|
333
|
+
assert_equal "302", response.code, "Should redirect without repository"
|
334
|
+
|
335
|
+
# Test 3: Access pages without view
|
336
|
+
response = get("/configure_view/test-view")
|
337
|
+
assert_equal "302", response.code, "Should redirect without view"
|
338
|
+
|
339
|
+
# Error handling working correctly
|
340
|
+
end
|
341
|
+
|
342
|
+
# Test backup management page access
|
343
|
+
def test_005_backup_management_page_access
|
344
|
+
start_web_server
|
345
|
+
setup_test_environment
|
346
|
+
|
347
|
+
# Test accessing backup management page
|
348
|
+
response = get("/backup_management")
|
349
|
+
assert_response_success(response, "Backup management page should load")
|
350
|
+
assert_includes_concise response, "Backup Management", "Should show backup management title"
|
351
|
+
assert_includes_concise response, "Create New Backup", "Should show backup creation form"
|
352
|
+
assert_includes_concise response, "Available Backups", "Should show backups list section"
|
353
|
+
end
|
354
|
+
|
355
|
+
# Test backup creation via web form
|
356
|
+
def test_006_backup_creation_workflow
|
357
|
+
start_web_server
|
358
|
+
setup_test_environment
|
359
|
+
|
360
|
+
# Test creating a full backup
|
361
|
+
response = post("/backup_management/create", {
|
362
|
+
"type" => "full",
|
363
|
+
"description" => "Test full backup from web"
|
364
|
+
})
|
365
|
+
assert_response_redirect(response, "Backup creation should redirect after success")
|
366
|
+
|
367
|
+
# Verify redirect includes success message
|
368
|
+
assert_includes response['Location'], "message=Backup created successfully", "Should redirect with success message"
|
369
|
+
|
370
|
+
# Test accessing backup management page to verify backup was created
|
371
|
+
response = get("/backup_management")
|
372
|
+
assert_response_success(response, "Backup management page should load after backup creation")
|
373
|
+
assert_includes_concise response, "Test full backup from web", "Should show created backup description"
|
374
|
+
assert_includes_concise response, "full", "Should show backup type"
|
375
|
+
assert_includes_concise response, "ago", "Should show human-readable age"
|
376
|
+
end
|
377
|
+
|
378
|
+
# Test incremental backup creation
|
379
|
+
def test_007_incremental_backup_creation
|
380
|
+
start_web_server
|
381
|
+
setup_test_environment
|
382
|
+
|
383
|
+
# Create a full backup first
|
384
|
+
response = post("/backup_management/create", {
|
385
|
+
"type" => "full",
|
386
|
+
"description" => "Initial full backup"
|
387
|
+
})
|
388
|
+
assert_response_redirect(response, "Full backup creation should redirect")
|
389
|
+
|
390
|
+
# Create an incremental backup
|
391
|
+
response = post("/backup_management/create", {
|
392
|
+
"type" => "incr",
|
393
|
+
"description" => "Incremental backup after changes"
|
394
|
+
})
|
395
|
+
assert_response_redirect(response, "Incremental backup creation should redirect")
|
396
|
+
|
397
|
+
# Verify both backups are listed
|
398
|
+
response = get("/backup_management")
|
399
|
+
assert_response_success(response, "Backup management page should load")
|
400
|
+
assert_includes_concise response, "Initial full backup", "Should show full backup"
|
401
|
+
assert_includes_concise response, "Incremental backup after changes", "Should show incremental backup"
|
402
|
+
assert_includes_concise response, "incr", "Should show incremental type"
|
403
|
+
end
|
404
|
+
|
405
|
+
# Test backup creation with empty description
|
406
|
+
def test_008_backup_creation_empty_description
|
407
|
+
start_web_server
|
408
|
+
setup_test_environment
|
409
|
+
|
410
|
+
# Test creating backup with empty description
|
411
|
+
response = post("/backup_management/create", {
|
412
|
+
"type" => "full",
|
413
|
+
"description" => ""
|
414
|
+
})
|
415
|
+
assert_response_redirect(response, "Backup creation should redirect even with empty description")
|
416
|
+
|
417
|
+
# Verify backup was created
|
418
|
+
response = get("/backup_management")
|
419
|
+
assert_response_success(response, "Backup management page should load")
|
420
|
+
assert_includes_concise response, "No description", "Should show no description message"
|
421
|
+
end
|
422
|
+
|
423
|
+
# Test backup creation with invalid type
|
424
|
+
def test_009_backup_creation_invalid_type
|
425
|
+
start_web_server
|
426
|
+
setup_test_environment
|
427
|
+
|
428
|
+
# Test creating backup with invalid type
|
429
|
+
response = post("/backup_management/create", {
|
430
|
+
"type" => "invalid",
|
431
|
+
"description" => "Invalid backup type"
|
432
|
+
})
|
433
|
+
assert_response_redirect(response, "Invalid backup type should redirect with error")
|
434
|
+
|
435
|
+
# Verify error message in redirect
|
436
|
+
assert_includes response['Location'], "error=Invalid backup type", "Should redirect with error message"
|
437
|
+
end
|
438
|
+
|
439
|
+
# Test backup management page with no backups
|
440
|
+
def test_010_backup_management_empty_state
|
441
|
+
start_web_server
|
442
|
+
setup_test_environment
|
443
|
+
|
444
|
+
# Access backup management page with no backups
|
445
|
+
response = get("/backup_management")
|
446
|
+
assert_response_success(response, "Backup management page should load")
|
447
|
+
assert_includes_concise response, "No backups available yet", "Should show empty state message"
|
448
|
+
assert_includes_concise response, "Create your first backup using the form above", "Should show empty state instructions"
|
449
|
+
end
|
450
|
+
|
451
|
+
# Test backup management page styling and UI elements
|
452
|
+
def test_011_backup_management_ui_elements
|
453
|
+
start_web_server
|
454
|
+
setup_test_environment
|
455
|
+
|
456
|
+
# Create a backup first
|
457
|
+
post("/backup_management/create", {
|
458
|
+
"type" => "full",
|
459
|
+
"description" => "UI test backup"
|
460
|
+
})
|
461
|
+
|
462
|
+
# Test UI elements
|
463
|
+
response = get("/backup_management")
|
464
|
+
assert_response_success(response, "Backup management page should load")
|
465
|
+
|
466
|
+
# Check for key UI elements
|
467
|
+
assert_includes_concise response, "backup-form", "Should have backup form styling"
|
468
|
+
assert_includes_concise response, "backups-table", "Should have backups table styling"
|
469
|
+
assert_includes_concise response, "backup-type", "Should have backup type styling"
|
470
|
+
assert_includes_concise response, "backup-age", "Should have backup age styling"
|
471
|
+
assert_includes_concise response, "Back to Dashboard", "Should have back navigation link"
|
472
|
+
end
|
473
|
+
|
474
|
+
# Test backup management page with multiple backups
|
475
|
+
def test_012_backup_management_multiple_backups
|
476
|
+
start_web_server
|
477
|
+
setup_test_environment
|
478
|
+
|
479
|
+
# Create multiple backups
|
480
|
+
post("/backup_management/create", {
|
481
|
+
"type" => "full",
|
482
|
+
"description" => "First backup"
|
483
|
+
})
|
484
|
+
|
485
|
+
sleep(1) # Ensure different timestamps
|
486
|
+
|
487
|
+
post("/backup_management/create", {
|
488
|
+
"type" => "incr",
|
489
|
+
"description" => "Second backup"
|
490
|
+
})
|
491
|
+
|
492
|
+
sleep(1) # Ensure different timestamps
|
493
|
+
|
494
|
+
post("/backup_management/create", {
|
495
|
+
"type" => "full",
|
496
|
+
"description" => "Third backup"
|
497
|
+
})
|
498
|
+
|
499
|
+
# Verify all backups are listed
|
500
|
+
response = get("/backup_management")
|
501
|
+
assert_response_success(response, "Backup management page should load")
|
502
|
+
|
503
|
+
# Check that all backups are present
|
504
|
+
assert_includes_concise response, "First backup", "Should show first backup"
|
505
|
+
assert_includes_concise response, "Second backup", "Should show second backup"
|
506
|
+
assert_includes_concise response, "Third backup", "Should show third backup"
|
507
|
+
|
508
|
+
# Check that backups are sorted by timestamp (newest first)
|
509
|
+
# This is harder to test without parsing the HTML, but we can verify the structure
|
510
|
+
assert_includes_concise response, "backups-table", "Should have backups table"
|
511
|
+
end
|
512
|
+
|
513
|
+
# Test backup management page error handling
|
514
|
+
def test_013_backup_management_error_handling
|
515
|
+
start_web_server
|
516
|
+
setup_test_environment
|
517
|
+
|
518
|
+
# Test accessing backup management without a view (should redirect)
|
519
|
+
# This is harder to test since we need to simulate no current view
|
520
|
+
# For now, just verify the page loads normally with a view
|
521
|
+
response = get("/backup_management")
|
522
|
+
assert_response_success(response, "Backup management page should load with valid view")
|
523
|
+
end
|
524
|
+
|
525
|
+
private
|
526
|
+
# All helper methods are now in WebTestHelper
|
527
|
+
end
|