// SPDX-FileCopyrightText: © 2025 Olivier Meunier // // SPDX-License-Identifier: AGPL-3.0-only package microdata_test import ( "encoding/json" "strconv" "strings" "testing" "golang.org/x/net/html" "github.com/stretchr/testify/require" "codeberg.org/readeck/readeck/pkg/extract/microdata" ) func runParseHTML(src string, f func(t *testing.T, md *microdata.Microdata)) func(t *testing.T) { return func(t *testing.T) { root, err := html.Parse(strings.NewReader(src)) require.NoError(t, err) md, err := microdata.ParseNode(root, "https://example.org/") require.NoError(t, err) f(t, md) } } func runParseAndEncodeRaw(src string, expected string) func(t *testing.T) { return runParseHTML(src, func(t *testing.T, md *microdata.Microdata) { out := new(strings.Builder) enc := json.NewEncoder(out) enc.SetEscapeHTML(false) enc.SetIndent("", " ") require.NoError(t, enc.Encode(md.Raw())) require.JSONEq(t, expected, out.String()) }) } func TestParserSchemaOrg(t *testing.T) { // nolint:misspell tests := []struct { html string expected string }{ { `

Pirates of the Carribean: On Stranger Tides (2011)

Jack Sparrow and Barbossa embark on a quest to find the elusive fountain of youth, only to discover that Blackbeard and his daughter are after it too. Director:
Rob Marshall
Writers: , and 7 more credits Stars:
Johnny Depp,
Penelope Cruz,
Ian McShane
8/10 stars from 200 users. Reviews: 50.
`, `[{ "@context": "https://schema.org", "@type": "Movie", "actor": [ { "@type": "Person", "name": "Johnny Depp" }, { "@type": "Person", "name": "Penelope Cruz" }, { "@type": "Person", "name": "Ian McShane" } ], "aggregateRating": { "@type": "AggregateRating", "bestRating": "10", "ratingCount": "200", "ratingValue": "8", "reviewCount": "50" }, "author": [ { "@type": "Person", "name": "Ted Elliott" }, { "@type": "Person", "name": "Terry Rossio" } ], "description": "Jack Sparrow and Barbossa embark on a quest to find the elusive fountain of youth, only to discover that Blackbeard and his daughter are after it too.", "director": { "@type": "Person", "name": "Rob Marshall" }, "name": "Pirates of the Carribean: On Stranger Tides (2011)" }]`, }, { `
Watch Footloose
`, `[{ "@context": "https://schema.org", "@type": "Movie", "name": "Footloose", "potentialAction" : { "@type": "WatchAction", "target" : "http://example.com/player?id=123" } }]`, }, { `

Jaws 3-D

Jaws 3-D shown in 3D.

Location: ACME Cinemas 10 10

Jaws 3-D

Language: English

Film format: 3D

`, `[{ "@context": "https://schema.org", "@type": "ScreeningEvent", "name": "Jaws 3-D", "description": "Jaws 3-D shown in 3D.", "location": { "@type": "MovieTheater", "name": "ACME Cinemas 10", "screenCount": "10" }, "workPresented": { "@type": "Movie", "name": "Jaws 3-D", "sameAs": "https://www.imdb.com/title/tt0085750/" }, "inLanguage": "en", "videoFormat": "3D" }]`, }, { `

This example shows the addition of Accessibility metadata. Although these properties are not a formal enumeration, there is evolving consensus amongst accessibility experts for appropriate values for these properties. This example shows simple text values, as suggested by www.a11ymetadata.org.

Name:
Holt Physical Science
Brief Synopsis:
NIMAC-sourced textbook
Long Synopsis:
N/A
Book Quality:
Publisher Quality
Book Size:
598 Pages
ISBN-13:
9780030426599
Publisher:
Holt, Rinehart and Winston
Date of Addition:
06/08/10
Copyright Date:
2007
Copyrighted By:
Holt, Rinehart and Winston
Adult content:
No
Language:
English US
Essential Images:
861
Described Images:
910
Categories:
Educational Materials
Grade Levels:
Sixth grade, Seventh grade, Eighth grade
Submitted By:
Bookshare Staff
NIMAC:
This book is currently only available to public K-12 schools and organizations in the United States for use with students with an IEP, because it was created from files supplied by the NIMAC under these restrictions. Learn more in the NIMAC Support Center.

Reviews of Holt Physical Science (0 reviews)

0 - No Rating Yet
`, `[{ "@context": "https://schema.org", "@type": "Book", "accessibilityAPI": "ARIA", "accessibilityControl": [ "fullKeyboardControl", "fullMouseControl" ], "accessibilityFeature": [ "largePrint/CSSEnabled", "highContrast/CSSEnabled", "resizeText/CSSEnabled", "displayTransformability", "longDescription", "alternativeText" ], "accessibilityHazard": [ "noFlashingHazard", "noMotionSimulationHazard", "noSoundHazard" ], "aggregateRating": { "@type": "AggregateRating", "reviewCount": "0", "ratingValue": "0" }, "bookFormat": "EBook/DAISY3", "copyrightHolder": { "@type": "Organization", "name": "Holt, Rinehart and Winston" }, "copyrightYear": "2007", "description": "NIMAC-sourced textbook", "genre": "Educational Materials", "inLanguage": "en-US", "isFamilyFriendly": "true", "isbn": "9780030426599", "name": "Holt Physical Science", "numberOfPages": "598", "publisher": { "@type": "Organization", "name": "Holt, Rinehart and Winston" } }]`, }, { `

The Lancet

Volume 376, July 2010-December 2010

Published by Elsevier

Issues:

  • No. 9734 p 1-68
  • No. 9735 p 69-140
`, `[{ "@context": "https://schema.org", "@type": "Periodical", "issn": "0140-6736", "hasPart": { "@id": "vol376", "@type": "PublicationVolume", "volumeNumber": "376", "hasPart": [ { "@id": "iss9734", "@type": "PublicationIssue", "datePublished": "2010-07-03", "pageEnd": "68", "pageStart": "1", "issueNumber": "9734" }, { "@id": "iss9735", "@type": "PublicationIssue", "datePublished": "2010-07-03", "pageEnd": "140", "pageStart": "69", "issueNumber": "9735" } ] }, "name": "The Lancet", "publisher": "Elsevier" }]`, }, { `
Mom's World Famous Banana Bread By , May 8, 2009 Banana bread on a plate This classic banana bread recipe comes from my mom -- the walnuts add a nice texture and flavor to the banana bread. Prep Time: 15 minutes Cook time: 1 hour Yield: 1 loaf Tags: Low fat
Nutrition facts: 240 calories, 9 grams fat
Ingredients: - 3 or 4 ripe bananas, smashed - 1 egg - 3/4 cup of sugar ... Instructions: Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add the flour last. Pour the mixture into a loaf pan and bake for one hour. 140 comments:
From Janel, May 5 -- thank you, great recipe! ...
`, `[{ "@context": "https://schema.org", "@type": "Recipe", "author": "John Smith", "cookTime": "PT1H", "datePublished": "2009-05-08", "description": "This classic banana bread recipe comes from my mom -- the walnuts add a nice texture and flavor to the banana bread.", "image": "https://example.org/bananabread.jpg", "recipeIngredient": [ "3 or 4 ripe bananas, smashed", { "@type": "PropertyValue", "value": "1", "name": "egg" }, { "@type": "PropertyValue", "value": "3/4", "name": "sugar", "unitCode": "cup"} ], "interactionStatistic": { "@type": "InteractionCounter", "interactionType": "https://schema.org/CommentAction", "userInteractionCount": "140" }, "name": "Mom's World Famous Banana Bread", "nutrition": { "@type": "NutritionInformation", "calories": "240 calories", "fatContent": "9 grams fat" }, "prepTime": "PT15M", "recipeInstructions": "Preheat the oven to 350 degrees. Mix in the ingredients in a bowl. Add the flour last. Pour the mixture into a loaf pan and bake for one hour.", "recipeYield": "1 loaf", "suitableForDiet": "https://schema.org/LowFatDiet" }]`, }, { `

Avatar

Director: James Cameron (born )
Action
Fiction Science fiction Trailer

Pirates of the Carribean: On Stranger Tides (2011)

Jack Sparrow and Barbossa embark on a quest to find the elusive fountain of youth, only to discover that Blackbeard and his daughter are after it too. Director:
Rob Marshall
Writers: , and 7 more credits Stars:
Johnny Depp,
Penelope Cruz,
Ian McShane
8/10 stars from 200 users. Reviews: 50.
`, `[ { "@context": "http://schema.org", "@type": "Movie", "director": { "@type": "Person", "birthDate": "1954-08-16", "name": "James Cameron" }, "genre": ["Action", "Fiction", "Science fiction"], "name": "Avatar", "trailer": "https://example.org/movies/avatar-theatrical-trailer.html" }, { "@context": "https://schema.org", "@type": "Movie", "actor": [ { "@type": "Person", "name": "Johnny Depp" }, { "@type": "Person", "name": "Penelope Cruz" }, { "@type": "Person", "name": "Ian McShane" } ], "aggregateRating": { "@type": "AggregateRating", "bestRating": "10", "ratingCount": "200", "ratingValue": "8", "reviewCount": "50" }, "author": [ { "@type": "Person", "name": "Ted Elliott" }, { "@type": "Person", "name": "Terry Rossio" } ], "description": "Jack Sparrow and Barbossa embark on a quest to find the elusive fountain of youth, only to discover that Blackbeard and his daughter are after it too.", "director": { "@type": "Person", "name": "Rob Marshall" }, "name": "Pirates of the Carribean: On Stranger Tides (2011)" } ]`, }, } for i, test := range tests { t.Run(strconv.Itoa(i+1), runParseAndEncodeRaw(test.html, test.expected)) } } func TestMicrodataFeatures(t *testing.T) { // nolint:misspell tests := []struct { name string html string expected string }{ { "item scope", `

My name is Penelope.

`, `[{ "@context": "http://schema.org", "@type": "Person", "name": "Penelope" }]`, }, { "item ref", `

Rear Window is a movie from 1954.

`, `[{ "@context": "http://schema.org", "@type": "Movie", "description": "A homebound photographer spies on his neighbours.", "genre": "Thriller", "name": "Rear Window" }]`, }, { "item id", ` `, `[{ "@context": "http://schema.org", "@id": "urn:isbn:978-0141196404", "@type": "Book", "author": "Fred Hoyle", "title": "The Black Cloud" }]`, }, { "meta content", ` `, `[{ "@context": "http://schema.org", "@type": "Person", "length": "1.70" }]`, }, { "parse value", `
80 liters 25%
`, `[{ "@context": "http://schema.org", "@type": "Container", "capacity": "80", "volume": "25" }]`, }, { "unescape html", ` `, `[ { "@context": "http://schema.org", "@id": "urn:isbn:978-0141196404", "@type": "Book", "author": "Fred Hoyle", "title": "The Black · Cloud", "description": "Some · description", "abc": "A · B C" }, { "@context": "http://schema.org", "@id": "urn:isbn:978-0141196404", "@type": "Book", "author": "Fred Hoyle", "title": "The Black · Cloud", "description": "Some · description", "abc": "A · B C" } ]`, }, } for _, test := range tests { t.Run(test.name, runParseAndEncodeRaw(test.html, test.expected)) } } func TestInvalidJSON(t *testing.T) { // nolint:misspell tests := []struct { name string html string expected string }{ { "unescape html", ` `, `[{ "@context": "http://schema.org", "@id": "urn:isbn:978-0141196404", "@type": "Book", "author": "Fred Hoyle", "title": "The Black · Cloud", "description": "Some · description", "abc": "A · B C" }]`, }, } for _, test := range tests { root, err := html.Parse(strings.NewReader(test.html)) require.NoError(t, err) md, err := microdata.ParseNode(root, "https://example.org/") require.Error(t, err) require.Nil(t, md) } }