# frozen_string_literal: true require "test_helper" require "volumen/server" require "rack/test" require "tmpdir" require "fileutils" require "json" class ServerTest < Minitest::Test include Rack::Test::Methods def app Volumen::Server.configured(config: @config, store: @store) end def setup @dir = Dir.mktmpdir File.write(File.join(@dir, "hello.md"), <<~POST) +++ title = "Hello" tags = ["intro"] +++ Hello **world**. POST File.write(File.join(@dir, "draft.md"), <<~POST) +++ title = "Draft" draft = true +++ Secret. POST @config = Volumen::Config.load(path: "/nonexistent", overrides: { content: @dir }) @store = Volumen::Store.new(@dir, default_lang: "en") end def teardown FileUtils.remove_entry(@dir) end def test_site_endpoint get "/api/volumen/site" assert_predicate last_response, :ok? assert_equal "My Blog", JSON.parse(last_response.body)["title"] end def test_posts_excludes_drafts get "/api/volumen/posts" data = JSON.parse(last_response.body) assert_equal 1, data["total"] assert_equal "hello", data["posts"].first["slug"] end def test_post_detail_renders_html get "/api/volumen/posts/hello" assert_predicate last_response, :ok? assert_includes JSON.parse(last_response.body)["html"], "world" end def test_post_not_found get "/api/volumen/posts/missing" assert_equal 404, last_response.status assert_equal "not_found", JSON.parse(last_response.body)["error"] end def test_tags_endpoint get "/api/volumen/tags" assert_equal [{ "name" => "intro", "count" => 1 }], JSON.parse(last_response.body)["tags"] end def test_cors_header_present get "/api/volumen/site" header = last_response.headers["Access-Control-Allow-Origin"] || last_response.headers["access-control-allow-origin"] assert_equal "*", header end def test_all_langs_post_appears_in_other_languages File.write(File.join(@dir, "global.md"), <<~POST) +++ title = "Global" lang = "en" all_langs = true +++ Everywhere. POST get "/api/volumen/posts?lang=cs" slugs = JSON.parse(last_response.body)["posts"].map { |post| post["slug"] } assert_includes slugs, "global" refute_includes slugs, "hello" end def test_feed_endpoint get "/api/volumen/feed.xml" assert_predicate last_response, :ok? assert_equal "application/rss+xml", last_response["Content-Type"]&.split(";")&.first body = last_response.body assert_includes body, "" assert_includes body, "Hello" refute_includes body, "Draft" assert_includes body, "en" end def test_draft_post_detail_is_not_found get "/api/volumen/posts/draft" assert_equal 404, last_response.status assert_equal "not_found", JSON.parse(last_response.body)["error"] end def test_sitemap_endpoint get "/api/volumen/sitemap.xml" assert_predicate last_response, :ok? assert_equal "application/xml", last_response["Content-Type"]&.split(";")&.first body = last_response.body assert_includes body, "" assert_includes body, "https://example.com/hello" refute_includes body, "draft" end def test_cors_preflight options "/api/volumen/site" assert_predicate last_response, :ok? assert_equal "*", last_response.headers["Access-Control-Allow-Origin"] assert_equal "GET, OPTIONS", last_response.headers["Access-Control-Allow-Methods"] end end