scriptorium 0.0.3 → 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/README.lt3 +324 -0
- data/README.md +3155 -1
- data/assets/.DS_Store +0 -0
- data/assets/README.md +44 -0
- data/assets/icons/social/reddit.png +0 -0
- data/assets/icons/social/x-logo.png +0 -0
- data/assets/icons/ui/.DS_Store +0 -0
- data/assets/icons/ui/back.png +0 -0
- data/assets/icons/ui/copy.png +0 -0
- data/assets/icons/ui/down.png +0 -0
- data/assets/icons/ui/end.png +0 -0
- data/assets/icons/ui/exit.png +0 -0
- data/assets/icons/ui/foo +10 -0
- data/assets/icons/ui/home.png +0 -0
- data/assets/icons/ui/left.png +0 -0
- data/assets/icons/ui/next.png +0 -0
- data/assets/icons/ui/right.png +0 -0
- data/assets/icons/ui/start.png +0 -0
- data/assets/icons/ui/up.png +0 -0
- data/assets/imagenotfound.jpg +0 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/sblog +84 -5
- data/bin/scriptorium +1 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +94 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +2 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +45 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +35 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +27 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- 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/banner_svg_config.md +114 -0
- data/doc/contrib.lt3 +8 -0
- data/doc/dependencies.md +281 -0
- data/doc/hacker.lt3 +5 -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/myuserdoc/userdoc-toc.txt +88 -0
- 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_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +35 -0
- data/doc/user_guide_section_1.md +137 -0
- data/doc/user_guide_section_10.md +515 -0
- data/doc/user_guide_section_11.md +708 -0
- data/doc/user_guide_section_2.md +233 -0
- data/doc/user_guide_section_3.md +5 -0
- data/doc/user_guide_section_4.md +221 -0
- data/doc/user_guide_section_5.md +243 -0
- data/doc/user_guide_section_6.md +147 -0
- data/doc/user_guide_section_7.md +311 -0
- data/doc/user_guide_section_8.md +224 -0
- data/doc/user_guide_section_9.md +375 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +2373 -0
- data/lib/scriptorium/banner_svg.rb +729 -0
- data/lib/scriptorium/contract.rb +34 -0
- data/lib/scriptorium/exceptions.rb +201 -1
- data/lib/scriptorium/helpers.rb +675 -0
- data/lib/scriptorium/post.rb +259 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +938 -0
- data/lib/scriptorium/standard_files.rb +149 -0
- data/lib/scriptorium/support/bootstrap/css.txt +5 -0
- data/lib/scriptorium/support/bootstrap/js.txt +4 -0
- 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.txt +10 -0
- data/lib/scriptorium/support/config/reddit_template.txt +17 -0
- data/lib/scriptorium/support/config/social.txt +8 -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/lib/scriptorium/support/templates/initial_post.lt3 +12 -0
- data/lib/scriptorium/support/templates/layout.txt +5 -0
- data/lib/scriptorium/support/templates/post.lt3 +104 -0
- data/lib/scriptorium/support/theme/footer.lt3 +2 -0
- data/lib/scriptorium/support/theme/header.lt3 +4 -0
- data/lib/scriptorium/support/theme/left.lt3 +3 -0
- data/lib/scriptorium/support/theme/main.lt3 +5 -0
- data/lib/scriptorium/support/theme/right.lt3 +3 -0
- data/lib/scriptorium/theme.rb +192 -0
- data/lib/scriptorium/version.rb +1 -1
- data/lib/scriptorium/view.rb +1021 -0
- data/lib/scriptorium/widgets/featured_posts.rb +149 -0
- data/lib/scriptorium/widgets/links.rb +112 -0
- data/lib/scriptorium/widgets/pages.rb +133 -0
- data/lib/scriptorium/widgets/widget.rb +133 -0
- data/lib/scriptorium.rb +38 -34
- data/lib/skeleton.rb +10 -1
- data/scriptorium.gemspec +17 -5
- data/test/README.md +69 -0
- data/test/WEB_INTEGRATION_README.md +196 -0
- data/test/all +83 -0
- data/test/api_demo.rb +99 -0
- data/test/assets/imagenotfound.jpg +0 -0
- data/test/assets/images/.DS_Store +0 -0
- data/test/assets/images/README.md +27 -0
- data/test/assets/images/odd_aspect.png +0 -0
- data/test/assets/images/perfect.png +0 -0
- data/test/assets/images/small.png +0 -0
- data/test/assets/images/tall.png +0 -0
- data/test/assets/images/very_tall.png +0 -0
- data/test/assets/images/very_wide.png +0 -0
- data/test/assets/images/wide.png +0 -0
- data/test/assets/testbanner.jpg +0 -0
- data/test/banner_svg/simple_helpers.rb +13 -0
- data/test/banner_svg/unit.rb +1000 -0
- data/test/config/deployment.txt +5 -0
- data/test/ed_test.rb +204 -0
- data/test/integration/cursor_banner_combinations.rb +193 -0
- data/test/integration/cursor_banner_features.rb +374 -0
- data/test/integration/integration_test.rb +326 -0
- data/test/integration/preview_flow_test.rb +94 -0
- data/test/livetext_plugin_test.rb +500 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/svg.txt +3 -0
- data/test/manual/banner-tests/test01.html +122 -0
- data/test/manual/banner-tests/test02.html +122 -0
- data/test/manual/banner-tests/test03.html +122 -0
- data/test/manual/banner-tests/test04.html +129 -0
- data/test/manual/banner-tests/test05.html +129 -0
- data/test/manual/banner-tests/test06.html +129 -0
- data/test/manual/banner-tests/test07.html +129 -0
- data/test/manual/banner-tests/test08.html +123 -0
- data/test/manual/banner-tests/test09.html +123 -0
- data/test/manual/banner-tests/test10.html +123 -0
- data/test/manual/banner-tests/test11.html +123 -0
- data/test/manual/banner-tests/test12.html +123 -0
- data/test/manual/banner-tests/test13.html +123 -0
- data/test/manual/banner-tests/test14.html +123 -0
- data/test/manual/banner-tests/test15.html +122 -0
- data/test/manual/banner-tests/test16.html +122 -0
- data/test/manual/banner-tests/test17.html +122 -0
- data/test/manual/banner-tests/test18.html +132 -0
- data/test/manual/banner-tests/test19.html +132 -0
- data/test/manual/banner-tests/test20.html +132 -0
- data/test/manual/banner-tests/test21.html +132 -0
- data/test/manual/banner-tests/test22.html +132 -0
- data/test/manual/banner-tests/test23.html +132 -0
- data/test/manual/banner-tests/test24.html +132 -0
- data/test/manual/banner-tests/test25.html +131 -0
- data/test/manual/banner_environment.rb +205 -0
- data/test/manual/codemirror_demo.html +773 -0
- data/test/manual/create_posts_for_web.rb +114 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/preview_manual_test.rb +129 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/test_advanced_widgets.rb +73 -0
- data/test/manual/test_banner_combinations.rb +120 -0
- data/test/manual/test_banner_features.rb +306 -0
- data/test/manual/test_banner_integration.rb +115 -0
- data/test/manual/test_banner_radial.rb +87 -0
- data/test/manual/test_basic_posts.rb +47 -0
- data/test/manual/test_layout_widgets.rb +40 -0
- data/test/manual/test_pagination.rb +24 -0
- data/test/manual/test_random_posts.rb +38 -0
- data/test/manual/test_syntax_highlighting.rb +167 -0
- data/test/rubytext/rubytext_comprehensive_test.rb +307 -0
- data/test/rubytext/rubytext_demo_test.rb +42 -0
- data/test/rubytext/rubytext_testing_guide.md +277 -0
- data/test/run_automated_tests.rb +45 -0
- data/test/staging/.DS_Store +0 -0
- data/test/support/preview_utils.rb +88 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_gem_assets.rb +48 -0
- data/test/test_helpers.rb +240 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +883 -0
- data/test/unit/api.rb +1776 -0
- data/test/unit/asset_management.rb +219 -0
- data/test/unit/backup_test.rb +451 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +69 -0
- data/test/unit/core.rb +1211 -0
- data/test/unit/deploy_config_test.rb +248 -0
- data/test/unit/deploy_test.rb +478 -0
- data/test/unit/edit_post_test.rb +168 -0
- data/test/unit/gem_asset_management.rb +183 -0
- data/test/unit/livetext_basic.rb +57 -0
- data/test/unit/livetext_compatibility.rb +82 -0
- data/test/unit/parse_cmd_test.rb +260 -0
- data/test/unit/permalink_copy_test.rb +211 -0
- data/test/unit/post.rb +309 -0
- 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 +278 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +569 -0
- data/test/unit/social_test.rb +366 -0
- data/test/unit/syntax_highlighting.rb +70 -0
- data/test/unit/theme_management_test.rb +91 -0
- data/test/unit/view.rb +498 -0
- data/test/unit/widgets.rb +669 -0
- 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/test/wizard_test.rb +123 -0
- data/ui/README.md +67 -0
- data/ui/common/lib/ui_common.rb +8 -0
- data/ui/rubytext/README.md +191 -0
- data/ui/rubytext/bin/scriptorium-rubytext +402 -0
- data/ui/rubytext/lib/rubytext_ui.rb +300 -0
- data/ui/tui/bin/scriptorium +1890 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +2600 -0
- data/ui/web/app/assets/livetext_mode.js +244 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +196 -0
- data/ui/web/app/views/asset_management.erb +645 -0
- data/ui/web/app/views/backup_management.erb +238 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/config_widget.erb +232 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +154 -0
- data/ui/web/app/views/deploy_config.erb +149 -0
- data/ui/web/app/views/edit_pages.erb +363 -0
- data/ui/web/app/views/edit_post.erb +175 -0
- 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/error_page.erb +29 -0
- data/ui/web/app/views/header_config.erb +155 -0
- data/ui/web/app/views/layout_config.erb +147 -0
- data/ui/web/app/views/navbar_config.erb +411 -0
- data/ui/web/app/views/theme_management.erb +130 -0
- data/ui/web/app/views/view_dashboard.erb +779 -0
- data/ui/web/app/views/widgets.erb +249 -0
- data/ui/web/bin/scriptorium-web +164 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/timing.log +17 -0
- data/ui/web/tmp/web_server.log +0 -0
- metadata +434 -8
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,478 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
|
5
|
+
require_relative '../../lib/scriptorium'
|
6
|
+
require_relative '../test_helpers'
|
7
|
+
|
8
|
+
class TestDeploy < Minitest::Test
|
9
|
+
include Scriptorium::Exceptions
|
10
|
+
include Scriptorium::Helpers
|
11
|
+
include TestHelpers
|
12
|
+
|
13
|
+
def setup
|
14
|
+
# Clean up any existing test directory first
|
15
|
+
test_dir = "test/scriptorium-TEST"
|
16
|
+
FileUtils.rm_rf(test_dir) if Dir.exist?(test_dir)
|
17
|
+
|
18
|
+
@repo = Scriptorium::Repo.create(test_dir, testmode: true)
|
19
|
+
@view = @repo.create_view("testview", "Test View", "Test Subtitle")
|
20
|
+
@api = Scriptorium::API.new(testmode: true)
|
21
|
+
@api.open_repo(@repo.root)
|
22
|
+
end
|
23
|
+
|
24
|
+
def teardown
|
25
|
+
# Clean up any test directories that were created
|
26
|
+
Dir.glob("test/scriptorium-TEST*").each do |dir|
|
27
|
+
system("rm -rf #{dir}")
|
28
|
+
end
|
29
|
+
# Clean up any root directory created during deployment testing
|
30
|
+
# FileUtils.rm_rf("root") if Dir.exist?("root")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_001_deploy_config_file_creation
|
34
|
+
# Test that deploy.txt can be created and read
|
35
|
+
deploy_file = @view.dir/:config/"deploy.txt"
|
36
|
+
write_file(deploy_file, "user@example.com:/var/www/html/")
|
37
|
+
|
38
|
+
assert File.exist?(deploy_file), "Deploy config file should exist"
|
39
|
+
content = read_file(deploy_file)
|
40
|
+
assert_equal "user@example.com:/var/www/html/", content.strip
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_002_deploy_config_validation
|
44
|
+
# Test various deploy config formats
|
45
|
+
deploy_file = @view.dir/:config/"deploy.txt"
|
46
|
+
|
47
|
+
# Valid formats
|
48
|
+
valid_configs = [
|
49
|
+
"user@server:/path/",
|
50
|
+
"user@server.com:/var/www/html/",
|
51
|
+
"deploy@mysite.com:/home/deploy/public_html/"
|
52
|
+
]
|
53
|
+
|
54
|
+
valid_configs.each do |config|
|
55
|
+
write_file(deploy_file, config)
|
56
|
+
content = read_file(deploy_file).strip
|
57
|
+
assert_equal config, content, "Should read config: #{config}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_003_deploy_requires_output_directory
|
62
|
+
# Test that deployment requires output directory to exist
|
63
|
+
deploy_file = @view.dir/:config/"deploy.txt"
|
64
|
+
write_file(deploy_file, "user@server:/path/")
|
65
|
+
|
66
|
+
# Output directory should exist after view creation (created by make_tree)
|
67
|
+
output_dir = @view.dir/:output
|
68
|
+
assert Dir.exist?(output_dir), "Output directory should exist after view creation"
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_004_deploy_rsync_command_format
|
72
|
+
# Test that the rsync command format is correct
|
73
|
+
deploy_config = "user@server:/var/www/html/"
|
74
|
+
output_dir = @view.dir/:output
|
75
|
+
make_dir(output_dir)
|
76
|
+
|
77
|
+
# Expected rsync command format
|
78
|
+
expected_cmd = "rsync -r -z #{output_dir}/ #{deploy_config}/"
|
79
|
+
|
80
|
+
# This is the format used in the TUI
|
81
|
+
actual_cmd = "rsync -r -z #{output_dir}/ #{deploy_config}/"
|
82
|
+
|
83
|
+
assert_equal expected_cmd, actual_cmd, "Rsync command format should match"
|
84
|
+
end
|
85
|
+
|
86
|
+
def test_005_deploy_with_sample_content
|
87
|
+
# Test deployment with actual content
|
88
|
+
deploy_file = @view.dir/:config/"deploy.txt"
|
89
|
+
write_file(deploy_file, "user@server:/path/")
|
90
|
+
|
91
|
+
# Create output directory and some content
|
92
|
+
output_dir = @view.dir/:output
|
93
|
+
make_dir(output_dir)
|
94
|
+
make_dir(output_dir/:posts)
|
95
|
+
make_dir(output_dir/:permalink)
|
96
|
+
|
97
|
+
# Create a sample file
|
98
|
+
sample_file = output_dir/"index.html"
|
99
|
+
write_file(sample_file, "<html><body>Test content</body></html>")
|
100
|
+
|
101
|
+
assert File.exist?(sample_file), "Sample file should exist"
|
102
|
+
assert Dir.exist?(output_dir/:posts), "Posts directory should exist"
|
103
|
+
assert Dir.exist?(output_dir/:permalink), "Permalink directory should exist"
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_006_deploy_marker_file_creation
|
107
|
+
# Test that deployment creates a marker file
|
108
|
+
output_dir = @view.dir/:output
|
109
|
+
|
110
|
+
# Simulate deployment marker creation
|
111
|
+
marker_content = "Deployed: #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
|
112
|
+
marker_file = output_dir/"last-deployed.txt"
|
113
|
+
write_file(marker_file, marker_content)
|
114
|
+
|
115
|
+
assert File.exist?(marker_file), "Deployment marker file should exist"
|
116
|
+
content = read_file(marker_file)
|
117
|
+
assert content.start_with?("Deployed:"), "Marker file should start with 'Deployed:'"
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_007_deploy_with_symlinks
|
121
|
+
# Test that deployment handles symlinks correctly
|
122
|
+
output_dir = @view.dir/:output
|
123
|
+
make_dir(output_dir/:permalink)
|
124
|
+
|
125
|
+
# Create a test symlink
|
126
|
+
target_file = output_dir/:permalink/"0001-test-post.html"
|
127
|
+
symlink_file = output_dir/:permalink/"test-post.html"
|
128
|
+
|
129
|
+
# Create the target file
|
130
|
+
write_file(target_file, "<html><body>Test post</body></html>")
|
131
|
+
|
132
|
+
# Create the copy
|
133
|
+
FileUtils.cp(target_file, symlink_file)
|
134
|
+
|
135
|
+
# Verify copy exists
|
136
|
+
assert File.exist?(symlink_file), "Copy should exist"
|
137
|
+
assert !File.symlink?(symlink_file), "Should not be a symlink"
|
138
|
+
|
139
|
+
# Test that rsync command works with regular files (no symlink preservation needed)
|
140
|
+
expected_cmd = "rsync -r -z #{output_dir}/ user@server:/path/"
|
141
|
+
actual_cmd = "rsync -r -z #{output_dir}/ user@server:/path/"
|
142
|
+
|
143
|
+
assert_equal expected_cmd, actual_cmd, "Rsync command should work with regular files"
|
144
|
+
end
|
145
|
+
|
146
|
+
def test_008_deploy_symlink_target_verification
|
147
|
+
# Test that symlink targets are accessible after deployment
|
148
|
+
output_dir = @view.dir/:output
|
149
|
+
make_dir(output_dir/:permalink)
|
150
|
+
|
151
|
+
# Create a test symlink with target
|
152
|
+
target_file = output_dir/:permalink/"0001-another-post.html"
|
153
|
+
symlink_file = output_dir/:permalink/"another-post.html"
|
154
|
+
|
155
|
+
# Create the target file
|
156
|
+
write_file(target_file, "<html><body>Another test post</body></html>")
|
157
|
+
|
158
|
+
# Create the copy
|
159
|
+
FileUtils.cp(target_file, symlink_file)
|
160
|
+
|
161
|
+
# Verify copy exists and has same content
|
162
|
+
assert File.exist?(symlink_file), "Copy should exist"
|
163
|
+
assert !File.symlink?(symlink_file), "Should not be a symlink"
|
164
|
+
|
165
|
+
# Verify copy has same content as target
|
166
|
+
copy_content = File.read(symlink_file)
|
167
|
+
target_content = File.read(target_file)
|
168
|
+
assert_equal target_content, copy_content, "Copy should have same content as target"
|
169
|
+
end
|
170
|
+
|
171
|
+
def test_009_domain_extraction_from_deploy_config
|
172
|
+
# Test domain extraction from various deploy config formats
|
173
|
+
test_cases = [
|
174
|
+
["user@example.com:/var/www/html/", "example.com"],
|
175
|
+
["deploy@mysite.com:/home/deploy/public_html/", "mysite.com"],
|
176
|
+
["admin@blog.example.org:/srv/www/", "blog.example.org"]
|
177
|
+
]
|
178
|
+
|
179
|
+
test_cases.each do |config, expected_domain|
|
180
|
+
# Simulate the domain extraction logic
|
181
|
+
domain = nil
|
182
|
+
if config =~ /@([^:]+):/
|
183
|
+
domain = $1
|
184
|
+
end
|
185
|
+
|
186
|
+
assert_equal expected_domain, domain, "Should extract domain from: #{config}"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_010_deploy_verification_url_format
|
191
|
+
# Test that verification URL is correctly formatted
|
192
|
+
domain = "example.com"
|
193
|
+
expected_url = "https://#{domain}/last-deployed.txt"
|
194
|
+
|
195
|
+
assert_equal "https://example.com/last-deployed.txt", expected_url, "Verification URL should be correctly formatted"
|
196
|
+
end
|
197
|
+
|
198
|
+
# New API deployment method tests
|
199
|
+
|
200
|
+
def test_011_can_deploy_status_check
|
201
|
+
# Test can_deploy? with various status configurations
|
202
|
+
|
203
|
+
# Test with deploy status 'n' (should fail)
|
204
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
205
|
+
write_file(status_file, "deploy n")
|
206
|
+
|
207
|
+
refute @api.can_deploy?("testview"), "Should not deploy when status is 'n'"
|
208
|
+
|
209
|
+
# Test with deploy status 'y' (should pass status check)
|
210
|
+
write_file(status_file, "deploy y")
|
211
|
+
|
212
|
+
# This will still fail because deploy.txt doesn't exist, but status check passes
|
213
|
+
refute @api.can_deploy?("testview"), "Should fail when deploy.txt is missing"
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_012_can_deploy_config_validation
|
217
|
+
# Test can_deploy? with various deploy.txt configurations
|
218
|
+
|
219
|
+
# Set deploy status to 'y'
|
220
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
221
|
+
write_file(status_file, "deploy y")
|
222
|
+
|
223
|
+
# Test with missing deploy.txt
|
224
|
+
refute @api.can_deploy?("testview"), "Should fail when deploy.txt is missing"
|
225
|
+
|
226
|
+
# Test with incomplete deploy.txt
|
227
|
+
deploy_file = @repo.root/"views"/"testview"/"config"/"deploy.txt"
|
228
|
+
write_file(deploy_file, "user root\nserver example.com")
|
229
|
+
|
230
|
+
refute @api.can_deploy?("testview"), "Should fail when required fields are missing"
|
231
|
+
|
232
|
+
# Test with complete deploy.txt
|
233
|
+
write_file(deploy_file, "user root\nserver.example.com\ndocroot /var/www/html\npath testview")
|
234
|
+
|
235
|
+
# This will fail SSH test, but we'll skip that for now
|
236
|
+
# The method should at least pass the config validation
|
237
|
+
begin
|
238
|
+
result = @api.can_deploy?("testview")
|
239
|
+
# If SSH test passes, result should be true
|
240
|
+
# If SSH test fails, result should be false
|
241
|
+
assert result == false || result == true, "Should return boolean result"
|
242
|
+
rescue => e
|
243
|
+
# SSH test might fail, which is expected in test environment
|
244
|
+
skip "SSH test failed (expected in test environment): #{e.message}"
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
def test_013_deploy_dry_run_mode
|
249
|
+
# Test deploy method in dry-run mode
|
250
|
+
|
251
|
+
# Set up deployment configuration
|
252
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
253
|
+
write_file(status_file, "deploy y")
|
254
|
+
|
255
|
+
deploy_file = @repo.root/"views"/"testview"/"config"/"deploy.txt"
|
256
|
+
write_file(deploy_file, "user root\nserver.example.com\ndocroot /var/www/html\npath testview")
|
257
|
+
|
258
|
+
# Create some output content
|
259
|
+
output_dir = @repo.root/"views"/"testview"/"output"
|
260
|
+
make_dir(output_dir)
|
261
|
+
write_file(output_dir/"index.html", "<html><body>Test content</body></html>")
|
262
|
+
|
263
|
+
# Test that the deploy method can be called (deployment test will fail, but that's expected)
|
264
|
+
begin
|
265
|
+
result = @api.deploy("testview", dry_run: true)
|
266
|
+
assert result, "Dry-run should succeed"
|
267
|
+
rescue DeploymentNotReady => e
|
268
|
+
# Deployment not ready, which is expected in test environment
|
269
|
+
skip "Deployment not ready (expected in test environment): #{e.message}"
|
270
|
+
rescue => e
|
271
|
+
raise e
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_014_deploy_missing_configuration
|
276
|
+
# Test deploy method with missing configuration
|
277
|
+
|
278
|
+
# Test with no status file
|
279
|
+
assert_raises(DeploymentNotReady, "Should fail when status is not ready") do
|
280
|
+
@api.deploy("testview")
|
281
|
+
end
|
282
|
+
|
283
|
+
# Test with deploy status 'n'
|
284
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
285
|
+
write_file(status_file, "deploy n")
|
286
|
+
|
287
|
+
assert_raises(DeploymentNotReady, "Should fail when status is not ready") do
|
288
|
+
@api.deploy("testview")
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
def test_015_deploy_invalid_configuration
|
293
|
+
# Test deploy method with invalid configuration
|
294
|
+
|
295
|
+
# Set deploy status to 'y'
|
296
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
297
|
+
write_file(status_file, "deploy y")
|
298
|
+
|
299
|
+
# Test with missing deploy.txt
|
300
|
+
assert_raises(DeploymentNotReady, "Should fail when deploy.txt is missing") do
|
301
|
+
@api.deploy("testview")
|
302
|
+
end
|
303
|
+
|
304
|
+
# Test with incomplete deploy.txt
|
305
|
+
deploy_file = @repo.root/"views"/"testview"/"config"/"deploy.txt"
|
306
|
+
write_file(deploy_file, "user root\nserver example.com")
|
307
|
+
|
308
|
+
assert_raises(DeploymentNotReady, "Should fail when required fields are missing") do
|
309
|
+
@api.deploy("testview")
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def test_016_deploy_rsync_command_construction
|
314
|
+
# Test that deploy method constructs correct rsync command
|
315
|
+
|
316
|
+
# Set up deployment configuration
|
317
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
318
|
+
write_file(status_file, "deploy y")
|
319
|
+
|
320
|
+
deploy_file = @repo.root/"views"/"testview"/"config"/"deploy.txt"
|
321
|
+
write_file(deploy_file, "user root\nserver example.com\ndocroot /var/www/html\npath testview")
|
322
|
+
|
323
|
+
# Create output content
|
324
|
+
output_dir = @repo.root/"views"/"testview"/"output"
|
325
|
+
make_dir(output_dir)
|
326
|
+
write_file(output_dir/"index.html", "<html><body>Test content</body></html>")
|
327
|
+
|
328
|
+
# Test dry-run to see the command that would be executed
|
329
|
+
begin
|
330
|
+
result = @api.deploy("testview", dry_run: true)
|
331
|
+
assert result, "Dry-run should succeed"
|
332
|
+
rescue DeploymentNotReady => e
|
333
|
+
# Deployment not ready, which is expected in test environment
|
334
|
+
skip "Deployment not ready (expected in test environment): #{e.message}"
|
335
|
+
rescue => e
|
336
|
+
raise e
|
337
|
+
end
|
338
|
+
|
339
|
+
# The dry-run should output the rsync command to stdout
|
340
|
+
# We can't easily capture this in the test, but we can verify the method runs
|
341
|
+
# The actual command format is: "rsync -r -z -l #{output_dir}/ #{remote_path}/"
|
342
|
+
end
|
343
|
+
|
344
|
+
|
345
|
+
|
346
|
+
def test_018_deploy_ssh_keys_test
|
347
|
+
# Test SSH key validation (will likely be skipped in test environment)
|
348
|
+
|
349
|
+
# Set up deployment configuration
|
350
|
+
status_file = @repo.root/"views"/"testview"/"config"/"status.txt"
|
351
|
+
write_file(status_file, "deploy y")
|
352
|
+
|
353
|
+
deploy_file = @repo.root/"views"/"testview"/"config"/"deploy.txt"
|
354
|
+
write_file(deploy_file, "user root\nserver example.com\ndocroot /var/www/html\npath testview")
|
355
|
+
|
356
|
+
# Test SSH key validation
|
357
|
+
begin
|
358
|
+
result = @api.can_deploy?("testview")
|
359
|
+
# This might pass or fail depending on SSH configuration
|
360
|
+
assert result == false || result == true, "Should return boolean result"
|
361
|
+
rescue => e
|
362
|
+
# SSH test might fail, which is expected in test environment
|
363
|
+
skip "SSH test failed (expected in test environment): #{e.message}"
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def test_020_deploy_config_parsing
|
368
|
+
# Test various deployment config formats
|
369
|
+
test_cases = [
|
370
|
+
# Valid space-separated format
|
371
|
+
{
|
372
|
+
input: "user root\nserver example.com\npath sample",
|
373
|
+
expected: {"user" => "root", "server" => "example.com", "path" => "sample"},
|
374
|
+
description: "valid space-separated format"
|
375
|
+
},
|
376
|
+
# Config with comments
|
377
|
+
{
|
378
|
+
input: "# This is a comment\nuser root\nserver example.com\npath sample",
|
379
|
+
expected: {"user" => "root", "server" => "example.com", "path" => "sample"},
|
380
|
+
description: "config with comments"
|
381
|
+
},
|
382
|
+
# Missing required fields
|
383
|
+
{
|
384
|
+
input: "user root\nserver example.com",
|
385
|
+
expected: {"user" => "root", "server" => "example.com"},
|
386
|
+
description: "missing path field"
|
387
|
+
},
|
388
|
+
# Empty config
|
389
|
+
{
|
390
|
+
input: "",
|
391
|
+
expected: {},
|
392
|
+
description: "empty config"
|
393
|
+
},
|
394
|
+
# Config with junk lines
|
395
|
+
{
|
396
|
+
input: "user root\njunk line here\nserver example.com\npath sample",
|
397
|
+
expected: {"user" => "root", "junk" => "line here", "server" => "example.com", "path" => "sample"},
|
398
|
+
description: "config with junk lines"
|
399
|
+
},
|
400
|
+
# Config with extra whitespace
|
401
|
+
{
|
402
|
+
input: " user root \n server example.com \n path sample ",
|
403
|
+
expected: {"user" => "root", "server" => "example.com", "path" => "sample"},
|
404
|
+
description: "config with extra whitespace"
|
405
|
+
}
|
406
|
+
]
|
407
|
+
|
408
|
+
test_cases.each do |test_case|
|
409
|
+
result = @api.parse_deploy_config(test_case[:input])
|
410
|
+
assert_equal test_case[:expected], result,
|
411
|
+
"Failed for #{test_case[:description]}: expected '#{test_case[:expected]}', got '#{result}'"
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
def test_020b_build_rsync_destination
|
416
|
+
# Test building rsync destinations from config hashes
|
417
|
+
test_cases = [
|
418
|
+
{
|
419
|
+
config: {"user" => "root", "server" => "example.com", "path" => "sample"},
|
420
|
+
expected: "root@example.com:sample",
|
421
|
+
description: "complete config"
|
422
|
+
},
|
423
|
+
{
|
424
|
+
config: {"user" => "root", "server" => "example.com"},
|
425
|
+
expected: nil,
|
426
|
+
description: "missing path"
|
427
|
+
},
|
428
|
+
{
|
429
|
+
config: {},
|
430
|
+
expected: nil,
|
431
|
+
description: "empty config"
|
432
|
+
}
|
433
|
+
]
|
434
|
+
|
435
|
+
test_cases.each do |test_case|
|
436
|
+
result = @api.build_rsync_destination(test_case[:config])
|
437
|
+
if test_case[:expected].nil?
|
438
|
+
assert_nil result, "Failed for #{test_case[:description]}: expected nil, got '#{result}'"
|
439
|
+
else
|
440
|
+
assert_equal test_case[:expected], result,
|
441
|
+
"Failed for #{test_case[:description]}: expected '#{test_case[:expected]}', got '#{result}'"
|
442
|
+
end
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
|
447
|
+
|
448
|
+
def test_022_deploy_config_edge_cases
|
449
|
+
# Test edge cases that could cause issues
|
450
|
+
edge_cases = [
|
451
|
+
# Config with only junk
|
452
|
+
{
|
453
|
+
input: "this is not a config\nneither is this\nor this",
|
454
|
+
expected: {"this" => "is not a config", "neither" => "is this", "or" => "this"},
|
455
|
+
description: "only junk lines"
|
456
|
+
},
|
457
|
+
# Config with empty lines
|
458
|
+
{
|
459
|
+
input: "user root\n\nserver example.com\n\npath sample\n",
|
460
|
+
expected: {"user" => "root", "server" => "example.com", "path" => "sample"},
|
461
|
+
description: "config with empty lines"
|
462
|
+
},
|
463
|
+
# Config with special characters
|
464
|
+
{
|
465
|
+
input: "user root\nserver example.com\npath /var/www/html",
|
466
|
+
expected: {"user" => "root", "server" => "example.com", "path" => "/var/www/html"},
|
467
|
+
description: "path with special characters"
|
468
|
+
}
|
469
|
+
]
|
470
|
+
|
471
|
+
edge_cases.each do |test_case|
|
472
|
+
result = @api.parse_deploy_config(test_case[:input])
|
473
|
+
assert_equal test_case[:expected], result,
|
474
|
+
"Failed for #{test_case[:description]}: expected '#{test_case[:expected]}', got '#{result}'"
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
end
|
@@ -0,0 +1,168 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../../lib/scriptorium'
|
3
|
+
require_relative '../test_helpers'
|
4
|
+
|
5
|
+
class TestEditPost < Minitest::Test
|
6
|
+
include TestHelpers
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@test_dir = "test/scriptorium-TEST"
|
10
|
+
FileUtils.rm_rf(@test_dir) if Dir.exist?(@test_dir)
|
11
|
+
|
12
|
+
@api = Scriptorium::API.new(testmode: true)
|
13
|
+
@api.create_repo(@test_dir)
|
14
|
+
@api.open_repo(@test_dir)
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
FileUtils.rm_rf(@test_dir) if Dir.exist?(@test_dir)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_001_edit_post_no_changes
|
22
|
+
@api.create_view("test_view", "Test View")
|
23
|
+
post = @api.create_post("Test Post", "Test body")
|
24
|
+
|
25
|
+
# Initially unpublished and undeployed
|
26
|
+
refute @api.post_published?(post.id)
|
27
|
+
refute @api.post_deployed?(post.id)
|
28
|
+
|
29
|
+
# Mock the editor by not changing the file content
|
30
|
+
# (file content remains the same, so checksum will be identical)
|
31
|
+
|
32
|
+
# Call edit_post with mock (should detect no changes)
|
33
|
+
@api.edit_post(post.id, mock: true)
|
34
|
+
|
35
|
+
# State should remain unchanged
|
36
|
+
refute @api.post_published?(post.id)
|
37
|
+
refute @api.post_deployed?(post.id)
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_002_edit_post_with_changes
|
41
|
+
@api.create_view("test_view", "Test View")
|
42
|
+
post = @api.create_post("Test Post", "Test body")
|
43
|
+
|
44
|
+
# Initially unpublished and undeployed
|
45
|
+
refute @api.post_published?(post.id)
|
46
|
+
refute @api.post_deployed?(post.id)
|
47
|
+
|
48
|
+
# Mock the editor by simulating a different checksum
|
49
|
+
@api.edit_post(post.id, mock: [:checksum, "different_checksum_for_testing"])
|
50
|
+
|
51
|
+
# State should remain unchanged since it was already unpublished/undeployed
|
52
|
+
refute @api.post_published?(post.id)
|
53
|
+
refute @api.post_deployed?(post.id)
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_003_edit_post_published_post
|
57
|
+
@api.create_view("test_view", "Test View")
|
58
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
59
|
+
|
60
|
+
post = @api.create_post("Test Post", "Test body")
|
61
|
+
|
62
|
+
# Publish the post
|
63
|
+
@api.publish_post(post.id)
|
64
|
+
assert @api.post_published?(post.id)
|
65
|
+
|
66
|
+
# Mock the editor by simulating a different checksum
|
67
|
+
@api.edit_post(post.id, mock: [:checksum, "different_checksum_for_testing"])
|
68
|
+
|
69
|
+
# Post should now be unpublished
|
70
|
+
refute @api.post_published?(post.id)
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_004_edit_post_deployed_post
|
74
|
+
@api.create_view("test_view", "Test View")
|
75
|
+
@api.repo.instance_variable_set(:@current_view, @api.repo.lookup_view("test_view"))
|
76
|
+
|
77
|
+
post = @api.create_post("Test Post", "Test body")
|
78
|
+
|
79
|
+
# Publish and deploy the post
|
80
|
+
@api.publish_post(post.id)
|
81
|
+
@api.mark_post_deployed(post.id)
|
82
|
+
assert @api.post_published?(post.id)
|
83
|
+
assert @api.post_deployed?(post.id)
|
84
|
+
|
85
|
+
# Mock the editor by simulating a different checksum
|
86
|
+
@api.edit_post(post.id, mock: [:checksum, "different_checksum_for_testing"])
|
87
|
+
|
88
|
+
# Post should now be unpublished and undeployed
|
89
|
+
refute @api.post_published?(post.id)
|
90
|
+
refute @api.post_deployed?(post.id)
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_005_edit_post_multiple_views
|
94
|
+
@api.create_view("test_view", "Test View")
|
95
|
+
@api.create_view("other_view", "Other View")
|
96
|
+
|
97
|
+
post = @api.create_post("Test Post", "Test body", views: "test_view other_view")
|
98
|
+
|
99
|
+
# Publish in both views
|
100
|
+
@api.publish_post(post.id, "test_view")
|
101
|
+
@api.publish_post(post.id, "other_view")
|
102
|
+
@api.mark_post_deployed(post.id, "test_view")
|
103
|
+
@api.mark_post_deployed(post.id, "other_view")
|
104
|
+
|
105
|
+
assert @api.post_published?(post.id, "test_view")
|
106
|
+
assert @api.post_published?(post.id, "other_view")
|
107
|
+
assert @api.post_deployed?(post.id, "test_view")
|
108
|
+
assert @api.post_deployed?(post.id, "other_view")
|
109
|
+
|
110
|
+
# Mock the editor by simulating a different checksum
|
111
|
+
@api.edit_post(post.id, mock: [:checksum, "different_checksum_for_testing"])
|
112
|
+
|
113
|
+
# Post should now be unpublished and undeployed in both views
|
114
|
+
|
115
|
+
refute @api.post_published?(post.id, "test_view")
|
116
|
+
refute @api.post_published?(post.id, "other_view")
|
117
|
+
refute @api.post_deployed?(post.id, "test_view")
|
118
|
+
refute @api.post_deployed?(post.id, "other_view")
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_006_edit_post_timestamp_change_only
|
122
|
+
@api.create_view("test_view", "Test View")
|
123
|
+
post = @api.create_post("Test Post", "Test body")
|
124
|
+
|
125
|
+
# Initially unpublished and undeployed
|
126
|
+
refute @api.post_published?(post.id)
|
127
|
+
refute @api.post_deployed?(post.id)
|
128
|
+
|
129
|
+
# Mock the editor by simulating no content changes (same checksum)
|
130
|
+
@api.edit_post(post.id, mock: [:checksum, Digest::MD5.file("#{@test_dir}/posts/#{post.num}/source.lt3").hexdigest])
|
131
|
+
|
132
|
+
# State should remain unchanged since content didn't change
|
133
|
+
refute @api.post_published?(post.id)
|
134
|
+
refute @api.post_deployed?(post.id)
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_007_edit_post_missing_source
|
138
|
+
@api.create_view("test_view", "Test View")
|
139
|
+
post = @api.create_post("Test Post", "Test body")
|
140
|
+
|
141
|
+
# Remove source.lt3 to test error handling
|
142
|
+
source_path = "#{@test_dir}/posts/#{post.num}/source.lt3"
|
143
|
+
File.delete(source_path) if File.exist?(source_path)
|
144
|
+
|
145
|
+
# Ensure body.html exists
|
146
|
+
body_path = "#{@test_dir}/posts/#{post.num}/body.html"
|
147
|
+
assert File.exist?(body_path)
|
148
|
+
|
149
|
+
# Call edit_post should raise error since source.lt3 is missing
|
150
|
+
assert_raises(RuntimeError) do
|
151
|
+
@api.edit_post(post.id, mock: true)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_008_edit_post_deleted_post
|
156
|
+
@api.create_view("test_view", "Test View")
|
157
|
+
post = @api.create_post("Test Post", "Test body")
|
158
|
+
|
159
|
+
# Delete the post
|
160
|
+
@api.delete_post(post.id)
|
161
|
+
assert @api.post_deleted?(post.id)
|
162
|
+
|
163
|
+
# Try to edit deleted post
|
164
|
+
assert_raises(PostDeleted) do
|
165
|
+
@api.edit_post(post.id, mock: true)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|