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
data/test/unit/api.rb
CHANGED
@@ -51,7 +51,24 @@ class TestScriptoriumAPI < Minitest::Test
|
|
51
51
|
assert_equal "test", post.tags
|
52
52
|
end
|
53
53
|
|
54
|
-
def
|
54
|
+
def test_004_create_page
|
55
|
+
@api.create_view("test_view", "Test View")
|
56
|
+
|
57
|
+
page_name = @api.create_page("test_view", "about", "About Us", "This is our about page content.")
|
58
|
+
|
59
|
+
assert_equal "about", page_name
|
60
|
+
|
61
|
+
# Check that the page file was created
|
62
|
+
page_file = "test/scriptorium-TEST/views/test_view/pages/about.lt3"
|
63
|
+
assert File.exist?(page_file), "Page file should exist"
|
64
|
+
|
65
|
+
# Check the content
|
66
|
+
content = read_file(page_file)
|
67
|
+
assert_includes content, ".title About Us"
|
68
|
+
assert_includes content, "This is our about page content."
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_005_posts
|
55
72
|
@api.create_view("test_view", "Test View")
|
56
73
|
@api.create_post("Post 1", "Body 1")
|
57
74
|
@api.create_post("Post 2", "Body 2")
|
@@ -152,10 +169,54 @@ class TestScriptoriumAPI < Minitest::Test
|
|
152
169
|
def test_014_themes_available
|
153
170
|
themes = @api.themes_available
|
154
171
|
assert_instance_of Array, themes
|
155
|
-
|
172
|
+
|
173
|
+
# Should have the standard theme
|
174
|
+
assert_includes themes, "standard"
|
175
|
+
|
176
|
+
# Check system vs user themes
|
177
|
+
system_themes = @api.system_themes
|
178
|
+
user_themes = @api.user_themes
|
179
|
+
|
180
|
+
assert_includes system_themes, "standard"
|
181
|
+
assert_empty user_themes # No user themes yet
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_015_clone_theme
|
185
|
+
# Clone the standard theme
|
186
|
+
result = @api.clone_theme("standard", "my-custom")
|
187
|
+
assert_equal "my-custom", result
|
188
|
+
|
189
|
+
# Check that the new theme exists
|
190
|
+
themes = @api.themes_available
|
191
|
+
assert_includes themes, "my-custom"
|
192
|
+
|
193
|
+
# Check that it's now a user theme
|
194
|
+
user_themes = @api.user_themes
|
195
|
+
assert_includes user_themes, "my-custom"
|
196
|
+
|
197
|
+
# Check that standard is still a system theme
|
198
|
+
system_themes = @api.system_themes
|
199
|
+
assert_includes system_themes, "standard"
|
200
|
+
end
|
201
|
+
|
202
|
+
def test_016_clone_theme_validation
|
203
|
+
# Try to clone to existing theme name
|
204
|
+
assert_raises(ThemeAlreadyExists) do
|
205
|
+
@api.clone_theme("standard", "standard")
|
206
|
+
end
|
207
|
+
|
208
|
+
# Try to clone from non-existent theme
|
209
|
+
assert_raises(ThemeNotFound) do
|
210
|
+
@api.clone_theme("nonexistent", "new-theme")
|
211
|
+
end
|
212
|
+
|
213
|
+
# Try to clone with invalid name
|
214
|
+
assert_raises(ThemeNameInvalid) do
|
215
|
+
@api.clone_theme("standard", "invalid name with spaces")
|
216
|
+
end
|
156
217
|
end
|
157
218
|
|
158
|
-
def
|
219
|
+
def test_017_widgets_available
|
159
220
|
widgets = @api.widgets_available
|
160
221
|
assert_instance_of Array, widgets
|
161
222
|
# Should return available widgets from widgets.txt
|
@@ -185,7 +246,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
185
246
|
# Clear the current view directly
|
186
247
|
@api.repo.instance_variable_set(:@current_view, nil)
|
187
248
|
|
188
|
-
assert_raises(
|
249
|
+
assert_raises(ViewTargetNil) do
|
189
250
|
@api.create_post("Test Post", "Test body")
|
190
251
|
end
|
191
252
|
end
|
@@ -489,12 +550,12 @@ class TestScriptoriumAPI < Minitest::Test
|
|
489
550
|
@api.create_view("test_view", "Test View")
|
490
551
|
|
491
552
|
# Test with non-draft file
|
492
|
-
assert_raises(
|
553
|
+
assert_raises(DraftFileInvalid) do
|
493
554
|
@api.delete_draft("not-a-draft.txt")
|
494
555
|
end
|
495
556
|
|
496
557
|
# Test with non-existent file
|
497
|
-
assert_raises(
|
558
|
+
assert_raises(DraftFileNotFound) do
|
498
559
|
@api.delete_draft("nonexistent-draft.lt3")
|
499
560
|
end
|
500
561
|
end
|
@@ -532,17 +593,17 @@ class TestScriptoriumAPI < Minitest::Test
|
|
532
593
|
@api.create_view("test_view", "Test View")
|
533
594
|
|
534
595
|
# Test with invalid widget name
|
535
|
-
assert_raises(
|
596
|
+
assert_raises(WidgetNameInvalid) do
|
536
597
|
@api.generate_widget("invalid-widget")
|
537
598
|
end
|
538
599
|
|
539
600
|
# Test with nil
|
540
|
-
assert_raises(
|
601
|
+
assert_raises(WidgetNameNil) do
|
541
602
|
@api.generate_widget(nil)
|
542
603
|
end
|
543
604
|
|
544
605
|
# Test with empty string
|
545
|
-
assert_raises(
|
606
|
+
assert_raises(WidgetsArgEmpty) do
|
546
607
|
@api.generate_widget("")
|
547
608
|
end
|
548
609
|
end
|
@@ -551,7 +612,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
551
612
|
@api.create_view("test_view", "Test View")
|
552
613
|
|
553
614
|
# Test with non-existent widget class
|
554
|
-
assert_raises(
|
615
|
+
assert_raises(CannotBuildWidget) do
|
555
616
|
@api.generate_widget("nonexistent")
|
556
617
|
end
|
557
618
|
end
|
@@ -628,7 +689,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
628
689
|
# Create a post so the search actually processes something
|
629
690
|
@api.create_post("Test Post", "Test body")
|
630
691
|
|
631
|
-
assert_raises(
|
692
|
+
assert_raises(UnknownSearchField) do
|
632
693
|
@api.search_posts(unknown_field: "value")
|
633
694
|
end
|
634
695
|
end
|
@@ -723,19 +784,19 @@ class TestScriptoriumAPI < Minitest::Test
|
|
723
784
|
|
724
785
|
# edit_file tests
|
725
786
|
def test_048_edit_file_validation_nil_path
|
726
|
-
assert_raises(
|
787
|
+
assert_raises(EditFilePathNil) do
|
727
788
|
@api.edit_file(nil)
|
728
789
|
end
|
729
790
|
end
|
730
791
|
|
731
792
|
def test_049_edit_file_validation_empty_path
|
732
|
-
assert_raises(
|
793
|
+
assert_raises(EditFilePathEmpty) do
|
733
794
|
@api.edit_file("")
|
734
795
|
end
|
735
796
|
end
|
736
797
|
|
737
798
|
def test_050_edit_file_validation_whitespace_path
|
738
|
-
assert_raises(
|
799
|
+
assert_raises(EditFilePathEmpty) do
|
739
800
|
@api.edit_file(" ")
|
740
801
|
end
|
741
802
|
end
|
@@ -801,7 +862,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
801
862
|
# Clear the current view
|
802
863
|
@api.repo.instance_variable_set(:@current_view, nil)
|
803
864
|
|
804
|
-
assert_raises(
|
865
|
+
assert_raises(ViewTargetNil, "No view specified and no current view set") do
|
805
866
|
@api.edit_layout
|
806
867
|
end
|
807
868
|
end
|
@@ -833,7 +894,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
833
894
|
# Clear the current view
|
834
895
|
@api.repo.instance_variable_set(:@current_view, nil)
|
835
896
|
|
836
|
-
assert_raises(
|
897
|
+
assert_raises(ViewTargetNil, "No view specified and no current view set") do
|
837
898
|
@api.edit_config
|
838
899
|
end
|
839
900
|
end
|
@@ -864,7 +925,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
864
925
|
def test_058_edit_widget_data_nil_widget
|
865
926
|
@api.create_view("test_view", "Test View")
|
866
927
|
|
867
|
-
assert_raises(
|
928
|
+
assert_raises(WidgetNameNil, "Widget name cannot be nil") do
|
868
929
|
@api.edit_widget_data(nil, nil)
|
869
930
|
end
|
870
931
|
end
|
@@ -892,7 +953,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
892
953
|
post = @api.create_post("Test Post", "Test body")
|
893
954
|
|
894
955
|
# Create source.lt3 file to test smart selection
|
895
|
-
source_path = "posts/#{post.num}/source.lt3"
|
956
|
+
source_path = "#{@test_dir}/posts/#{post.num}/source.lt3"
|
896
957
|
write_file(source_path, "Test source content")
|
897
958
|
|
898
959
|
# Mock edit_file to track calls
|
@@ -907,20 +968,18 @@ class TestScriptoriumAPI < Minitest::Test
|
|
907
968
|
@api.create_view("test_view", "Test View")
|
908
969
|
post = @api.create_post("Test Post", "Test body")
|
909
970
|
|
910
|
-
# Ensure source.lt3 doesn't exist
|
911
|
-
source_path = "posts/#{post.num}/source.lt3"
|
971
|
+
# Ensure source.lt3 doesn't exist
|
972
|
+
source_path = "#{@test_dir}/posts/#{post.num}/source.lt3"
|
912
973
|
File.delete(source_path) if File.exist?(source_path)
|
913
974
|
|
914
|
-
#
|
915
|
-
|
916
|
-
@api.stub :edit_file, ->(path) { called_path = path } do
|
975
|
+
# Should raise error since source.lt3 is required
|
976
|
+
assert_raises(RuntimeError) do
|
917
977
|
@api.edit_post(post.id)
|
918
|
-
assert_equal "posts/#{post.num}/body.html", called_path
|
919
978
|
end
|
920
979
|
end
|
921
980
|
|
922
981
|
def test_064_edit_post_nonexistent
|
923
|
-
assert_raises(
|
982
|
+
assert_raises(CannotGetPost) do
|
924
983
|
@api.edit_post(999)
|
925
984
|
end
|
926
985
|
end
|
@@ -948,22 +1007,39 @@ class TestScriptoriumAPI < Minitest::Test
|
|
948
1007
|
|
949
1008
|
def test_069_publish_post_already_published
|
950
1009
|
@api.create_view("test_view", "Test View")
|
1010
|
+
|
1011
|
+
# Set test_view as current view
|
1012
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1013
|
+
|
951
1014
|
post = @api.create_post("Test Post", "Test body")
|
952
1015
|
|
953
1016
|
# Publish once
|
954
1017
|
@api.publish_post(post.id)
|
955
1018
|
|
956
1019
|
# Try to publish again
|
957
|
-
assert_raises(
|
1020
|
+
assert_raises(PostAlreadyPublished, "Post #{post.id} is already published") do
|
958
1021
|
@api.publish_post(post.id)
|
959
1022
|
end
|
960
1023
|
end
|
961
1024
|
|
962
1025
|
def test_070_publish_post_nonexistent
|
963
|
-
assert_raises(
|
1026
|
+
assert_raises(CannotGetPost) do
|
964
1027
|
@api.publish_post(999)
|
965
1028
|
end
|
966
1029
|
end
|
1030
|
+
|
1031
|
+
def test_070_5_unpublish_post
|
1032
|
+
@api.create_view("test_view", "Test View")
|
1033
|
+
post = @api.create_post("Test Post", "Test body")
|
1034
|
+
|
1035
|
+
# Publish the post
|
1036
|
+
@api.publish_post(post.id)
|
1037
|
+
assert @api.post_published?(post.id)
|
1038
|
+
|
1039
|
+
# Unpublish the post
|
1040
|
+
@api.unpublish_post(post.id)
|
1041
|
+
refute @api.post_published?(post.id)
|
1042
|
+
end
|
967
1043
|
|
968
1044
|
def test_071_post_published_status
|
969
1045
|
@api.create_view("test_view", "Test View")
|
@@ -979,7 +1055,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
979
1055
|
assert @api.post_published?(post.id)
|
980
1056
|
end
|
981
1057
|
|
982
|
-
def
|
1058
|
+
def test_072_posts_with_published_parameter
|
983
1059
|
@api.create_view("test_view", "Test View")
|
984
1060
|
|
985
1061
|
# Create multiple posts
|
@@ -988,7 +1064,7 @@ class TestScriptoriumAPI < Minitest::Test
|
|
988
1064
|
post3 = @api.create_post("Post 3", "Body 3")
|
989
1065
|
|
990
1066
|
# Initially no published posts
|
991
|
-
published_posts = @api.
|
1067
|
+
published_posts = @api.posts(published: true)
|
992
1068
|
assert_equal 0, published_posts.length
|
993
1069
|
|
994
1070
|
# Publish two posts
|
@@ -996,33 +1072,296 @@ class TestScriptoriumAPI < Minitest::Test
|
|
996
1072
|
@api.publish_post(post3.id)
|
997
1073
|
|
998
1074
|
# Should have 2 published posts
|
999
|
-
published_posts = @api.
|
1075
|
+
published_posts = @api.posts(published: true)
|
1000
1076
|
assert_equal 2, published_posts.length
|
1001
1077
|
assert_includes published_posts.map(&:id), post1.id
|
1002
1078
|
assert_includes published_posts.map(&:id), post3.id
|
1003
1079
|
refute_includes published_posts.map(&:id), post2.id
|
1004
1080
|
end
|
1005
1081
|
|
1006
|
-
def
|
1082
|
+
def test_073_posts_with_published_parameter_and_view
|
1007
1083
|
@api.create_view("test_view", "Test View")
|
1008
1084
|
@api.create_view("other_view", "Other View")
|
1009
1085
|
|
1086
|
+
# Set test_view as current view
|
1087
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1088
|
+
|
1010
1089
|
# Create posts in different views
|
1011
1090
|
post1 = @api.create_post("Post 1", "Body 1", views: "test_view")
|
1012
1091
|
post2 = @api.create_post("Post 2", "Body 2", views: "other_view")
|
1013
1092
|
|
1014
|
-
# Publish
|
1093
|
+
# Publish post1 in test_view (current view)
|
1015
1094
|
@api.publish_post(post1.id)
|
1016
|
-
@api.publish_post(post2.id)
|
1017
1095
|
|
1018
1096
|
# Get published posts for specific view
|
1019
|
-
test_view_posts = @api.
|
1097
|
+
test_view_posts = @api.posts("test_view", published: true)
|
1020
1098
|
assert_equal 1, test_view_posts.length
|
1021
1099
|
assert_equal post1.id, test_view_posts.first.id
|
1022
1100
|
|
1023
|
-
other_view_posts = @api.
|
1024
|
-
assert_equal
|
1025
|
-
|
1101
|
+
other_view_posts = @api.posts("other_view", published: true)
|
1102
|
+
assert_equal 0, other_view_posts.length # post2 not published
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
def test_073_5_view_specific_publishing
|
1106
|
+
@api.create_view("test_view", "Test View")
|
1107
|
+
@api.create_view("other_view", "Other View")
|
1108
|
+
|
1109
|
+
# Set test_view as current view
|
1110
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1111
|
+
|
1112
|
+
# Create a post that belongs to both views
|
1113
|
+
post = @api.create_post("Test Post", "Test body", views: "test_view other_view")
|
1114
|
+
|
1115
|
+
# Initially unpublished in both views
|
1116
|
+
refute @api.post_published?(post.id, "test_view")
|
1117
|
+
refute @api.post_published?(post.id, "other_view")
|
1118
|
+
|
1119
|
+
# Publish in test_view only (current view)
|
1120
|
+
@api.publish_post(post.id)
|
1121
|
+
|
1122
|
+
# Should be published in test_view, unpublished in other_view
|
1123
|
+
assert @api.post_published?(post.id, "test_view")
|
1124
|
+
refute @api.post_published?(post.id, "other_view")
|
1125
|
+
|
1126
|
+
# Publish in other_view
|
1127
|
+
@api.publish_post(post.id, "other_view")
|
1128
|
+
|
1129
|
+
# Should be published in both views
|
1130
|
+
assert @api.post_published?(post.id, "test_view")
|
1131
|
+
assert @api.post_published?(post.id, "other_view")
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
def test_073_6_deployment_state_management
|
1135
|
+
@api.create_view("test_view", "Test View")
|
1136
|
+
@api.create_view("other_view", "Other View")
|
1137
|
+
|
1138
|
+
# Set test_view as current view
|
1139
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1140
|
+
|
1141
|
+
# Create a post that belongs to both views
|
1142
|
+
post = @api.create_post("Test Post", "Test body", views: "test_view other_view")
|
1143
|
+
|
1144
|
+
# Initially unpublished and undeployed in both views
|
1145
|
+
refute @api.post_published?(post.id, "test_view")
|
1146
|
+
refute @api.post_deployed?(post.id, "test_view")
|
1147
|
+
refute @api.post_published?(post.id, "other_view")
|
1148
|
+
refute @api.post_deployed?(post.id, "other_view")
|
1149
|
+
|
1150
|
+
# Publish in test_view only
|
1151
|
+
@api.publish_post(post.id)
|
1152
|
+
|
1153
|
+
# Should be published but still undeployed in test_view
|
1154
|
+
assert @api.post_published?(post.id, "test_view")
|
1155
|
+
refute @api.post_deployed?(post.id, "test_view")
|
1156
|
+
|
1157
|
+
# Deploy in test_view
|
1158
|
+
@api.mark_post_deployed(post.id)
|
1159
|
+
|
1160
|
+
# Should be published and deployed in test_view
|
1161
|
+
assert @api.post_published?(post.id, "test_view")
|
1162
|
+
assert @api.post_deployed?(post.id, "test_view")
|
1163
|
+
|
1164
|
+
# Should still be unpublished and undeployed in other_view
|
1165
|
+
refute @api.post_published?(post.id, "other_view")
|
1166
|
+
refute @api.post_deployed?(post.id, "other_view")
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
def test_073_7_deployment_state_workflow
|
1170
|
+
@api.create_view("test_view", "Test View")
|
1171
|
+
|
1172
|
+
# Set test_view as current view
|
1173
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1174
|
+
|
1175
|
+
# Create multiple posts
|
1176
|
+
post1 = @api.create_post("Post 1", "Body 1")
|
1177
|
+
post2 = @api.create_post("Post 2", "Body 2")
|
1178
|
+
post3 = @api.create_post("Post 3", "Body 3")
|
1179
|
+
|
1180
|
+
# Initially all posts are unpublished and undeployed
|
1181
|
+
[post1, post2, post3].each do |post|
|
1182
|
+
refute @api.post_published?(post.id)
|
1183
|
+
refute @api.post_deployed?(post.id)
|
1184
|
+
end
|
1185
|
+
|
1186
|
+
# Publish post1 and post3
|
1187
|
+
@api.publish_post(post1.id)
|
1188
|
+
@api.publish_post(post3.id)
|
1189
|
+
|
1190
|
+
# Deploy post1
|
1191
|
+
@api.mark_post_deployed(post1.id)
|
1192
|
+
|
1193
|
+
# Check states
|
1194
|
+
assert @api.post_published?(post1.id)
|
1195
|
+
assert @api.post_deployed?(post1.id)
|
1196
|
+
refute @api.post_published?(post2.id)
|
1197
|
+
refute @api.post_deployed?(post2.id)
|
1198
|
+
assert @api.post_published?(post3.id)
|
1199
|
+
refute @api.post_deployed?(post3.id)
|
1200
|
+
|
1201
|
+
# Get deployed posts
|
1202
|
+
deployed_posts = @api.get_deployed_posts
|
1203
|
+
assert_equal 1, deployed_posts.length
|
1204
|
+
assert_equal post1.id, deployed_posts.first.id
|
1205
|
+
|
1206
|
+
# Mark post1 as undeployed
|
1207
|
+
@api.mark_post_undeployed(post1.id)
|
1208
|
+
refute @api.post_deployed?(post1.id)
|
1209
|
+
|
1210
|
+
# Get deployed posts again
|
1211
|
+
deployed_posts = @api.get_deployed_posts
|
1212
|
+
assert_equal 0, deployed_posts.length
|
1213
|
+
end
|
1214
|
+
|
1215
|
+
def test_073_8_deployment_workflow_integration
|
1216
|
+
@api.create_view("test_view", "Test View")
|
1217
|
+
|
1218
|
+
# Set test_view as current view
|
1219
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1220
|
+
|
1221
|
+
# Create a post (don't publish it yet)
|
1222
|
+
post = @api.create_post("Test Post", "Test body")
|
1223
|
+
|
1224
|
+
# Post should be unpublished and undeployed
|
1225
|
+
refute @api.post_published?(post.id)
|
1226
|
+
refute @api.post_deployed?(post.id)
|
1227
|
+
|
1228
|
+
# Try to deploy unpublished post (should fail)
|
1229
|
+
assert_raises(PostNotPublished) do
|
1230
|
+
@api.mark_post_deployed(post.id)
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
# Now publish the post
|
1234
|
+
@api.publish_post(post.id)
|
1235
|
+
|
1236
|
+
# Post should be published but not deployed
|
1237
|
+
assert @api.post_published?(post.id)
|
1238
|
+
refute @api.post_deployed?(post.id)
|
1239
|
+
|
1240
|
+
# Now deploy the published post
|
1241
|
+
@api.mark_post_deployed(post.id)
|
1242
|
+
|
1243
|
+
# Post should be both published and deployed
|
1244
|
+
assert @api.post_published?(post.id)
|
1245
|
+
assert @api.post_deployed?(post.id)
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
def test_073_9_post_states_display
|
1249
|
+
@api.create_view("test_view", "Test View")
|
1250
|
+
|
1251
|
+
# Set test_view as current view
|
1252
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1253
|
+
|
1254
|
+
# Create multiple posts
|
1255
|
+
post1 = @api.create_post("Post 1", "Body 1")
|
1256
|
+
post2 = @api.create_post("Post 2", "Body 2")
|
1257
|
+
post3 = @api.create_post("Post 3", "Body 3")
|
1258
|
+
|
1259
|
+
# Get initial states
|
1260
|
+
states = @api.get_post_states
|
1261
|
+
assert_equal 3, states.length
|
1262
|
+
|
1263
|
+
# Check initial state (should be "-" for unpublished/undeployed)
|
1264
|
+
assert_equal "-", states[post1.id][:state]
|
1265
|
+
assert_equal "-", states[post2.id][:state]
|
1266
|
+
assert_equal "-", states[post3.id][:state]
|
1267
|
+
|
1268
|
+
# Publish post1
|
1269
|
+
@api.publish_post(post1.id)
|
1270
|
+
states = @api.get_post_states
|
1271
|
+
assert_equal "P", states[post1.id][:state] # Published only
|
1272
|
+
|
1273
|
+
# Deploy post1
|
1274
|
+
@api.mark_post_deployed(post1.id)
|
1275
|
+
states = @api.get_post_states
|
1276
|
+
assert_equal "PD", states[post1.id][:state] # Published and deployed
|
1277
|
+
|
1278
|
+
# Publish post3
|
1279
|
+
@api.publish_post(post3.id)
|
1280
|
+
states = @api.get_post_states
|
1281
|
+
assert_equal "PD", states[post1.id][:state] # Published and deployed
|
1282
|
+
assert_equal "P", states[post3.id][:state] # Published only
|
1283
|
+
assert_equal "-", states[post2.id][:state] # Neither
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
def test_073_10_state_validation_rules
|
1287
|
+
@api.create_view("test_view", "Test View")
|
1288
|
+
|
1289
|
+
# Set test_view as current view
|
1290
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1291
|
+
|
1292
|
+
# Create a post
|
1293
|
+
post = @api.create_post("Test Post", "Test body")
|
1294
|
+
|
1295
|
+
# Test: Cannot publish deleted post
|
1296
|
+
@api.delete_post(post.id)
|
1297
|
+
assert_raises(PostDeleted) do
|
1298
|
+
@api.publish_post(post.id)
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
# Test: Cannot deploy deleted post
|
1302
|
+
assert_raises(PostDeleted) do
|
1303
|
+
@api.mark_post_deployed(post.id)
|
1304
|
+
end
|
1305
|
+
|
1306
|
+
# Test: Cannot unpublish deployed post
|
1307
|
+
@api.undelete_post(post.id)
|
1308
|
+
@api.publish_post(post.id)
|
1309
|
+
@api.mark_post_deployed(post.id)
|
1310
|
+
assert_raises(PostAlreadyDeployed) do
|
1311
|
+
@api.unpublish_post(post.id)
|
1312
|
+
end
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
def test_073_11_delete_undelete_workflow
|
1316
|
+
@api.create_view("test_view", "Test View")
|
1317
|
+
|
1318
|
+
# Set test_view as current view
|
1319
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1320
|
+
|
1321
|
+
# Create a post
|
1322
|
+
post = @api.create_post("Test Post", "Test body")
|
1323
|
+
|
1324
|
+
# Post should not be deleted initially
|
1325
|
+
refute @api.post_deleted?(post.id)
|
1326
|
+
|
1327
|
+
# Delete the post
|
1328
|
+
@api.delete_post(post.id)
|
1329
|
+
assert @api.post_deleted?(post.id)
|
1330
|
+
|
1331
|
+
# Post should be in deleted state (X)
|
1332
|
+
states = @api.get_post_states
|
1333
|
+
assert_equal "X", states[post.id][:state]
|
1334
|
+
|
1335
|
+
# Undelete the post
|
1336
|
+
@api.undelete_post(post.id)
|
1337
|
+
refute @api.post_deleted?(post.id)
|
1338
|
+
|
1339
|
+
# Post should be back to normal state (-)
|
1340
|
+
states = @api.get_post_states
|
1341
|
+
assert_equal "-", states[post.id][:state]
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
def test_073_12_edit_state_transition
|
1345
|
+
@api.create_view("test_view", "Test View")
|
1346
|
+
|
1347
|
+
# Set test_view as current view
|
1348
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
1349
|
+
|
1350
|
+
# Create and publish a post
|
1351
|
+
post = @api.create_post("Test Post", "Test body")
|
1352
|
+
@api.publish_post(post.id)
|
1353
|
+
@api.mark_post_deployed(post.id)
|
1354
|
+
|
1355
|
+
# Post should be published and deployed
|
1356
|
+
assert @api.post_published?(post.id)
|
1357
|
+
assert @api.post_deployed?(post.id)
|
1358
|
+
|
1359
|
+
# Regenerate the post - should reset state to unpublished/undeployed
|
1360
|
+
@api.repo.generate_post(post.id)
|
1361
|
+
|
1362
|
+
# Post should now be unpublished and undeployed (content changed)
|
1363
|
+
refute @api.post_published?(post.id)
|
1364
|
+
refute @api.post_deployed?(post.id)
|
1026
1365
|
end
|
1027
1366
|
|
1028
1367
|
def test_074_create_post_with_generation
|
@@ -1053,4 +1392,385 @@ class TestScriptoriumAPI < Minitest::Test
|
|
1053
1392
|
assert_match /post\.published\s+no/, metadata_content
|
1054
1393
|
refute @api.post_published?(post.id)
|
1055
1394
|
end
|
1395
|
+
|
1396
|
+
def test_999_placeholder
|
1397
|
+
# This test ensures the file has at least one test method
|
1398
|
+
assert true
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
# Asset management tests
|
1402
|
+
|
1403
|
+
def test_1000_list_assets_global
|
1404
|
+
# @api is already set up in setup method
|
1405
|
+
|
1406
|
+
# Create some test assets
|
1407
|
+
write_file("test/scriptorium-TEST/assets/test1.jpg", "Test image 1")
|
1408
|
+
write_file("test/scriptorium-TEST/assets/test2.png", "Test image 2")
|
1409
|
+
|
1410
|
+
assets = @api.list_assets(target: 'global')
|
1411
|
+
|
1412
|
+
assert_equal 3, assets.length
|
1413
|
+
# Check that our test assets are present (imagenotfound.jpg will also be there)
|
1414
|
+
filenames = assets.map { |a| a[:filename] }
|
1415
|
+
assert_includes filenames, "test1.jpg"
|
1416
|
+
assert_includes filenames, "test2.png"
|
1417
|
+
assert_includes filenames, "imagenotfound.jpg"
|
1418
|
+
assert_equal "image", assets[0][:type]
|
1419
|
+
assert assets[0][:size] > 0
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
def test_1001_list_assets_library
|
1423
|
+
# @api is already set up in setup method
|
1424
|
+
|
1425
|
+
# Create library assets
|
1426
|
+
write_file("test/scriptorium-TEST/assets/library/sample1.jpg", "Sample 1")
|
1427
|
+
write_file("test/scriptorium-TEST/assets/library/sample2.txt", "Sample 2")
|
1428
|
+
|
1429
|
+
assets = @api.list_assets(target: 'library')
|
1430
|
+
|
1431
|
+
# There might be existing assets from setup, so check that our test assets are included
|
1432
|
+
assert assets.length >= 2, "Should have at least our 2 test assets"
|
1433
|
+
filenames = assets.map { |a| a[:filename] }
|
1434
|
+
assert_includes filenames, "sample1.jpg"
|
1435
|
+
assert_includes filenames, "sample2.txt"
|
1436
|
+
|
1437
|
+
# Find our specific test assets
|
1438
|
+
sample1 = assets.find { |a| a[:filename] == "sample1.jpg" }
|
1439
|
+
sample2 = assets.find { |a| a[:filename] == "sample2.txt" }
|
1440
|
+
|
1441
|
+
assert_equal "image", sample1[:type]
|
1442
|
+
assert_equal "document", sample2[:type]
|
1443
|
+
end
|
1444
|
+
|
1445
|
+
def test_1002_list_assets_view
|
1446
|
+
# @api is already set up in setup method
|
1447
|
+
@api.create_view("testview", "Test View", "Test Subtitle")
|
1448
|
+
|
1449
|
+
# Create view assets
|
1450
|
+
write_file("test/scriptorium-TEST/views/testview/assets/view1.jpg", "View asset 1")
|
1451
|
+
write_file("test/scriptorium-TEST/views/testview/assets/view2.svg", "View asset 2")
|
1452
|
+
|
1453
|
+
assets = @api.list_assets(target: 'view', view: 'testview')
|
1454
|
+
|
1455
|
+
assert_equal 3, assets.length
|
1456
|
+
# Check that our test assets are present (imagenotfound.jpg will also be there)
|
1457
|
+
filenames = assets.map { |a| a[:filename] }
|
1458
|
+
assert_includes filenames, "view1.jpg"
|
1459
|
+
assert_includes filenames, "view2.svg"
|
1460
|
+
assert_includes filenames, "imagenotfound.jpg"
|
1461
|
+
assert_equal "image", assets[0][:type]
|
1462
|
+
end
|
1463
|
+
|
1464
|
+
def test_1003_list_assets_gem
|
1465
|
+
# @api is already set up in setup method
|
1466
|
+
|
1467
|
+
# Test gem assets (should work in development environment)
|
1468
|
+
assets = @api.list_assets(target: 'gem')
|
1469
|
+
|
1470
|
+
# In development environment, we should find assets from the working directory
|
1471
|
+
# If no gem assets are found, that's also acceptable
|
1472
|
+
if assets.length > 0
|
1473
|
+
assert assets.all? { |asset| asset[:type] == 'image' || asset[:type] == 'other' }
|
1474
|
+
end
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
def test_1004_get_asset_info
|
1478
|
+
# @api is already set up in setup method
|
1479
|
+
|
1480
|
+
# Create test asset
|
1481
|
+
write_file("test/scriptorium-TEST/assets/test_info.jpg", "Test info image")
|
1482
|
+
|
1483
|
+
asset_info = @api.get_asset_info("test_info.jpg", target: 'global')
|
1484
|
+
|
1485
|
+
assert_equal "test_info.jpg", asset_info[:filename]
|
1486
|
+
assert_equal "image", asset_info[:type]
|
1487
|
+
assert asset_info[:size] > 0
|
1488
|
+
assert asset_info[:path].include?("test_info.jpg")
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
def test_1005_asset_exists
|
1492
|
+
# @api is already set up in setup method
|
1493
|
+
|
1494
|
+
# Create test asset
|
1495
|
+
write_file("test/scriptorium-TEST/assets/exists.jpg", "Exists")
|
1496
|
+
|
1497
|
+
assert @api.asset_exists?("exists.jpg", target: 'global')
|
1498
|
+
refute @api.asset_exists?("missing.jpg", target: 'global')
|
1499
|
+
end
|
1500
|
+
|
1501
|
+
def test_1006_copy_asset_global_to_view
|
1502
|
+
# @api is already set up in setup method
|
1503
|
+
@api.create_view("testview", "Test View", "Test Subtitle")
|
1504
|
+
|
1505
|
+
# Create source asset
|
1506
|
+
write_file("test/scriptorium-TEST/assets/source.jpg", "Source image")
|
1507
|
+
|
1508
|
+
# Copy asset
|
1509
|
+
target_path = @api.copy_asset("source.jpg", from: 'global', to: 'view', view: 'testview')
|
1510
|
+
|
1511
|
+
# Verify copy
|
1512
|
+
assert File.exist?(target_path)
|
1513
|
+
assert File.exist?("test/scriptorium-TEST/views/testview/assets/source.jpg")
|
1514
|
+
assert_equal "Source image", read_file("test/scriptorium-TEST/views/testview/assets/source.jpg").chomp
|
1515
|
+
end
|
1516
|
+
|
1517
|
+
def test_1007_copy_asset_gem_to_global
|
1518
|
+
# @api is already set up in setup method
|
1519
|
+
|
1520
|
+
# Find a gem asset to copy
|
1521
|
+
gem_assets = @api.list_assets(target: 'gem')
|
1522
|
+
skip "No gem assets available for testing" if gem_assets.empty?
|
1523
|
+
|
1524
|
+
gem_filename = gem_assets.first[:filename]
|
1525
|
+
|
1526
|
+
# Copy from gem to global
|
1527
|
+
target_path = @api.copy_asset(gem_filename, from: 'gem', to: 'global')
|
1528
|
+
|
1529
|
+
# Verify copy
|
1530
|
+
assert File.exist?(target_path)
|
1531
|
+
assert File.exist?("test/scriptorium-TEST/assets/#{gem_filename}")
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
def test_1008_copy_asset_library_to_view
|
1535
|
+
# @api is already set up in setup method
|
1536
|
+
@api.create_view("testview", "Test View", "Test Subtitle")
|
1537
|
+
|
1538
|
+
# Create library asset
|
1539
|
+
write_file("test/scriptorium-TEST/assets/library/lib.jpg", "Library image")
|
1540
|
+
|
1541
|
+
# Copy to view
|
1542
|
+
target_path = @api.copy_asset("lib.jpg", from: 'library', to: 'view', view: 'testview')
|
1543
|
+
|
1544
|
+
# Verify copy
|
1545
|
+
assert File.exist?(target_path)
|
1546
|
+
assert File.exist?("test/scriptorium-TEST/views/testview/assets/lib.jpg")
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
def test_1009_upload_asset
|
1550
|
+
# @api is already set up in setup method
|
1551
|
+
|
1552
|
+
# Create temporary source file
|
1553
|
+
source_file = "test/temp_source.jpg"
|
1554
|
+
write_file(source_file, "Temporary source image")
|
1555
|
+
|
1556
|
+
# Upload to global
|
1557
|
+
target_path = @api.upload_asset(source_file, target: 'global')
|
1558
|
+
|
1559
|
+
# Verify upload
|
1560
|
+
assert File.exist?(target_path)
|
1561
|
+
assert File.exist?("test/scriptorium-TEST/assets/temp_source.jpg")
|
1562
|
+
assert_equal "Temporary source image", read_file("test/scriptorium-TEST/assets/temp_source.jpg").chomp
|
1563
|
+
|
1564
|
+
# Cleanup
|
1565
|
+
File.delete(source_file)
|
1566
|
+
end
|
1567
|
+
|
1568
|
+
def test_1010_upload_asset_to_view
|
1569
|
+
# @api is already set up in setup method
|
1570
|
+
@api.create_view("testview", "Test View", "Test Subtitle")
|
1571
|
+
|
1572
|
+
# Create temporary source file
|
1573
|
+
source_file = "test/temp_view_source.jpg"
|
1574
|
+
write_file(source_file, "View source image")
|
1575
|
+
|
1576
|
+
# Upload to view
|
1577
|
+
target_path = @api.upload_asset(source_file, target: 'view', view: 'testview')
|
1578
|
+
|
1579
|
+
# Verify upload
|
1580
|
+
assert File.exist?(target_path)
|
1581
|
+
assert File.exist?("test/scriptorium-TEST/views/testview/assets/temp_view_source.jpg")
|
1582
|
+
|
1583
|
+
# Cleanup
|
1584
|
+
File.delete(source_file)
|
1585
|
+
end
|
1586
|
+
|
1587
|
+
def test_1011_delete_asset
|
1588
|
+
# @api is already set up in setup method
|
1589
|
+
|
1590
|
+
# Create test asset
|
1591
|
+
write_file("test/scriptorium-TEST/assets/to_delete.jpg", "Delete me")
|
1592
|
+
|
1593
|
+
# Verify it exists
|
1594
|
+
assert File.exist?("test/scriptorium-TEST/assets/to_delete.jpg")
|
1595
|
+
|
1596
|
+
# Delete it
|
1597
|
+
result = @api.delete_asset("to_delete.jpg", target: 'global')
|
1598
|
+
|
1599
|
+
# Verify deletion
|
1600
|
+
assert result
|
1601
|
+
refute File.exist?("test/scriptorium-TEST/assets/to_delete.jpg")
|
1602
|
+
end
|
1603
|
+
|
1604
|
+
def test_1012_get_asset_path
|
1605
|
+
# @api is already set up in setup method
|
1606
|
+
|
1607
|
+
# Create test asset
|
1608
|
+
write_file("test/scriptorium-TEST/assets/path_test.jpg", "Path test")
|
1609
|
+
|
1610
|
+
# Get path
|
1611
|
+
path = @api.get_asset_path("path_test.jpg", target: 'global')
|
1612
|
+
|
1613
|
+
assert path.include?("path_test.jpg")
|
1614
|
+
assert path.include?("assets")
|
1615
|
+
end
|
1616
|
+
|
1617
|
+
def test_1013_get_asset_dimensions
|
1618
|
+
# @api is already set up in setup method
|
1619
|
+
|
1620
|
+
# Create test image (we'll use a placeholder)
|
1621
|
+
write_file("test/scriptorium-TEST/assets/dimensions.jpg", "Image data")
|
1622
|
+
|
1623
|
+
# Get dimensions (may be nil if FastImage not available)
|
1624
|
+
dimensions = @api.get_asset_dimensions("dimensions.jpg", target: 'global')
|
1625
|
+
|
1626
|
+
# Just verify the method doesn't crash
|
1627
|
+
assert true
|
1628
|
+
end
|
1629
|
+
|
1630
|
+
def test_1014_get_asset_size
|
1631
|
+
# @api is already set up in setup method
|
1632
|
+
|
1633
|
+
# Create test asset
|
1634
|
+
content = "Test content for size measurement"
|
1635
|
+
write_file("test/scriptorium-TEST/assets/size_test.txt", content)
|
1636
|
+
|
1637
|
+
# Get size (write_file adds a newline, so size will be content.length + 1)
|
1638
|
+
size = @api.get_asset_size("size_test.txt", target: 'global')
|
1639
|
+
|
1640
|
+
assert_equal content.length + 1, size
|
1641
|
+
end
|
1642
|
+
|
1643
|
+
def test_1015_get_asset_type
|
1644
|
+
# @api is already set up in setup method
|
1645
|
+
|
1646
|
+
# Test various file types
|
1647
|
+
assert_equal "image", @api.get_asset_type("test.jpg")
|
1648
|
+
assert_equal "image", @api.get_asset_type("test.png")
|
1649
|
+
assert_equal "image", @api.get_asset_type("test.svg")
|
1650
|
+
assert_equal "document", @api.get_asset_type("test.txt")
|
1651
|
+
assert_equal "document", @api.get_asset_type("test.md")
|
1652
|
+
assert_equal "video", @api.get_asset_type("test.mp4")
|
1653
|
+
assert_equal "audio", @api.get_asset_type("test.mp3")
|
1654
|
+
assert_equal "other", @api.get_asset_type("test.xyz")
|
1655
|
+
assert_nil @api.get_asset_type(nil)
|
1656
|
+
end
|
1657
|
+
|
1658
|
+
def test_1016_bulk_copy_assets
|
1659
|
+
# @api is already set up in setup method
|
1660
|
+
@api.create_view("testview", "Test View", "Test Subtitle")
|
1661
|
+
|
1662
|
+
# Create multiple source assets
|
1663
|
+
write_file("test/scriptorium-TEST/assets/bulk1.jpg", "Bulk 1")
|
1664
|
+
write_file("test/scriptorium-TEST/assets/bulk2.png", "Bulk 2")
|
1665
|
+
write_file("test/scriptorium-TEST/assets/bulk3.txt", "Bulk 3")
|
1666
|
+
|
1667
|
+
filenames = ["bulk1.jpg", "bulk2.png", "bulk3.txt"]
|
1668
|
+
|
1669
|
+
# Bulk copy
|
1670
|
+
results = @api.bulk_copy_assets(filenames, from: 'global', to: 'view', view: 'testview')
|
1671
|
+
|
1672
|
+
# Verify results
|
1673
|
+
assert_equal 3, results.length
|
1674
|
+
assert results.all? { |r| r[:success] }
|
1675
|
+
|
1676
|
+
# Verify files were copied
|
1677
|
+
filenames.each do |filename|
|
1678
|
+
assert File.exist?("test/scriptorium-TEST/views/testview/assets/#{filename}")
|
1679
|
+
end
|
1680
|
+
end
|
1681
|
+
|
1682
|
+
def test_1017_copy_asset_invalid_source
|
1683
|
+
# @api is already set up in setup method
|
1684
|
+
|
1685
|
+
# Try to copy from invalid source
|
1686
|
+
assert_raises(InvalidFormatError) do
|
1687
|
+
@api.copy_asset("test.jpg", from: 'invalid', to: 'global')
|
1688
|
+
end
|
1689
|
+
end
|
1690
|
+
|
1691
|
+
def test_1018_copy_asset_invalid_target
|
1692
|
+
# @api is already set up in setup method
|
1693
|
+
|
1694
|
+
# Try to copy to invalid target
|
1695
|
+
assert_raises(InvalidFormatError) do
|
1696
|
+
@api.copy_asset("test.jpg", from: 'global', to: 'invalid')
|
1697
|
+
end
|
1698
|
+
end
|
1699
|
+
|
1700
|
+
def test_1019_copy_asset_source_not_found
|
1701
|
+
# @api is already set up in setup method
|
1702
|
+
|
1703
|
+
# Try to copy non-existent asset
|
1704
|
+
assert_raises(FileNotFoundError) do
|
1705
|
+
@api.copy_asset("missing.jpg", from: 'global', to: 'global')
|
1706
|
+
end
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
def test_1020_list_assets_no_view_specified
|
1710
|
+
# @api is already set up in setup method
|
1711
|
+
|
1712
|
+
# Should work for global assets
|
1713
|
+
assets = @api.list_assets(target: 'global')
|
1714
|
+
assert assets.is_a?(Array)
|
1715
|
+
|
1716
|
+
# Clear the current view to test the error case
|
1717
|
+
@api.repo.instance_variable_set(:@current_view, nil)
|
1718
|
+
|
1719
|
+
# Should fail for view assets without view
|
1720
|
+
assert_raises(ViewTargetNil) do
|
1721
|
+
@api.list_assets(target: 'view')
|
1722
|
+
end
|
1723
|
+
end
|
1724
|
+
|
1725
|
+
def test_999_creates_posts_with_sequential_ids
|
1726
|
+
# Create three posts
|
1727
|
+
post1 = @api.create_post(
|
1728
|
+
"First Post",
|
1729
|
+
"This is the first post content.",
|
1730
|
+
views: "sample",
|
1731
|
+
tags: "test"
|
1732
|
+
)
|
1733
|
+
|
1734
|
+
post2 = @api.create_post(
|
1735
|
+
"Second Post",
|
1736
|
+
"This is the second post content.",
|
1737
|
+
views: "sample",
|
1738
|
+
tags: "test"
|
1739
|
+
)
|
1740
|
+
|
1741
|
+
post3 = @api.create_post(
|
1742
|
+
"Third Post",
|
1743
|
+
"This is the third post content.",
|
1744
|
+
views: "sample",
|
1745
|
+
tags: "test"
|
1746
|
+
)
|
1747
|
+
|
1748
|
+
# Verify they have sequential IDs
|
1749
|
+
assert_equal 1, post1.id, "First post should have ID 1"
|
1750
|
+
assert_equal 2, post2.id, "Second post should have ID 2"
|
1751
|
+
assert_equal 3, post3.id, "Third post should have ID 3"
|
1752
|
+
|
1753
|
+
# Verify the posts exist in the repository
|
1754
|
+
assert_equal "First Post", @api.post(1).title
|
1755
|
+
assert_equal "Second Post", @api.post(2).title
|
1756
|
+
assert_equal "Third Post", @api.post(3).title
|
1757
|
+
end
|
1758
|
+
|
1759
|
+
def test_998_post_counter_is_correctly_updated
|
1760
|
+
# Check initial counter
|
1761
|
+
initial_counter = @api.instance_variable_get(:@repo).last_post_num
|
1762
|
+
assert_equal 0, initial_counter, "Initial counter should be 0"
|
1763
|
+
|
1764
|
+
# Create a post
|
1765
|
+
post = @api.create_post(
|
1766
|
+
"Test Post",
|
1767
|
+
"Test content",
|
1768
|
+
views: "sample"
|
1769
|
+
)
|
1770
|
+
|
1771
|
+
# Check counter after creation
|
1772
|
+
updated_counter = @api.instance_variable_get(:@repo).last_post_num
|
1773
|
+
assert_equal 1, updated_counter, "Counter should be 1 after creating one post"
|
1774
|
+
assert_equal 1, post.id, "Post should have ID 1"
|
1775
|
+
end
|
1056
1776
|
end
|