defmodule Blogex.FeedTest do use ExUnit.Case import Blogex.Test.PostBuilder alias Blogex.Test.FakeBlog alias Blogex.Feed @base_url "https://example.com" setup do Blogex.Test.Setup.with_blog( %{}, blog_id: :eng, title: "Eng Blog", description: "Tech articles", base_path: "/blog/eng" ) end describe "rss/3" do test "produces valid RSS 2.0 XML", %{blog: blog} do xml = Feed.rss(blog, @base_url) assert xml =~ ~s() end test "includes blog title and description", %{blog: blog} do xml = Feed.rss(blog, @base_url) assert xml =~ "Eng Blog" assert xml =~ "Tech articles" end test "includes post entries with correct links", %{blog: blog} do xml = Feed.rss(blog, @base_url) assert xml =~ "https://example.com/blog/eng/newest-post" end test "wraps post body in CDATA", %{blog: blog} do xml = Feed.rss(blog, @base_url) assert xml =~ "elixir" end test "respects limit option" do {:ok, _} = FakeBlog.start(build_many(10)) xml = Feed.rss(FakeBlog, @base_url, limit: 3) item_count = xml |> String.split("") |> length() |> Kernel.-(1) assert item_count == 3 end test "excludes drafts", %{blog: blog} do xml = Feed.rss(blog, @base_url) refute xml =~ "draft-post" end test "excludes future-dated published posts", %{blog: blog} do xml = Feed.rss(blog, @base_url) refute xml =~ "future-post" end test "includes self-referencing atom:link", %{blog: blog} do xml = Feed.rss(blog, @base_url) assert xml =~ ~s(href="https://example.com/blog/eng/feed.xml") assert xml =~ ~s(rel="self") end end describe "atom/3" do test "produces valid Atom XML", %{blog: blog} do xml = Feed.atom(blog, @base_url) assert xml =~ ~s() assert xml =~ ~s() end test "includes post entries", %{blog: blog} do xml = Feed.atom(blog, @base_url) assert xml =~ "" assert xml =~ ~s(href="https://example.com/blog/eng/newest-post") end test "respects limit option" do {:ok, _} = FakeBlog.start(build_many(10)) xml = Feed.atom(FakeBlog, @base_url, limit: 2) entry_count = xml |> String.split("") |> length() |> Kernel.-(1) assert entry_count == 2 end test "excludes future-dated published posts", %{blog: blog} do xml = Feed.atom(blog, @base_url) refute xml =~ "future-post" end end describe "XML escaping" do test "escapes special characters in titles" do {:ok, _} = FakeBlog.start( [build(title: "Foo & Bar ")], title: "A & B" ) xml = Feed.rss(FakeBlog, @base_url) assert xml =~ "Foo & Bar <Baz>" assert xml =~ "A & B" end end describe "empty blog" do test "rss produces valid XML with no items" do {:ok, _} = FakeBlog.start([]) xml = Feed.rss(FakeBlog, @base_url) assert xml =~ "" refute xml =~ "" end test "atom produces valid XML with no entries" do {:ok, _} = FakeBlog.start([]) xml = Feed.atom(FakeBlog, @base_url) assert xml =~ "" end end end