mirror of
https://github.com/pawelorzech/Swoosh.git
synced 2026-03-31 20:15:41 +00:00
feat: add video and audio card support to MobiledocBuilder
- Add 8-param build() overload accepting videoUrl and audioUrl
- Video card: ["video",{"src":"url","loop":false}]
- Audio card: ["audio",{"src":"url"}]
- Card order: images -> video -> audio -> bookmark
- Add tests for video only, audio only, and all media types combined
This commit is contained in:
parent
2410d05bd6
commit
96e2799787
2 changed files with 159 additions and 0 deletions
|
|
@ -62,6 +62,24 @@ object MobiledocBuilder {
|
||||||
linkTitle: String?,
|
linkTitle: String?,
|
||||||
linkDescription: String?,
|
linkDescription: String?,
|
||||||
imageAlt: String?
|
imageAlt: String?
|
||||||
|
): String {
|
||||||
|
return build(text, imageUrls, linkUrl, linkTitle, linkDescription, imageAlt, null, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds mobiledoc JSON with support for images, video, audio, and bookmark cards.
|
||||||
|
*
|
||||||
|
* Card order: images -> video -> audio -> bookmark
|
||||||
|
*/
|
||||||
|
fun build(
|
||||||
|
text: String,
|
||||||
|
imageUrls: List<String>,
|
||||||
|
linkUrl: String?,
|
||||||
|
linkTitle: String?,
|
||||||
|
linkDescription: String?,
|
||||||
|
imageAlt: String?,
|
||||||
|
videoUrl: String?,
|
||||||
|
audioUrl: String?
|
||||||
): String {
|
): String {
|
||||||
val escapedText = escapeForJson(text).replace("\n", "\\n")
|
val escapedText = escapeForJson(text).replace("\n", "\\n")
|
||||||
|
|
||||||
|
|
@ -77,6 +95,20 @@ object MobiledocBuilder {
|
||||||
cardSections.add("[10,${cards.size - 1}]")
|
cardSections.add("[10,${cards.size - 1}]")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add video card if present
|
||||||
|
if (videoUrl != null) {
|
||||||
|
val escapedUrl = escapeForJson(videoUrl)
|
||||||
|
cards.add("""["video",{"src":"$escapedUrl","loop":false}]""")
|
||||||
|
cardSections.add("[10,${cards.size - 1}]")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add audio card if present
|
||||||
|
if (audioUrl != null) {
|
||||||
|
val escapedUrl = escapeForJson(audioUrl)
|
||||||
|
cards.add("""["audio",{"src":"$escapedUrl"}]""")
|
||||||
|
cardSections.add("[10,${cards.size - 1}]")
|
||||||
|
}
|
||||||
|
|
||||||
// Add bookmark card if link is present
|
// Add bookmark card if link is present
|
||||||
if (linkUrl != null) {
|
if (linkUrl != null) {
|
||||||
val escapedUrl = escapeForJson(linkUrl)
|
val escapedUrl = escapeForJson(linkUrl)
|
||||||
|
|
|
||||||
|
|
@ -597,4 +597,131 @@ class MobiledocBuilderTest {
|
||||||
val secondCard = cards.get(1).asJsonArray.get(1).asJsonObject
|
val secondCard = cards.get(1).asJsonArray.get(1).asJsonObject
|
||||||
assertEquals("", secondCard.get("alt").asString)
|
assertEquals("", secondCard.get("alt").asString)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- Video card tests ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with video only produces valid JSON with video card`() {
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Check this video", emptyList(), null, null, null, null,
|
||||||
|
"https://example.com/video.mp4", null
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
assertNotNull(json)
|
||||||
|
|
||||||
|
val cards = json.getAsJsonArray("cards")
|
||||||
|
assertEquals(1, cards.size())
|
||||||
|
val card = cards.get(0).asJsonArray
|
||||||
|
assertEquals("video", card.get(0).asString)
|
||||||
|
val cardData = card.get(1).asJsonObject
|
||||||
|
assertEquals("https://example.com/video.mp4", cardData.get("src").asString)
|
||||||
|
assertFalse(cardData.get("loop").asBoolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with video has correct sections`() {
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Text", emptyList(), null, null, null, null,
|
||||||
|
"https://example.com/video.mp4", null
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
val sections = json.getAsJsonArray("sections")
|
||||||
|
assertEquals("Should have text section + video card section", 2, sections.size())
|
||||||
|
|
||||||
|
val videoSection = sections.get(1).asJsonArray
|
||||||
|
assertEquals(10, videoSection.get(0).asInt)
|
||||||
|
assertEquals(0, videoSection.get(1).asInt)
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Audio card tests ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with audio only produces valid JSON with audio card`() {
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Listen to this", emptyList(), null, null, null, null,
|
||||||
|
null, "https://example.com/audio.mp3"
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
assertNotNull(json)
|
||||||
|
|
||||||
|
val cards = json.getAsJsonArray("cards")
|
||||||
|
assertEquals(1, cards.size())
|
||||||
|
val card = cards.get(0).asJsonArray
|
||||||
|
assertEquals("audio", card.get(0).asString)
|
||||||
|
val cardData = card.get(1).asJsonObject
|
||||||
|
assertEquals("https://example.com/audio.mp3", cardData.get("src").asString)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with audio has correct sections`() {
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Text", emptyList(), null, null, null, null,
|
||||||
|
null, "https://example.com/audio.mp3"
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
val sections = json.getAsJsonArray("sections")
|
||||||
|
assertEquals("Should have text section + audio card section", 2, sections.size())
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Combined: text + images + video + audio + bookmark ---
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with all media types produces valid JSON with correct card order`() {
|
||||||
|
val images = listOf("https://example.com/img1.jpg", "https://example.com/img2.jpg")
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Full post", images,
|
||||||
|
"https://link.com", "Link Title", "Link Desc",
|
||||||
|
"Alt text",
|
||||||
|
"https://example.com/video.mp4",
|
||||||
|
"https://example.com/audio.mp3"
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
assertNotNull(json)
|
||||||
|
|
||||||
|
val cards = json.getAsJsonArray("cards")
|
||||||
|
// 2 images + 1 video + 1 audio + 1 bookmark = 5 cards
|
||||||
|
assertEquals(5, cards.size())
|
||||||
|
|
||||||
|
// Verify card order: image, image, video, audio, bookmark
|
||||||
|
assertEquals("image", cards.get(0).asJsonArray.get(0).asString)
|
||||||
|
assertEquals("image", cards.get(1).asJsonArray.get(0).asString)
|
||||||
|
assertEquals("video", cards.get(2).asJsonArray.get(0).asString)
|
||||||
|
assertEquals("audio", cards.get(3).asJsonArray.get(0).asString)
|
||||||
|
assertEquals("bookmark", cards.get(4).asJsonArray.get(0).asString)
|
||||||
|
|
||||||
|
// Verify sections: 1 text + 5 card sections = 6
|
||||||
|
val sections = json.getAsJsonArray("sections")
|
||||||
|
assertEquals(6, sections.size())
|
||||||
|
|
||||||
|
// Verify card section indices are sequential
|
||||||
|
for (i in 0 until 5) {
|
||||||
|
val cardSection = sections.get(i + 1).asJsonArray
|
||||||
|
assertEquals(10, cardSection.get(0).asInt)
|
||||||
|
assertEquals(i, cardSection.get(1).asInt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with video and audio but no images produces correct cards`() {
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Media post", emptyList(), null, null, null, null,
|
||||||
|
"https://example.com/video.mp4",
|
||||||
|
"https://example.com/audio.mp3"
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
val cards = json.getAsJsonArray("cards")
|
||||||
|
assertEquals(2, cards.size())
|
||||||
|
assertEquals("video", cards.get(0).asJsonArray.get(0).asString)
|
||||||
|
assertEquals("audio", cards.get(1).asJsonArray.get(0).asString)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `build with video URL containing special chars produces valid JSON`() {
|
||||||
|
val result = MobiledocBuilder.build(
|
||||||
|
"Text", emptyList(), null, null, null, null,
|
||||||
|
"https://example.com/video?id=1&name=\"test\"", null
|
||||||
|
)
|
||||||
|
val json = JsonParser.parseString(result).asJsonObject
|
||||||
|
assertNotNull(json)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue