mirror of
https://github.com/jlengrand/OpenGraphKt.git
synced 2026-03-10 08:31:23 +00:00
Adds Generator
This commit is contained in:
337
opengraphkt/src/main/kotlin/fr/lengrand/opengraphkt/Generator.kt
Normal file
337
opengraphkt/src/main/kotlin/fr/lengrand/opengraphkt/Generator.kt
Normal file
@@ -0,0 +1,337 @@
|
||||
package fr.lengrand.opengraphkt
|
||||
|
||||
import java.time.OffsetDateTime
|
||||
|
||||
/**
|
||||
* A generator for Open Graph protocol HTML meta tags.
|
||||
*
|
||||
* This class converts an OpenGraph Data object into HTML meta tags according to the Open Graph protocol specification.
|
||||
* It can be used to generate the appropriate meta tags for embedding in HTML documents.
|
||||
*
|
||||
* @see <a href="https://ogp.me/">Open Graph Protocol</a>
|
||||
*/
|
||||
class Generator {
|
||||
|
||||
/**
|
||||
* Generates HTML meta tags from an OpenGraph Data object.
|
||||
*
|
||||
* @param data The OpenGraph Data object to convert to HTML meta tags
|
||||
* @return A string containing the HTML meta tags
|
||||
*/
|
||||
fun generate(data: Data): String {
|
||||
val tags = mutableListOf<String>()
|
||||
|
||||
// Add basic metadata tags
|
||||
addBasicMetaTags(data, tags)
|
||||
|
||||
// Add image tags
|
||||
addImageTags(data.images, tags)
|
||||
|
||||
// Add video tags
|
||||
addVideoTags(data.videos, tags)
|
||||
|
||||
// Add audio tags
|
||||
addAudioTags(data.audios, tags)
|
||||
|
||||
// Add type-specific tags
|
||||
when (data.getType()) {
|
||||
Type.ARTICLE -> addArticleTags(data.article, tags)
|
||||
Type.PROFILE -> addProfileTags(data.profile, tags)
|
||||
Type.BOOK -> addBookTags(data.book, tags)
|
||||
Type.MUSIC_SONG -> addMusicSongTags(data.musicSong, tags)
|
||||
Type.MUSIC_ALBUM -> addMusicAlbumTags(data.musicAlbum, tags)
|
||||
Type.MUSIC_PLAYLIST -> addMusicPlaylistTags(data.musicPlaylist, tags)
|
||||
Type.MUSIC_RADIO_STATION -> addMusicRadioStationTags(data.musicRadioStation, tags)
|
||||
Type.VIDEO_MOVIE, Type.VIDEO_TV_SHOW, Type.VIDEO_OTHER -> addVideoMovieTags(data.videoMovie, tags)
|
||||
Type.VIDEO_EPISODE -> addVideoEpisodeTags(data.videoEpisode, tags)
|
||||
else -> { /* No additional tags for other types */ }
|
||||
}
|
||||
|
||||
return tags.joinToString("\n")
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds basic Open Graph meta tags to the list.
|
||||
*
|
||||
* @param data The OpenGraph Data object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addBasicMetaTags(data: Data, tags: MutableList<String>) {
|
||||
// Required properties
|
||||
data.title?.let { tags.add(createMetaTag("og:title", it)) }
|
||||
data.type?.let { tags.add(createMetaTag("og:type", it)) }
|
||||
data.url?.let { tags.add(createMetaTag("og:url", it.toString())) }
|
||||
|
||||
// Optional properties
|
||||
data.description?.let { tags.add(createMetaTag("og:description", it)) }
|
||||
data.siteName?.let { tags.add(createMetaTag("og:site_name", it)) }
|
||||
data.determiner?.let { tags.add(createMetaTag("og:determiner", it)) }
|
||||
data.locale?.let { tags.add(createMetaTag("og:locale", it)) }
|
||||
|
||||
// Locale alternates
|
||||
data.localeAlternate.forEach { locale ->
|
||||
tags.add(createMetaTag("og:locale:alternate", locale))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds image meta tags to the list.
|
||||
*
|
||||
* @param images The list of Image objects
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addImageTags(images: List<Image>, tags: MutableList<String>) {
|
||||
images.forEach { image ->
|
||||
image.url?.let { tags.add(createMetaTag("og:image", it)) }
|
||||
image.secureUrl?.let { tags.add(createMetaTag("og:image:secure_url", it)) }
|
||||
image.type?.let { tags.add(createMetaTag("og:image:type", it)) }
|
||||
image.width?.let { tags.add(createMetaTag("og:image:width", it.toString())) }
|
||||
image.height?.let { tags.add(createMetaTag("og:image:height", it.toString())) }
|
||||
image.alt?.let { tags.add(createMetaTag("og:image:alt", it)) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds video meta tags to the list.
|
||||
*
|
||||
* @param videos The list of Video objects
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addVideoTags(videos: List<Video>, tags: MutableList<String>) {
|
||||
videos.forEach { video ->
|
||||
video.url?.let { tags.add(createMetaTag("og:video", it)) }
|
||||
video.secureUrl?.let { tags.add(createMetaTag("og:video:secure_url", it)) }
|
||||
video.type?.let { tags.add(createMetaTag("og:video:type", it)) }
|
||||
video.width?.let { tags.add(createMetaTag("og:video:width", it.toString())) }
|
||||
video.height?.let { tags.add(createMetaTag("og:video:height", it.toString())) }
|
||||
video.duration?.let { tags.add(createMetaTag("og:video:duration", it.toString())) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds audio meta tags to the list.
|
||||
*
|
||||
* @param audios The list of Audio objects
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addAudioTags(audios: List<Audio>, tags: MutableList<String>) {
|
||||
audios.forEach { audio ->
|
||||
audio.url?.let { tags.add(createMetaTag("og:audio", it)) }
|
||||
audio.secureUrl?.let { tags.add(createMetaTag("og:audio:secure_url", it)) }
|
||||
audio.type?.let { tags.add(createMetaTag("og:audio:type", it)) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds article-specific meta tags to the list.
|
||||
*
|
||||
* @param article The Article object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addArticleTags(article: Article?, tags: MutableList<String>) {
|
||||
if (article == null) return
|
||||
|
||||
article.publishedTime?.let { tags.add(createMetaTag("og:article:published_time", formatDateTime(it))) }
|
||||
article.modifiedTime?.let { tags.add(createMetaTag("og:article:modified_time", formatDateTime(it))) }
|
||||
article.expirationTime?.let { tags.add(createMetaTag("og:article:expiration_time", formatDateTime(it))) }
|
||||
article.section?.let { tags.add(createMetaTag("og:article:section", it)) }
|
||||
|
||||
article.authors.forEach { author ->
|
||||
tags.add(createMetaTag("og:article:author", author))
|
||||
}
|
||||
|
||||
article.tags.forEach { tag ->
|
||||
tags.add(createMetaTag("og:article:tag", tag))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds profile-specific meta tags to the list.
|
||||
*
|
||||
* @param profile The Profile object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addProfileTags(profile: Profile?, tags: MutableList<String>) {
|
||||
if (profile == null) return
|
||||
|
||||
profile.firstName?.let { tags.add(createMetaTag("og:profile:first_name", it)) }
|
||||
profile.lastName?.let { tags.add(createMetaTag("og:profile:last_name", it)) }
|
||||
profile.username?.let { tags.add(createMetaTag("og:profile:username", it)) }
|
||||
profile.gender?.let { tags.add(createMetaTag("og:profile:gender", it.toString())) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds book-specific meta tags to the list.
|
||||
*
|
||||
* @param book The Book object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addBookTags(book: Book?, tags: MutableList<String>) {
|
||||
if (book == null) return
|
||||
|
||||
book.authors.forEach { author ->
|
||||
tags.add(createMetaTag("og:book:author", author))
|
||||
}
|
||||
|
||||
book.isbn?.let { tags.add(createMetaTag("og:book:isbn", it)) }
|
||||
book.releaseDate?.let { tags.add(createMetaTag("og:book:release_date", formatDateTime(it))) }
|
||||
|
||||
book.tags.forEach { tag ->
|
||||
tags.add(createMetaTag("og:book:tag", tag))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds music.song-specific meta tags to the list.
|
||||
*
|
||||
* @param musicSong The MusicSong object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addMusicSongTags(musicSong: MusicSong?, tags: MutableList<String>) {
|
||||
if (musicSong == null) return
|
||||
|
||||
musicSong.duration?.let { tags.add(createMetaTag("og:music:duration", it.toString())) }
|
||||
musicSong.album?.let { tags.add(createMetaTag("og:music:album", it)) }
|
||||
musicSong.albumDisc?.let { tags.add(createMetaTag("og:music:album:disc", it.toString())) }
|
||||
musicSong.albumTrack?.let { tags.add(createMetaTag("og:music:album:track", it.toString())) }
|
||||
|
||||
musicSong.musician.forEach { musician ->
|
||||
tags.add(createMetaTag("og:music:musician", musician))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds music.album-specific meta tags to the list.
|
||||
*
|
||||
* @param musicAlbum The MusicAlbum object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addMusicAlbumTags(musicAlbum: MusicAlbum?, tags: MutableList<String>) {
|
||||
if (musicAlbum == null) return
|
||||
|
||||
musicAlbum.songs.forEach { song ->
|
||||
tags.add(createMetaTag("og:music:song", song))
|
||||
}
|
||||
|
||||
musicAlbum.songDisc?.let { tags.add(createMetaTag("og:music:song:disc", it.toString())) }
|
||||
musicAlbum.songTrack?.let { tags.add(createMetaTag("og:music:song:track", it.toString())) }
|
||||
|
||||
musicAlbum.musician.forEach { musician ->
|
||||
tags.add(createMetaTag("og:music:musician", musician))
|
||||
}
|
||||
|
||||
musicAlbum.releaseDate?.let { tags.add(createMetaTag("og:music:release_date", formatDateTime(it))) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds music.playlist-specific meta tags to the list.
|
||||
*
|
||||
* @param musicPlaylist The MusicPlaylist object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addMusicPlaylistTags(musicPlaylist: MusicPlaylist?, tags: MutableList<String>) {
|
||||
if (musicPlaylist == null) return
|
||||
|
||||
musicPlaylist.songs.forEach { song ->
|
||||
tags.add(createMetaTag("og:music:song", song))
|
||||
}
|
||||
|
||||
musicPlaylist.songDisc?.let { tags.add(createMetaTag("og:music:song:disc", it.toString())) }
|
||||
musicPlaylist.songTrack?.let { tags.add(createMetaTag("og:music:song:track", it.toString())) }
|
||||
musicPlaylist.creator?.let { tags.add(createMetaTag("og:music:creator", it)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds music.radio_station-specific meta tags to the list.
|
||||
*
|
||||
* @param musicRadioStation The MusicRadioStation object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addMusicRadioStationTags(musicRadioStation: MusicRadioStation?, tags: MutableList<String>) {
|
||||
if (musicRadioStation == null) return
|
||||
|
||||
musicRadioStation.creator?.let { tags.add(createMetaTag("og:music:creator", it)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds video.movie-specific meta tags to the list.
|
||||
*
|
||||
* @param videoMovie The VideoMovie object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addVideoMovieTags(videoMovie: VideoMovie?, tags: MutableList<String>) {
|
||||
if (videoMovie == null) return
|
||||
|
||||
videoMovie.actors.forEach { actor ->
|
||||
tags.add(createMetaTag("og:video:actor", actor))
|
||||
}
|
||||
|
||||
videoMovie.director.forEach { director ->
|
||||
tags.add(createMetaTag("og:video:director", director))
|
||||
}
|
||||
|
||||
videoMovie.writer.forEach { writer ->
|
||||
tags.add(createMetaTag("og:video:writer", writer))
|
||||
}
|
||||
|
||||
videoMovie.duration?.let { tags.add(createMetaTag("og:video:duration", it.toString())) }
|
||||
videoMovie.releaseDate?.let { tags.add(createMetaTag("og:video:release_date", formatDateTime(it))) }
|
||||
|
||||
videoMovie.tags.forEach { tag ->
|
||||
tags.add(createMetaTag("og:video:tag", tag))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds video.episode-specific meta tags to the list.
|
||||
*
|
||||
* @param videoEpisode The VideoEpisode object
|
||||
* @param tags The list to add the tags to
|
||||
*/
|
||||
private fun addVideoEpisodeTags(videoEpisode: VideoEpisode?, tags: MutableList<String>) {
|
||||
if (videoEpisode == null) return
|
||||
|
||||
videoEpisode.actors.forEach { actor ->
|
||||
tags.add(createMetaTag("og:video:actor", actor))
|
||||
}
|
||||
|
||||
videoEpisode.director.forEach { director ->
|
||||
tags.add(createMetaTag("og:video:director", director))
|
||||
}
|
||||
|
||||
videoEpisode.writer.forEach { writer ->
|
||||
tags.add(createMetaTag("og:video:writer", writer))
|
||||
}
|
||||
|
||||
videoEpisode.duration?.let { tags.add(createMetaTag("og:video:duration", it.toString())) }
|
||||
videoEpisode.releaseDate?.let { tags.add(createMetaTag("og:video:release_date", formatDateTime(it))) }
|
||||
|
||||
videoEpisode.tags.forEach { tag ->
|
||||
tags.add(createMetaTag("og:video:tag", tag))
|
||||
}
|
||||
|
||||
videoEpisode.series?.let { tags.add(createMetaTag("og:video:series", it)) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML meta tag with the given property and content.
|
||||
*
|
||||
* @param property The property attribute value
|
||||
* @param content The content attribute value
|
||||
* @return The HTML meta tag string
|
||||
*/
|
||||
private fun createMetaTag(property: String, content: String): String {
|
||||
val escapedContent = content.replace("\"", """)
|
||||
return "<meta property=\"$property\" content=\"$escapedContent\" />"
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an OffsetDateTime to a string suitable for OpenGraph tags.
|
||||
*
|
||||
* @param dateTime The OffsetDateTime to format
|
||||
* @return The formatted date string in ISO-8601 format with 'Z' timezone indicator
|
||||
*/
|
||||
private fun formatDateTime(dateTime: OffsetDateTime): String {
|
||||
return dateTime.toInstant().toString()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,329 @@
|
||||
package fr.lengrand.opengraphkt
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.net.URI
|
||||
import java.time.OffsetDateTime
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class GeneratorTest {
|
||||
|
||||
private val generator = Generator()
|
||||
|
||||
@Test
|
||||
fun `test generate with basic metadata`() {
|
||||
// Create a simple Data object with only basic metadata
|
||||
val data = Data(
|
||||
tags = emptyList(),
|
||||
title = "Test Title",
|
||||
type = "website",
|
||||
url = URI("https://example.com").toURL(),
|
||||
description = "Test Description",
|
||||
siteName = "Test Site",
|
||||
determiner = "the",
|
||||
locale = "en_US",
|
||||
localeAlternate = listOf("fr_FR", "es_ES"),
|
||||
images = emptyList(),
|
||||
videos = emptyList(),
|
||||
audios = emptyList(),
|
||||
article = null,
|
||||
profile = null,
|
||||
book = null,
|
||||
musicSong = null,
|
||||
musicAlbum = null,
|
||||
musicPlaylist = null,
|
||||
musicRadioStation = null,
|
||||
videoMovie = null,
|
||||
videoEpisode = null
|
||||
)
|
||||
|
||||
val html = generator.generate(data)
|
||||
|
||||
// Verify that all basic metadata tags are generated correctly
|
||||
assertTrue(html.contains("<meta property=\"og:title\" content=\"Test Title\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:type\" content=\"website\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:url\" content=\"https://example.com\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:description\" content=\"Test Description\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:site_name\" content=\"Test Site\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:determiner\" content=\"the\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:locale\" content=\"en_US\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:locale:alternate\" content=\"fr_FR\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:locale:alternate\" content=\"es_ES\" />"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test generate with images`() {
|
||||
// Create a Data object with images
|
||||
val data = Data(
|
||||
tags = emptyList(),
|
||||
title = "Test Title",
|
||||
type = "website",
|
||||
url = URI("https://example.com").toURL(),
|
||||
description = null,
|
||||
siteName = null,
|
||||
determiner = null,
|
||||
locale = null,
|
||||
localeAlternate = emptyList(),
|
||||
images = listOf(
|
||||
Image(
|
||||
url = "https://example.com/image1.jpg",
|
||||
secureUrl = "https://secure.example.com/image1.jpg",
|
||||
type = "image/jpeg",
|
||||
width = 800,
|
||||
height = 600,
|
||||
alt = "Test Image 1"
|
||||
),
|
||||
Image(
|
||||
url = "https://example.com/image2.png",
|
||||
secureUrl = null,
|
||||
type = "image/png",
|
||||
width = 1024,
|
||||
height = 768,
|
||||
alt = null
|
||||
)
|
||||
),
|
||||
videos = emptyList(),
|
||||
audios = emptyList(),
|
||||
article = null,
|
||||
profile = null,
|
||||
book = null,
|
||||
musicSong = null,
|
||||
musicAlbum = null,
|
||||
musicPlaylist = null,
|
||||
musicRadioStation = null,
|
||||
videoMovie = null,
|
||||
videoEpisode = null
|
||||
)
|
||||
|
||||
val html = generator.generate(data)
|
||||
|
||||
// Verify that all image tags are generated correctly
|
||||
assertTrue(html.contains("<meta property=\"og:image\" content=\"https://example.com/image1.jpg\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:secure_url\" content=\"https://secure.example.com/image1.jpg\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:type\" content=\"image/jpeg\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:width\" content=\"800\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:height\" content=\"600\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:alt\" content=\"Test Image 1\" />"))
|
||||
|
||||
assertTrue(html.contains("<meta property=\"og:image\" content=\"https://example.com/image2.png\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:type\" content=\"image/png\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:width\" content=\"1024\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:image:height\" content=\"768\" />"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test generate with article`() {
|
||||
// Create a Data object with article-specific metadata
|
||||
val data = Data(
|
||||
tags = emptyList(),
|
||||
title = "Test Article",
|
||||
type = "article",
|
||||
url = URI("https://example.com/article").toURL(),
|
||||
description = null,
|
||||
siteName = null,
|
||||
determiner = null,
|
||||
locale = null,
|
||||
localeAlternate = emptyList(),
|
||||
images = emptyList(),
|
||||
videos = emptyList(),
|
||||
audios = emptyList(),
|
||||
article = Article(
|
||||
publishedTime = OffsetDateTime.parse("2023-01-01T00:00:00Z"),
|
||||
modifiedTime = OffsetDateTime.parse("2023-01-02T12:00:00Z"),
|
||||
expirationTime = null,
|
||||
authors = listOf("John Doe", "Jane Smith"),
|
||||
section = "News",
|
||||
tags = listOf("test", "article")
|
||||
),
|
||||
profile = null,
|
||||
book = null,
|
||||
musicSong = null,
|
||||
musicAlbum = null,
|
||||
musicPlaylist = null,
|
||||
musicRadioStation = null,
|
||||
videoMovie = null,
|
||||
videoEpisode = null
|
||||
)
|
||||
|
||||
val html = generator.generate(data)
|
||||
|
||||
// Verify that all article-specific tags are generated correctly
|
||||
assertTrue(html.contains("<meta property=\"og:article:published_time\" content=\"2023-01-01T00:00:00Z\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:article:modified_time\" content=\"2023-01-02T12:00:00Z\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:article:section\" content=\"News\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:article:author\" content=\"John Doe\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:article:author\" content=\"Jane Smith\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:article:tag\" content=\"test\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:article:tag\" content=\"article\" />"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test generate with profile`() {
|
||||
// Create a Data object with profile-specific metadata
|
||||
val data = Data(
|
||||
tags = emptyList(),
|
||||
title = "Test Profile",
|
||||
type = "profile",
|
||||
url = URI("https://example.com/profile").toURL(),
|
||||
description = null,
|
||||
siteName = null,
|
||||
determiner = null,
|
||||
locale = null,
|
||||
localeAlternate = emptyList(),
|
||||
images = emptyList(),
|
||||
videos = emptyList(),
|
||||
audios = emptyList(),
|
||||
article = null,
|
||||
profile = Profile(
|
||||
firstName = "John",
|
||||
lastName = "Doe",
|
||||
username = "johndoe",
|
||||
gender = Gender.MALE
|
||||
),
|
||||
book = null,
|
||||
musicSong = null,
|
||||
musicAlbum = null,
|
||||
musicPlaylist = null,
|
||||
musicRadioStation = null,
|
||||
videoMovie = null,
|
||||
videoEpisode = null
|
||||
)
|
||||
|
||||
val html = generator.generate(data)
|
||||
|
||||
// Verify that all profile-specific tags are generated correctly
|
||||
assertTrue(html.contains("<meta property=\"og:profile:first_name\" content=\"John\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:profile:last_name\" content=\"Doe\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:profile:username\" content=\"johndoe\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:profile:gender\" content=\"male\" />"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test generate with video movie`() {
|
||||
// Create a Data object with video.movie-specific metadata
|
||||
val data = Data(
|
||||
tags = emptyList(),
|
||||
title = "Test Movie",
|
||||
type = "video.movie",
|
||||
url = URI("https://example.com/movie").toURL(),
|
||||
description = null,
|
||||
siteName = null,
|
||||
determiner = null,
|
||||
locale = null,
|
||||
localeAlternate = emptyList(),
|
||||
images = emptyList(),
|
||||
videos = listOf(
|
||||
Video(
|
||||
url = "https://example.com/movie.mp4",
|
||||
secureUrl = null,
|
||||
type = "video/mp4",
|
||||
width = 1280,
|
||||
height = 720,
|
||||
duration = 120
|
||||
)
|
||||
),
|
||||
audios = emptyList(),
|
||||
article = null,
|
||||
profile = null,
|
||||
book = null,
|
||||
musicSong = null,
|
||||
musicAlbum = null,
|
||||
musicPlaylist = null,
|
||||
musicRadioStation = null,
|
||||
videoMovie = VideoMovie(
|
||||
actors = listOf("Actor 1", "Actor 2"),
|
||||
director = listOf("Director"),
|
||||
writer = listOf("Writer 1", "Writer 2"),
|
||||
duration = 120,
|
||||
releaseDate = OffsetDateTime.parse("2023-01-01T00:00:00Z"),
|
||||
tags = listOf("action", "drama")
|
||||
),
|
||||
videoEpisode = null
|
||||
)
|
||||
|
||||
val html = generator.generate(data)
|
||||
|
||||
// Verify that all video.movie-specific tags are generated correctly
|
||||
assertTrue(html.contains("<meta property=\"og:video\" content=\"https://example.com/movie.mp4\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:type\" content=\"video/mp4\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:width\" content=\"1280\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:height\" content=\"720\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:duration\" content=\"120\" />"))
|
||||
|
||||
assertTrue(html.contains("<meta property=\"og:video:actor\" content=\"Actor 1\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:actor\" content=\"Actor 2\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:director\" content=\"Director\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:writer\" content=\"Writer 1\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:writer\" content=\"Writer 2\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:release_date\" content=\"2023-01-01T00:00:00Z\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:tag\" content=\"action\" />"))
|
||||
assertTrue(html.contains("<meta property=\"og:video:tag\" content=\"drama\" />"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test content escaping`() {
|
||||
// Create a Data object with content that needs escaping
|
||||
val data = Data(
|
||||
tags = emptyList(),
|
||||
title = "Test \"Quoted\" Title",
|
||||
type = "website",
|
||||
url = URI("https://example.com").toURL(),
|
||||
description = null,
|
||||
siteName = null,
|
||||
determiner = null,
|
||||
locale = null,
|
||||
localeAlternate = emptyList(),
|
||||
images = emptyList(),
|
||||
videos = emptyList(),
|
||||
audios = emptyList(),
|
||||
article = null,
|
||||
profile = null,
|
||||
book = null,
|
||||
musicSong = null,
|
||||
musicAlbum = null,
|
||||
musicPlaylist = null,
|
||||
musicRadioStation = null,
|
||||
videoMovie = null,
|
||||
videoEpisode = null
|
||||
)
|
||||
|
||||
val html = generator.generate(data)
|
||||
|
||||
// Verify that quotes are properly escaped
|
||||
assertTrue(html.contains("<meta property=\"og:title\" content=\"Test "Quoted" Title\" />"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `test round trip conversion`() {
|
||||
// Create a sample HTML with OpenGraph tags
|
||||
val sampleHtml = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Open Graph Example</title>
|
||||
<meta property="og:title" content="The Rock" />
|
||||
<meta property="og:type" content="video.movie" />
|
||||
<meta property="og:url" content="https://example.com/the-rock" />
|
||||
<meta property="og:image" content="https://example.com/rock.jpg" />
|
||||
<meta property="og:description" content="An action movie about a rock" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>Example Page</h1>
|
||||
</body>
|
||||
</html>
|
||||
""".trimIndent()
|
||||
|
||||
// Parse the HTML to get a Data object
|
||||
val parser = Parser()
|
||||
val data = parser.parse(sampleHtml)
|
||||
|
||||
// Generate HTML tags from the Data object
|
||||
val generatedHtml = generator.generate(data)
|
||||
|
||||
// Verify that all original tags are present in the generated HTML
|
||||
assertTrue(generatedHtml.contains("<meta property=\"og:title\" content=\"The Rock\" />"))
|
||||
assertTrue(generatedHtml.contains("<meta property=\"og:type\" content=\"video.movie\" />"))
|
||||
assertTrue(generatedHtml.contains("<meta property=\"og:url\" content=\"https://example.com/the-rock\" />"))
|
||||
assertTrue(generatedHtml.contains("<meta property=\"og:image\" content=\"https://example.com/rock.jpg\" />"))
|
||||
assertTrue(generatedHtml.contains("<meta property=\"og:description\" content=\"An action movie about a rock\" />"))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user