1
0

meta_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. package extract
  2. import (
  3. "net/url"
  4. "testing"
  5. "time"
  6. )
  7. func TestReadPageMetaTags(t *testing.T) {
  8. base, _ := url.Parse("https://news.example/2025/story")
  9. m := readPageMeta(parse(t, `<html><head>
  10. <title>Fallback Title | News</title>
  11. <meta property="og:title" content="The Story">
  12. <meta property="og:site_name" content="Example News">
  13. <meta property="og:image" content="/img/lead.jpg">
  14. <meta property="og:image" content="/img/second.jpg">
  15. <meta name="author" content="Ada Lovelace">
  16. <meta name="description" content="What happened.">
  17. <meta property="article:published_time" content="2025-03-14T09:30:00+01:00">
  18. </head><body></body></html>`), base)
  19. want := pageMeta{
  20. Title: "The Story", Author: "Ada Lovelace", SiteName: "Example News", Description: "What happened.",
  21. Image: "https://news.example/img/lead.jpg",
  22. Published: time.Date(2025, 3, 14, 9, 30, 0, 0, time.FixedZone("", 3600)),
  23. }
  24. if m.Title != want.Title || m.Author != want.Author || m.SiteName != want.SiteName ||
  25. m.Description != want.Description || m.Image != want.Image || !m.Published.Equal(want.Published) {
  26. t.Errorf("got %+v\nwant %+v", m, want)
  27. }
  28. }
  29. func TestReadPageMetaJSONLD(t *testing.T) {
  30. base, _ := url.Parse("https://blog.example/post")
  31. m := readPageMeta(parse(t, `<html><head>
  32. <title>Title Tag</title>
  33. <meta property="article:author" content="https://blog.example/authors/grace">
  34. <script type="application/ld+json">{"@context":"https://schema.org","@graph":[
  35. {"@type":"WebSite","name":"Not an article"},
  36. {"@type":["BlogPosting","Article"],"headline":"JSON-LD Headline",
  37. "author":[{"@type":"Person","name":"Grace Hopper"},{"name":"Alan Turing"}],
  38. "publisher":{"@type":"Organization","name":"The Blog"},
  39. "image":{"@type":"ImageObject","url":"https://cdn.example/hero.png"},
  40. "datePublished":"2024-11-02"}
  41. ]}</script>
  42. <script type="application/ld+json">this is not JSON</script>
  43. </head><body></body></html>`), base)
  44. if m.Title != "JSON-LD Headline" {
  45. t.Errorf("Title = %q", m.Title)
  46. }
  47. if m.Author != "Grace Hopper, Alan Turing" {
  48. t.Errorf("Author = %q (profile URLs must not count as names)", m.Author)
  49. }
  50. if m.SiteName != "The Blog" {
  51. t.Errorf("SiteName = %q", m.SiteName)
  52. }
  53. if m.Image != "https://cdn.example/hero.png" {
  54. t.Errorf("Image = %q", m.Image)
  55. }
  56. if !m.Published.Equal(time.Date(2024, 11, 2, 0, 0, 0, 0, time.UTC)) {
  57. t.Errorf("Published = %v", m.Published)
  58. }
  59. }
  60. func TestReadPageMetaImages(t *testing.T) {
  61. base, _ := url.Parse("https://site.example/a")
  62. tests := map[string]string{
  63. `<meta name="twitter:image" content="https://site.example/t.jpg">`: "https://site.example/t.jpg",
  64. `<meta property="og:image" content="//cdn.example/x.jpg">`: "https://cdn.example/x.jpg",
  65. `<meta property="og:image" content="data:image/png;base64,AAAA">`: "",
  66. `<meta property="og:image" content="javascript:alert(1)">`: "",
  67. ``: "",
  68. }
  69. for head, want := range tests {
  70. if got := readPageMeta(parse(t, "<html><head>"+head+"</head></html>"), base).Image; got != want {
  71. t.Errorf("%s: Image = %q, want %q", head, got, want)
  72. }
  73. }
  74. }
  75. func TestExtractCoverImageAndFallbacks(t *testing.T) {
  76. a, err := extractFile(t, "photo-essay.html", "https://letterpress.example/essays/print-shop")
  77. if err != nil {
  78. t.Fatal(err)
  79. }
  80. if a.ImageURL != "https://letterpress.example/img/press.jpg" {
  81. t.Errorf("ImageURL = %q", a.ImageURL)
  82. }
  83. if a.SiteName != "Letterpress Weekly" || a.Author != "Grace Hopper" {
  84. t.Errorf("SiteName = %q, Author = %q", a.SiteName, a.Author)
  85. }
  86. }