scriptorium 0.0.3 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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/back-icon.png +0 -0
- data/assets/icons/facebook.svg +1 -0
- data/assets/icons/github.svg +1 -0
- data/assets/icons/instagram.svg +1 -0
- data/assets/icons/reddit.svg +1 -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/icons/x.svg +1 -0
- data/assets/icons/youtube.svg +1 -0
- data/assets/samples/placeholder.svg +9 -0
- data/assets/themes/standard/favicon.svg +6 -0
- data/bin/scriptorium +1511 -0
- data/doc/README.txt +6 -0
- data/doc/anti-amnesia/20250727-054000-scriptorium-overview.md +95 -0
- data/doc/anti-amnesia/20250727-060000-api-design-tui-planning.md +34 -0
- data/doc/anti-amnesia/20250727-061000-runeblog-tui-analysis.md +50 -0
- data/doc/anti-amnesia/20250727-123000-anti-amnesia-conventions.md +31 -0
- data/doc/anti-amnesia/20250727-154000-livetext-plugin-file-stats.md +73 -0
- data/doc/anti-amnesia/20250727-172600-cursor-rbenv-ruby-version-mystery.md +64 -0
- data/doc/anti-amnesia/20250727-172600-unified-minitest-framework.md +70 -0
- data/doc/anti-amnesia/20250727-172900-ai-cognitive-assessment-capabilities.md +40 -0
- data/doc/anti-amnesia/20250727-173000-widget-testing-achievement.md +110 -0
- data/doc/anti-amnesia/20250727-180000-post-id-num-refactoring.md +73 -0
- data/doc/anti-amnesia/20250728-124243-aaa-syntax-clarification.md +46 -0
- data/doc/anti-amnesia/20250728-124421-conversation-summary-concise.md +124 -0
- data/doc/anti-amnesia/20250729-190000-scriptorium-tui-testing-complete.md +46 -0
- data/doc/anti-amnesia/20250729-200000-scriptorium-tui-testing-edit-file-workflow.md +97 -0
- data/doc/anti-amnesia/20250729-210000-reddit-autopost-integration-complete.md +158 -0
- data/doc/anti-amnesia/20250729-211500-dependency-management-system.md +211 -0
- data/doc/anti-amnesia/20250729-213000-python-virtual-environment-setup.md +141 -0
- data/doc/anti-amnesia/20250729-214500-theme-management-commands.md +211 -0
- data/doc/anti-amnesia/20250729-215000-version-update-to-0.6.0.md +134 -0
- data/doc/anti-amnesia/20250729-220000-user-guide-complete.md +41 -0
- data/doc/anti-amnesia/20250804-190500-cognitive-loop-bug.md +45 -0
- data/doc/anti-amnesia/20250804-190700-anti-amnesia-timestamping-fix.md +30 -0
- data/doc/anti-amnesia/20250804-213700-publishing-test-fix.md +49 -0
- data/doc/anti-amnesia/20250804-214400-additional-test-fixes.md +46 -0
- data/doc/anti-amnesia/20250804-220000-asset-function-logic-clarification.md +41 -0
- data/doc/anti-amnesia/20250806-202032-asset-function-logic-clarification.md +41 -0
- data/doc/anti-amnesia/20250807-213025.md +116 -0
- data/doc/anti-amnesia/20250813-082428-syntax-highlighting-and-navigation-improvements.md +256 -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/reddit_credentials_template.json +8 -0
- data/doc/reddit_integration.md +207 -0
- data/doc/user.lt3 +38 -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/doc/userdoc-toc.txt +88 -0
- data/lib/rouge/lexers/livetext.rb +74 -0
- data/lib/scriptorium/api.rb +640 -0
- data/lib/scriptorium/banner_svg.rb +742 -0
- data/lib/scriptorium/contract.rb +33 -0
- data/lib/scriptorium/exceptions.rb +170 -1
- data/lib/scriptorium/helpers.rb +475 -0
- data/lib/scriptorium/post.rb +195 -0
- data/lib/scriptorium/reddit.rb +83 -0
- data/lib/scriptorium/repo.rb +624 -0
- data/lib/scriptorium/standard_files.rb +515 -0
- data/lib/scriptorium/syntax_highlighter.rb +234 -0
- data/lib/scriptorium/theme.rb +179 -0
- data/lib/scriptorium/version.rb +2 -2
- data/lib/scriptorium/view.rb +976 -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 +21 -40
- data/lib/skeleton.rb +8 -2
- data/scriptorium.gemspec +15 -4
- data/test/README.md +69 -0
- data/test/all +43 -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 +768 -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/livetext_plugin_test.rb +229 -0
- data/test/manual/asset_mgmt.rb +67 -0
- data/test/manual/banner-tests/config.txt +3 -0
- data/test/manual/banner-tests/index.html +45 -0
- data/test/manual/banner-tests/test01.html +58 -0
- data/test/manual/banner-tests/test02.html +58 -0
- data/test/manual/banner-tests/test03.html +58 -0
- data/test/manual/banner-tests/test04.html +65 -0
- data/test/manual/banner-tests/test05.html +65 -0
- data/test/manual/banner-tests/test06.html +65 -0
- data/test/manual/banner-tests/test07.html +65 -0
- data/test/manual/banner-tests/test08.html +59 -0
- data/test/manual/banner-tests/test09.html +59 -0
- data/test/manual/banner-tests/test10.html +59 -0
- data/test/manual/banner-tests/test11.html +59 -0
- data/test/manual/banner-tests/test12.html +59 -0
- data/test/manual/banner-tests/test13.html +59 -0
- data/test/manual/banner-tests/test14.html +59 -0
- data/test/manual/banner-tests/test15.html +58 -0
- data/test/manual/banner-tests/test16.html +58 -0
- data/test/manual/banner-tests/test17.html +58 -0
- data/test/manual/banner-tests/test18.html +68 -0
- data/test/manual/banner-tests/test19.html +68 -0
- data/test/manual/banner-tests/test20.html +68 -0
- data/test/manual/banner-tests/test21.html +68 -0
- data/test/manual/banner-tests/test22.html +68 -0
- data/test/manual/banner-tests/test23.html +68 -0
- data/test/manual/banner-tests/test24.html +68 -0
- data/test/manual/banner-tests/test25.html +67 -0
- data/test/manual/banner_environment.rb +192 -0
- data/test/manual/deploy_symlink_demo.rb +142 -0
- data/test/manual/environment.rb +67 -0
- data/test/manual/make_banner.rb +153 -0
- data/test/manual/sample_banner_config.txt +12 -0
- data/test/manual/symlink_demo.rb +117 -0
- data/test/manual/test1.rb +47 -0
- data/test/manual/test2.rb +12 -0
- data/test/manual/test3.rb +38 -0
- data/test/manual/test4.rb +40 -0
- data/test/manual/test5.rb +24 -0
- data/test/manual/test6.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_from_file.rb +150 -0
- data/test/manual/test_banner_in_header.rb +35 -0
- data/test/manual/test_code_highlighting.rb +68 -0
- data/test/manual/test_complex_header.rb +74 -0
- data/test/manual/test_empty_header.rb +32 -0
- data/test/manual/test_radial_custom.rb +58 -0
- data/test/manual/test_radial_large_radius.rb +52 -0
- data/test/manual/test_svg_debug.rb +47 -0
- data/test/manual/test_syntax_highlighting.rb +147 -0
- data/test/pages-demo/config/currentview.txt +1 -0
- data/test/pages-demo/views/demo/config/bootstrap_css.txt +5 -0
- data/test/pages-demo/views/demo/config/bootstrap_js.txt +4 -0
- data/test/pages-demo/views/demo/config/common.js +57 -0
- data/test/pages-demo/views/demo/config/footer.txt +1 -0
- data/test/pages-demo/views/demo/config/global-head.txt +8 -0
- data/test/pages-demo/views/demo/config/header.txt +1 -0
- data/test/pages-demo/views/demo/config/layout.txt +1 -0
- data/test/pages-demo/views/demo/config/left.txt +1 -0
- data/test/pages-demo/views/demo/config/main.txt +1 -0
- data/test/pages-demo/views/demo/config/right.txt +1 -0
- data/test/pages-demo/views/demo/config.txt +3 -0
- data/test/pages-demo/views/demo/output/panes/footer.html +1 -0
- data/test/pages-demo/views/demo/output/panes/header.html +1 -0
- data/test/pages-demo/views/demo/output/panes/left.html +1 -0
- data/test/pages-demo/views/demo/output/panes/main.html +1 -0
- data/test/pages-demo/views/demo/output/panes/right.html +1 -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/scriptorium-TEST-1754622690-146/config/bootstrap_css.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/config/bootstrap_js.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/config/common.js +57 -0
- data/test/scriptorium-TEST-1754622690-146/config/currentview.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/config/global-head.txt +9 -0
- data/test/scriptorium-TEST-1754622690-146/config/last_post_num.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/config/os_helpers.rb +4 -0
- data/test/scriptorium-TEST-1754622690-146/config/widgets.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/posts/0001/meta.txt +8 -0
- data/test/scriptorium-TEST-1754622690-146/posts/0001/source.lt3 +6 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/README.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/config.txt +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/initial/post.lt3 +12 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/footer.txt +2 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/header.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/left.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/main.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/config/right.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/gen/text.css +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/layout/layout.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index.lt3 +1 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/index_entry.lt3 +14 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/post.lt3 +13 -0
- data/test/scriptorium-TEST-1754622690-146/themes/standard/templates/widget.lt3 +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_css.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/bootstrap_js.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/common.js +57 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/deploy.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/footer.txt +2 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/global-head.txt +9 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/header.txt +4 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/layout.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/left.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/main.txt +5 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/reddit.txt +10 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/right.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/social.txt +7 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config/status.txt +7 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/config.txt +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/footer.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/header.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/left.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/main.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/layout/right.html +3 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/footer.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/header.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/left.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/main.html +1 -0
- data/test/scriptorium-TEST-1754622690-146/views/sample/output/panes/right.html +1 -0
- data/test/staging/.DS_Store +0 -0
- data/test/syntax_highlighting_test.lt3 +124 -0
- data/test/test_helpers.rb +230 -0
- data/test/tui_editor_integration_test.rb +296 -0
- data/test/tui_integration_test.rb +637 -0
- data/test/unit/api.rb +1056 -0
- data/test/unit/asset_management.rb +245 -0
- data/test/unit/clipboard_test.rb +60 -0
- data/test/unit/contract_test.rb +91 -0
- data/test/unit/core.rb +857 -0
- data/test/unit/deploy_test.rb +187 -0
- data/test/unit/gem_asset_management.rb +189 -0
- data/test/unit/livetext_basic.rb +69 -0
- data/test/unit/livetext_compatibility.rb +89 -0
- data/test/unit/post.rb +244 -0
- data/test/unit/read_commented_file_test.rb +276 -0
- data/test/unit/reddit_test.rb +235 -0
- data/test/unit/repo.rb +548 -0
- data/test/unit/social_test.rb +369 -0
- data/test/unit/symlink_test.rb +213 -0
- data/test/unit/view.rb +431 -0
- data/test/unit/widgets.rb +669 -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 +1420 -0
- data/ui/tui/test/tui_test.rb +23 -0
- data/ui/web/app/app.rb +1378 -0
- data/ui/web/app/error_helpers.rb +150 -0
- data/ui/web/app/views/advanced_config.erb +190 -0
- data/ui/web/app/views/asset_management.erb +589 -0
- data/ui/web/app/views/banner_config.erb +200 -0
- data/ui/web/app/views/configure_view.erb +401 -0
- data/ui/web/app/views/dashboard.erb +162 -0
- data/ui/web/app/views/deploy_config.erb +146 -0
- data/ui/web/app/views/edit_pages.erb +195 -0
- data/ui/web/app/views/edit_post.erb +54 -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/view_dashboard.erb +138 -0
- data/ui/web/bin/scriptorium-web +153 -0
- data/ui/web/test/web_basic_test.rb +38 -0
- data/ui/web/test_navbar.txt +7 -0
- data/ui/web/tmp/web_server.log +5 -0
- data/ui/web/tmp/web_server.pid +1 -0
- metadata +359 -7
- data/lib/scriptorium/engine.rb +0 -22
- data/test/engine/unit.rb +0 -44
@@ -0,0 +1,369 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require_relative '../../lib/scriptorium'
|
3
|
+
require_relative '../test_helpers'
|
4
|
+
|
5
|
+
class SocialTest < Minitest::Test
|
6
|
+
include Scriptorium::Exceptions
|
7
|
+
include Scriptorium::Helpers
|
8
|
+
include TestHelpers
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@test_dir = "test/social_test_files"
|
12
|
+
make_dir(@test_dir)
|
13
|
+
@repo = Scriptorium::Repo.create("test/scriptorium-TEST", testmode: true)
|
14
|
+
@view = @repo.create_view("test", "Test View", "A test view")
|
15
|
+
end
|
16
|
+
|
17
|
+
def teardown
|
18
|
+
FileUtils.rm_rf(@test_dir) if Dir.exist?(@test_dir)
|
19
|
+
Scriptorium::Repo.destroy if Scriptorium::Repo.testing
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_001_social_config_file_created
|
23
|
+
social_config_file = @view.dir/:config/"social.txt"
|
24
|
+
assert File.exist?(social_config_file), "Social config file should be created"
|
25
|
+
|
26
|
+
content = read_file(social_config_file)
|
27
|
+
assert_includes content, "enabled: true"
|
28
|
+
assert_includes content, "platforms: facebook, twitter"
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_002_social_meta_tags_generated_when_enabled
|
32
|
+
# Enable social features
|
33
|
+
social_config = <<~EOS
|
34
|
+
enabled: true
|
35
|
+
platforms: facebook, twitter
|
36
|
+
EOS
|
37
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
38
|
+
|
39
|
+
# Generate meta tags
|
40
|
+
meta_tags = @view.generate_social_meta_tags
|
41
|
+
|
42
|
+
# Check for Open Graph tags
|
43
|
+
assert_includes meta_tags, 'property="og:title"'
|
44
|
+
assert_includes meta_tags, 'property="og:type"'
|
45
|
+
assert_includes meta_tags, 'property="og:url"'
|
46
|
+
assert_includes meta_tags, 'property="og:description"'
|
47
|
+
assert_includes meta_tags, 'property="og:site_name"'
|
48
|
+
|
49
|
+
# Check for Twitter Card tags
|
50
|
+
assert_includes meta_tags, 'name="twitter:card"'
|
51
|
+
assert_includes meta_tags, 'name="twitter:title"'
|
52
|
+
assert_includes meta_tags, 'name="twitter:description"'
|
53
|
+
assert_includes meta_tags, 'name="twitter:url"'
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_003_social_meta_tags_not_generated_when_disabled
|
57
|
+
# Disable social features
|
58
|
+
social_config = <<~EOS
|
59
|
+
enabled: false
|
60
|
+
platforms: facebook, twitter
|
61
|
+
EOS
|
62
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
63
|
+
|
64
|
+
# Generate meta tags
|
65
|
+
meta_tags = @view.generate_social_meta_tags
|
66
|
+
|
67
|
+
# Should be empty when disabled
|
68
|
+
assert_empty meta_tags
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_004_post_specific_meta_tags
|
72
|
+
# Enable social features
|
73
|
+
social_config = <<~EOS
|
74
|
+
enabled: true
|
75
|
+
platforms: facebook, twitter
|
76
|
+
EOS
|
77
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
78
|
+
|
79
|
+
# Create post data
|
80
|
+
post_data = {
|
81
|
+
:"post.id" => "1",
|
82
|
+
:"post.title" => "Test Post",
|
83
|
+
:"post.body" => "This is a test post body",
|
84
|
+
:"post.blurb" => "Test post blurb",
|
85
|
+
:"post.pubdate" => "2024-01-01 12:00:00",
|
86
|
+
:"post.slug" => "test-post.html"
|
87
|
+
}
|
88
|
+
|
89
|
+
# Generate meta tags for post
|
90
|
+
meta_tags = @view.generate_social_meta_tags(nil, post_data)
|
91
|
+
|
92
|
+
# Check for post-specific content
|
93
|
+
assert_includes meta_tags, 'content="Test Post"'
|
94
|
+
assert_includes meta_tags, 'content="article"'
|
95
|
+
assert_includes meta_tags, 'content="posts/test-post.html"'
|
96
|
+
assert_includes meta_tags, 'content="Test post blurb"'
|
97
|
+
assert_includes meta_tags, 'content="2024-01-01 12:00:00"'
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_005_complete_post_html_generation
|
101
|
+
# Enable social features
|
102
|
+
social_config = <<~EOS
|
103
|
+
enabled: true
|
104
|
+
platforms: facebook, twitter
|
105
|
+
EOS
|
106
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
107
|
+
|
108
|
+
# Create post data
|
109
|
+
post_data = {
|
110
|
+
:"post.id" => "1",
|
111
|
+
:"post.title" => "Test Post",
|
112
|
+
:"post.body" => "<p>This is a test post body</p>",
|
113
|
+
:"post.pubdate" => "2024-01-01 12:00:00",
|
114
|
+
:"post.tags" => "test, example"
|
115
|
+
}
|
116
|
+
|
117
|
+
# Generate complete HTML
|
118
|
+
html = @view.generate_post_html(post_data)
|
119
|
+
|
120
|
+
# Check for complete HTML structure
|
121
|
+
assert_includes html, "<!DOCTYPE html>"
|
122
|
+
assert_includes html, "<html>"
|
123
|
+
assert_includes html, "<head>"
|
124
|
+
assert_includes html, "<body>"
|
125
|
+
assert_includes html, "Test Post"
|
126
|
+
assert_includes html, "This is a test post body"
|
127
|
+
assert_includes html, "2024-01-01 12:00:00"
|
128
|
+
assert_includes html, "test, example"
|
129
|
+
|
130
|
+
# Check for social meta tags
|
131
|
+
assert_includes html, 'property="og:title"'
|
132
|
+
assert_includes html, 'name="twitter:card"'
|
133
|
+
end
|
134
|
+
|
135
|
+
# Reddit Button Tests
|
136
|
+
|
137
|
+
def test_006_reddit_config_file_created
|
138
|
+
reddit_config_file = @view.dir/:config/"reddit.txt"
|
139
|
+
assert File.exist?(reddit_config_file), "Reddit config file should be created"
|
140
|
+
|
141
|
+
content = read_file(reddit_config_file)
|
142
|
+
assert_includes content, "button true"
|
143
|
+
assert_includes content, "subreddit"
|
144
|
+
assert_includes content, "hover_text"
|
145
|
+
end
|
146
|
+
|
147
|
+
def test_007_reddit_button_not_generated_when_reddit_not_enabled
|
148
|
+
# Disable Reddit in social config
|
149
|
+
social_config = <<~EOS
|
150
|
+
enabled: true
|
151
|
+
platforms: facebook, twitter
|
152
|
+
EOS
|
153
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
154
|
+
|
155
|
+
# Enable Reddit button in reddit config
|
156
|
+
reddit_config = <<~EOS
|
157
|
+
button true
|
158
|
+
subreddit
|
159
|
+
hover_text
|
160
|
+
EOS
|
161
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
162
|
+
|
163
|
+
# Generate Reddit button
|
164
|
+
button_html = @view.generate_reddit_button
|
165
|
+
|
166
|
+
# Should be empty when Reddit not enabled in social config
|
167
|
+
assert_empty button_html
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_008_reddit_button_not_generated_when_button_disabled
|
171
|
+
# Enable Reddit in social config
|
172
|
+
social_config = <<~EOS
|
173
|
+
enabled: true
|
174
|
+
platforms: facebook, twitter, reddit
|
175
|
+
EOS
|
176
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
177
|
+
|
178
|
+
# Disable Reddit button in reddit config
|
179
|
+
reddit_config = <<~EOS
|
180
|
+
button false
|
181
|
+
subreddit
|
182
|
+
hover_text
|
183
|
+
EOS
|
184
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
185
|
+
|
186
|
+
# Generate Reddit button
|
187
|
+
button_html = @view.generate_reddit_button
|
188
|
+
|
189
|
+
# Should be empty when button disabled
|
190
|
+
assert_empty button_html
|
191
|
+
end
|
192
|
+
|
193
|
+
def test_009_reddit_button_generated_when_enabled
|
194
|
+
# Enable Reddit in social config
|
195
|
+
social_config = <<~EOS
|
196
|
+
enabled: true
|
197
|
+
platforms: facebook, twitter, reddit
|
198
|
+
EOS
|
199
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
200
|
+
|
201
|
+
# Enable Reddit button in reddit config
|
202
|
+
reddit_config = <<~EOS
|
203
|
+
button true
|
204
|
+
subreddit
|
205
|
+
hover_text
|
206
|
+
EOS
|
207
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
208
|
+
|
209
|
+
# Generate Reddit button
|
210
|
+
button_html = @view.generate_reddit_button
|
211
|
+
|
212
|
+
# Should contain Reddit button HTML
|
213
|
+
assert_includes button_html, 'href="https://reddit.com/submit'
|
214
|
+
assert_includes button_html, 'title="Share on Reddit"'
|
215
|
+
assert_includes button_html, 'src="assets/reddit-logo.png"'
|
216
|
+
assert_includes button_html, 'alt="Share on Reddit"'
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_010_reddit_button_with_subreddit
|
220
|
+
# Enable Reddit in social config
|
221
|
+
social_config = <<~EOS
|
222
|
+
enabled: true
|
223
|
+
platforms: facebook, twitter, reddit
|
224
|
+
EOS
|
225
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
226
|
+
|
227
|
+
# Enable Reddit button with subreddit
|
228
|
+
reddit_config = <<~EOS
|
229
|
+
button true
|
230
|
+
subreddit RubyElixirEtc
|
231
|
+
hover_text
|
232
|
+
EOS
|
233
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
234
|
+
|
235
|
+
# Generate Reddit button
|
236
|
+
button_html = @view.generate_reddit_button
|
237
|
+
|
238
|
+
# Should contain subreddit-specific URL and hover text
|
239
|
+
assert_includes button_html, 'href="https://reddit.com/r/RubyElixirEtc/submit'
|
240
|
+
assert_includes button_html, 'title="Share on r/RubyElixirEtc"'
|
241
|
+
end
|
242
|
+
|
243
|
+
def test_011_reddit_button_with_custom_hover_text
|
244
|
+
# Enable Reddit in social config
|
245
|
+
social_config = <<~EOS
|
246
|
+
enabled: true
|
247
|
+
platforms: facebook, twitter, reddit
|
248
|
+
EOS
|
249
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
250
|
+
|
251
|
+
# Enable Reddit button with custom hover text
|
252
|
+
reddit_config = <<~EOS
|
253
|
+
button true
|
254
|
+
subreddit
|
255
|
+
hover_text Share this awesome post!
|
256
|
+
EOS
|
257
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
258
|
+
|
259
|
+
# Generate Reddit button
|
260
|
+
button_html = @view.generate_reddit_button
|
261
|
+
|
262
|
+
# Should contain custom hover text
|
263
|
+
assert_includes button_html, 'title="Share this awesome post!"'
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_012_reddit_button_with_post_data
|
267
|
+
# Enable Reddit in social config
|
268
|
+
social_config = <<~EOS
|
269
|
+
enabled: true
|
270
|
+
platforms: facebook, twitter, reddit
|
271
|
+
EOS
|
272
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
273
|
+
|
274
|
+
# Enable Reddit button
|
275
|
+
reddit_config = <<~EOS
|
276
|
+
button true
|
277
|
+
subreddit
|
278
|
+
hover_text
|
279
|
+
EOS
|
280
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
281
|
+
|
282
|
+
# Create post data
|
283
|
+
post_data = {
|
284
|
+
:"post.id" => "123",
|
285
|
+
:"post.title" => "My Test Post",
|
286
|
+
:"post.slug" => "my-test-post"
|
287
|
+
}
|
288
|
+
|
289
|
+
# Generate Reddit button with post data
|
290
|
+
button_html = @view.generate_reddit_button(post_data)
|
291
|
+
|
292
|
+
# Should contain post-specific URL and title
|
293
|
+
assert_includes button_html, 'url=posts/my-test-post.html'
|
294
|
+
assert_includes button_html, 'title=My+Test+Post'
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_013_reddit_button_integration_with_post_generation
|
298
|
+
# Enable Reddit in social config
|
299
|
+
social_config = <<~EOS
|
300
|
+
enabled: true
|
301
|
+
platforms: facebook, twitter, reddit
|
302
|
+
EOS
|
303
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
304
|
+
|
305
|
+
# Enable Reddit button
|
306
|
+
reddit_config = <<~EOS
|
307
|
+
button true
|
308
|
+
subreddit
|
309
|
+
hover_text
|
310
|
+
EOS
|
311
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
312
|
+
|
313
|
+
# Create and generate a post
|
314
|
+
draft_name = @repo.create_draft(title: "Reddit Test Post", tags: %w[test reddit])
|
315
|
+
body = "This is a test post for Reddit button integration."
|
316
|
+
text = File.read(draft_name)
|
317
|
+
text.sub!(/BEGIN HERE.../, body)
|
318
|
+
write_file(draft_name, text)
|
319
|
+
post_id = @repo.finish_draft(draft_name)
|
320
|
+
@repo.generate_post(post_id)
|
321
|
+
|
322
|
+
# Check that the generated post contains Reddit button
|
323
|
+
post_file = @repo.root/:views/:test/:output/:posts/"#{d4(post_id)}-reddit-test-post.html"
|
324
|
+
assert File.exist?(post_file), "Generated post should exist"
|
325
|
+
|
326
|
+
post_content = read_file(post_file)
|
327
|
+
assert_includes post_content, 'href="https://reddit.com/submit'
|
328
|
+
assert_includes post_content, 'src="assets/reddit-logo.png"'
|
329
|
+
end
|
330
|
+
|
331
|
+
def test_014_reddit_button_missing_config_file_handling
|
332
|
+
# Enable Reddit in social config
|
333
|
+
social_config = <<~EOS
|
334
|
+
enabled: true
|
335
|
+
platforms: facebook, twitter, reddit
|
336
|
+
EOS
|
337
|
+
write_file(@view.dir/:config/"social.txt", social_config)
|
338
|
+
|
339
|
+
# Remove reddit.txt config file
|
340
|
+
reddit_config_file = @view.dir/:config/"reddit.txt"
|
341
|
+
File.delete(reddit_config_file) if File.exist?(reddit_config_file)
|
342
|
+
|
343
|
+
# Generate Reddit button
|
344
|
+
button_html = @view.generate_reddit_button
|
345
|
+
|
346
|
+
# Should be empty when config file missing
|
347
|
+
assert_empty button_html
|
348
|
+
end
|
349
|
+
|
350
|
+
def test_015_reddit_button_missing_social_config_file_handling
|
351
|
+
# Remove social.txt config file
|
352
|
+
social_config_file = @view.dir/:config/"social.txt"
|
353
|
+
File.delete(social_config_file) if File.exist?(social_config_file)
|
354
|
+
|
355
|
+
# Enable Reddit button in reddit config
|
356
|
+
reddit_config = <<~EOS
|
357
|
+
button true
|
358
|
+
subreddit
|
359
|
+
hover_text
|
360
|
+
EOS
|
361
|
+
write_file(@view.dir/:config/"reddit.txt", reddit_config)
|
362
|
+
|
363
|
+
# Generate Reddit button
|
364
|
+
button_html = @view.generate_reddit_button
|
365
|
+
|
366
|
+
# Should be empty when social config file missing
|
367
|
+
assert_empty button_html
|
368
|
+
end
|
369
|
+
end
|
@@ -0,0 +1,213 @@
|
|
1
|
+
# Test file for symlink functionality
|
2
|
+
# Tests the clean URL symlink generation for posts
|
3
|
+
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require_relative '../../lib/scriptorium'
|
6
|
+
require_relative '../test_helpers'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
class TestSymlinkFunctionality < Minitest::Test
|
10
|
+
include Scriptorium::Helpers
|
11
|
+
include TestHelpers
|
12
|
+
|
13
|
+
def setup
|
14
|
+
@test_dir = "test/symlink_test_files"
|
15
|
+
FileUtils.mkdir_p(@test_dir)
|
16
|
+
Scriptorium::Repo.testing = true
|
17
|
+
|
18
|
+
# Create test repository
|
19
|
+
@repo = Scriptorium::Repo.create("test/scriptorium-TEST", testmode: true)
|
20
|
+
@view = @repo.create_view("test_view", "Test View", "Test Subtitle")
|
21
|
+
end
|
22
|
+
|
23
|
+
def teardown
|
24
|
+
FileUtils.rm_rf(@test_dir) if File.exist?(@test_dir)
|
25
|
+
FileUtils.rm_rf("test/scriptorium-TEST") if File.exist?("test/scriptorium-TEST")
|
26
|
+
end
|
27
|
+
|
28
|
+
# ========================================
|
29
|
+
# clean_slugify function tests
|
30
|
+
# ========================================
|
31
|
+
|
32
|
+
def test_001_clean_slugify_basic
|
33
|
+
result = clean_slugify("My Test Post")
|
34
|
+
assert_equal "my-test-post", result
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_002_clean_slugify_with_special_characters
|
38
|
+
result = clean_slugify("Post with & < > \" ' characters!")
|
39
|
+
assert_equal "post-with-characters", result
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_003_clean_slugify_with_underscores_and_hyphens
|
43
|
+
result = clean_slugify("Post with_underscores-and-hyphens")
|
44
|
+
assert_equal "post-with-underscores-and-hyphens", result
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_004_clean_slugify_with_multiple_spaces
|
48
|
+
result = clean_slugify("Post with multiple spaces")
|
49
|
+
assert_equal "post-with-multiple-spaces", result
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_005_clean_slugify_with_leading_trailing_hyphens
|
53
|
+
result = clean_slugify("-Post with leading/trailing hyphens-")
|
54
|
+
assert_equal "post-with-leadingtrailing-hyphens", result
|
55
|
+
end
|
56
|
+
|
57
|
+
# ========================================
|
58
|
+
# Symlink generation tests
|
59
|
+
# ========================================
|
60
|
+
|
61
|
+
def test_006_symlink_creation_for_post
|
62
|
+
# Create a test post
|
63
|
+
post_title = "My First Test Post"
|
64
|
+
post_body = "This is the body of my test post."
|
65
|
+
|
66
|
+
# Create draft and finish it
|
67
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
68
|
+
post_num = @repo.finish_draft(draft_name)
|
69
|
+
|
70
|
+
# Generate the post
|
71
|
+
@repo.generate_post(post_num)
|
72
|
+
|
73
|
+
# Check that both files exist
|
74
|
+
numbered_slug = slugify(post_num, post_title) + ".html"
|
75
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
76
|
+
|
77
|
+
numbered_path = @view.dir/:output/:permalink/numbered_slug
|
78
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
79
|
+
|
80
|
+
# Both files should exist
|
81
|
+
assert File.exist?(numbered_path), "Numbered post file should exist: #{numbered_path}"
|
82
|
+
assert File.exist?(clean_symlink_path), "Clean symlink should exist: #{clean_symlink_path}"
|
83
|
+
|
84
|
+
# Clean symlink should be a symlink
|
85
|
+
assert File.symlink?(clean_symlink_path), "Clean symlink should be a symlink"
|
86
|
+
|
87
|
+
# Symlink should point to the numbered file
|
88
|
+
symlink_target = File.readlink(clean_symlink_path)
|
89
|
+
expected_target = numbered_slug
|
90
|
+
assert_equal expected_target, symlink_target, "Symlink should point to numbered file"
|
91
|
+
end
|
92
|
+
|
93
|
+
def test_007_symlink_points_to_correct_file
|
94
|
+
# Create a test post with a specific title
|
95
|
+
post_title = "Another Test Post"
|
96
|
+
post_body = "This is another test post."
|
97
|
+
|
98
|
+
# Create draft and finish it
|
99
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
100
|
+
post_num = @repo.finish_draft(draft_name)
|
101
|
+
|
102
|
+
# Generate the post
|
103
|
+
@repo.generate_post(post_num)
|
104
|
+
|
105
|
+
# Check symlink target
|
106
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
107
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
108
|
+
|
109
|
+
assert File.symlink?(clean_symlink_path), "Should be a symlink"
|
110
|
+
|
111
|
+
# Get the actual target
|
112
|
+
symlink_target = File.readlink(clean_symlink_path)
|
113
|
+
|
114
|
+
# Expected target should be the numbered slug
|
115
|
+
expected_slug = slugify(post_num, post_title) + ".html"
|
116
|
+
assert_equal expected_slug, symlink_target, "Symlink should point to correct numbered file"
|
117
|
+
end
|
118
|
+
|
119
|
+
def test_008_symlink_overwrites_existing
|
120
|
+
# Create a test post
|
121
|
+
post_title = "Duplicate Test Post"
|
122
|
+
post_body = "This is a test post."
|
123
|
+
|
124
|
+
# Create draft and finish it
|
125
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
126
|
+
post_num = @repo.finish_draft(draft_name)
|
127
|
+
|
128
|
+
# Generate the post (should create symlink)
|
129
|
+
@repo.generate_post(post_num)
|
130
|
+
|
131
|
+
# Check that symlink exists
|
132
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
133
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
134
|
+
|
135
|
+
assert File.symlink?(clean_symlink_path), "Symlink should exist"
|
136
|
+
|
137
|
+
# Get the target
|
138
|
+
original_target = File.readlink(clean_symlink_path)
|
139
|
+
|
140
|
+
# Now create another post with the same clean slug (different numbered slug)
|
141
|
+
post_title2 = "Duplicate Test Post" # Same title, different post
|
142
|
+
post_body2 = "This is another test post with same title."
|
143
|
+
|
144
|
+
draft_name2 = @repo.create_draft(title: post_title2, body: post_body2)
|
145
|
+
post_num2 = @repo.finish_draft(draft_name2)
|
146
|
+
|
147
|
+
# Generate the second post (should overwrite symlink)
|
148
|
+
@repo.generate_post(post_num2)
|
149
|
+
|
150
|
+
# Check that symlink still exists and points to the new target
|
151
|
+
assert File.symlink?(clean_symlink_path), "Symlink should still exist"
|
152
|
+
|
153
|
+
new_target = File.readlink(clean_symlink_path)
|
154
|
+
expected_target = slugify(post_num2, post_title2) + ".html"
|
155
|
+
|
156
|
+
assert_equal expected_target, new_target, "Symlink should point to new target"
|
157
|
+
refute_equal original_target, new_target, "Symlink should have been updated"
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_009_symlink_with_special_characters_in_title
|
161
|
+
# Test with a title that has special characters
|
162
|
+
post_title = "Post with Special Characters: & < > \" ' !"
|
163
|
+
post_body = "This post has special characters in the title."
|
164
|
+
|
165
|
+
# Create draft and finish it
|
166
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
167
|
+
post_num = @repo.finish_draft(draft_name)
|
168
|
+
|
169
|
+
# Generate the post
|
170
|
+
@repo.generate_post(post_num)
|
171
|
+
|
172
|
+
# Check that symlink exists with cleaned slug
|
173
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
174
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
175
|
+
|
176
|
+
assert File.exist?(clean_symlink_path), "Symlink should exist for cleaned title"
|
177
|
+
assert File.symlink?(clean_symlink_path), "Should be a symlink"
|
178
|
+
|
179
|
+
# Check that the symlink points to the correct numbered file
|
180
|
+
symlink_target = File.readlink(clean_symlink_path)
|
181
|
+
expected_target = slugify(post_num, post_title) + ".html"
|
182
|
+
assert_equal expected_target, symlink_target, "Symlink should point to correct numbered file"
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_010_symlink_deployment_ready
|
186
|
+
# Test that symlinks are created in the correct location for deployment
|
187
|
+
post_title = "Deployment Test Post"
|
188
|
+
post_body = "This post tests deployment readiness."
|
189
|
+
|
190
|
+
# Create draft and finish it
|
191
|
+
draft_name = @repo.create_draft(title: post_title, body: post_body)
|
192
|
+
post_num = @repo.finish_draft(draft_name)
|
193
|
+
|
194
|
+
# Generate the post
|
195
|
+
@repo.generate_post(post_num)
|
196
|
+
|
197
|
+
# Check that symlink is in the correct deployment location
|
198
|
+
clean_slug = clean_slugify(post_title) + ".html"
|
199
|
+
clean_symlink_path = @view.dir/:output/:permalink/clean_slug
|
200
|
+
|
201
|
+
# Verify the path structure
|
202
|
+
assert_equal @view.dir/:output/:permalink/clean_slug, clean_symlink_path
|
203
|
+
assert File.exist?(clean_symlink_path), "Symlink should exist in deployment location"
|
204
|
+
|
205
|
+
# Verify it's a symlink
|
206
|
+
assert File.symlink?(clean_symlink_path), "Should be a symlink"
|
207
|
+
|
208
|
+
# Verify the target exists and is accessible
|
209
|
+
symlink_target = File.readlink(clean_symlink_path)
|
210
|
+
target_path = @view.dir/:output/:permalink/symlink_target
|
211
|
+
assert File.exist?(target_path), "Symlink target should exist"
|
212
|
+
end
|
213
|
+
end
|