package com.peachpasswords.ui.components import org.junit.Assert.assertArrayEquals import org.junit.Assert.assertEquals import org.junit.Assert.assertNull import org.junit.Test class FaviconsTest { @Test fun finds_rel_icon_href() { val html = """
""" assertEquals("/static/icon.png", extractIconHref(html)) } @Test fun finds_shortcut_icon_and_apple_touch_icon() { assertEquals( "/favicon-32.png", extractIconHref(""""""), ) assertEquals( "/apple.png", extractIconHref(""""""), ) } @Test fun skips_non_icon_links_and_returns_null_when_absent() { val html = """ """.trimIndent() assertNull(extractIconHref(html)) assertNull(extractIconHref("no head tags")) } @Test fun resolves_relative_absolute_and_protocol_relative_hrefs() { assertEquals("https://x.test/img/icon.png", resolveIconUrl("/img/icon.png", "x.test")) assertEquals("https://x.test/icon.png", resolveIconUrl("icon.png", "x.test")) assertEquals("https://cdn.x.test/i.ico", resolveIconUrl("//cdn.x.test/i.ico", "x.test")) assertEquals("https://x.test/a.ico", resolveIconUrl("http://x.test/a.ico", "x.test")) assertEquals("https://y.test/b.ico", resolveIconUrl("https://y.test/b.ico", "x.test")) } @Test fun rejects_data_and_javascript_hrefs() { assertNull(resolveIconUrl("data:image/png;base64,AAAA", "x.test")) assertNull(resolveIconUrl("javascript:void(0)", "x.test")) assertNull(resolveIconUrl(" ", "x.test")) } @Test fun unwraps_png_inside_ico_container() { val png = byteArrayOf(0x89.toByte(), 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 1, 2, 3) val ico = ByteArray(22 + png.size) ico[2] = 1 // ICO type ico[18] = 22 // data offset, little-endian png.copyInto(ico, 22) assertArrayEquals(png, decodeOrUnwrapIco(ico)) } @Test fun passes_non_ico_bytes_through_and_rejects_ico_without_png() { val png = byteArrayOf(0x89.toByte(), 0x50, 0x4E, 0x47, 1, 2, 3) assertArrayEquals(png, decodeOrUnwrapIco(png)) val icoBmp = ByteArray(22 + 4) icoBmp[2] = 1 icoBmp[18] = 22 assertNull(decodeOrUnwrapIco(icoBmp)) } }