package pw.binom.viewmate.phone import pw.binom.viewmate.core.media.MirrorAudio import pw.binom.viewmate.core.media.MirrorFiles import pw.binom.viewmate.core.media.MirrorVideo import pw.binom.viewmate.core.phone.buildDownloadFiles import pw.binom.viewmate.core.phone.buildGlassesFileSpecs import pw.binom.viewmate.core.protocol.DownloadPhase import pw.binom.viewmate.core.protocol.DownloadProgress import java.io.File import java.nio.file.Files import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNull import kotlin.test.assertTrue class GlassesFilesTest { private fun tempDir(): File = Files.createTempDirectory("glasses-files-test").toFile() private fun mirrorFiles() = MirrorFiles( video = MirrorVideo(key = "v", url = "https://s3/mirror/video.mkv"), audios = listOf( MirrorAudio(index = 0, key = "a0", title = "Русский", url = "https://s3/mirror/audio-0.ogg"), MirrorAudio(index = 1, key = "a1", url = "https://s3/mirror/audio-1.ogg"), ), ) @Test fun buildDownloadFilesUsesPresignedUrlsAndNames() { val msg = buildDownloadFiles( itemId = "movie-1", title = "Interstellar", files = mirrorFiles(), sizes = emptyMap(), presign = { "$it?sig" }, ) assertEquals("movie-1", msg.itemId) assertEquals("Interstellar", msg.title) assertEquals(1, msg.files.size) assertEquals("video.mkv", msg.files[0].name) assertEquals("https://s3/mirror/video.mkv?sig", msg.files[0].url) } @Test fun buildDownloadFilesFillsKnownSizes() { val msg = buildDownloadFiles( itemId = "movie-1", title = "T", files = mirrorFiles(), sizes = mapOf("video" to 1_863_946_240L, "audio-0" to 68_157_440L), presign = { it }, ) assertEquals(1_863_946_240L, msg.files[0].sizeBytes) } @Test fun buildGlassesFileSpecsPresignsEveryFile() { val specs = buildGlassesFileSpecs( files = mirrorFiles(), sizes = emptyMap(), presign = { "signed-$it" }, ) assertEquals(1, specs.size) assertTrue(specs.all { it.url.startsWith("signed-") }) assertEquals("video.mkv", specs.single().name) } @Test fun glassesFileStateNullIsNone() { assertEquals(FileDownloadState.NONE to 0, glassesFileState(null)) } @Test fun glassesFileStateMapsPhases() { val done = DownloadProgress("i", "video.mkv", 100, 10, 10, DownloadPhase.DONE) assertEquals(FileDownloadState.DONE to 100, glassesFileState(done)) val downloading = DownloadProgress("i", "video.mkv", 45, 450, 1000, DownloadPhase.DOWNLOADING) assertEquals(FileDownloadState.DOWNLOADING to 45, glassesFileState(downloading)) val failed = DownloadProgress("i", "audio-0.ogg", 0, 5, 10, DownloadPhase.FAILED) assertEquals(FileDownloadState.FAILED to 0, glassesFileState(failed)) } @Test fun glassesFileStateClampsDownloadingPercent() { val p = DownloadProgress("i", "video.mkv", 150, 150, 100, DownloadPhase.DOWNLOADING) assertEquals(FileDownloadState.DOWNLOADING to 99, glassesFileState(p)) } @Test fun phoneFileStateFinalExistsIsDone() { val dir = tempDir() val final = File(dir, "video.mkv").apply { writeBytes(ByteArray(10)) } val part = File(dir, "video.mkv.part") assertEquals(FileDownloadState.DONE to 100, phoneFileState(final, part)) } @Test fun phoneFileStatePartIsDownloading() { val dir = tempDir() val final = File(dir, "video.mkv") val part = File(dir, "video.mkv.part").apply { writeBytes(ByteArray(10)) } assertEquals(FileDownloadState.DOWNLOADING to 0, phoneFileState(final, part)) } @Test fun phoneFileStateNoneWhenNothing() { val dir = tempDir() assertEquals(FileDownloadState.NONE to 0, phoneFileState(File(dir, "video.mkv"), File(dir, "video.mkv.part"))) } @Test fun glassesOverallPercentEmptyIsNull() { assertNull(glassesOverallPercent(listOf("video.mkv", "audio-0.ogg"), emptyMap(), emptyMap())) } @Test fun glassesOverallPercentAllDoneIsHundred() { val names = listOf("video.mkv", "audio-0.ogg") val perFile = mapOf( "video.mkv" to DownloadProgress("i", "video.mkv", 100, 100, 100, DownloadPhase.DONE), "audio-0.ogg" to DownloadProgress("i", "audio-0.ogg", 100, 50, 50, DownloadPhase.DONE), ) assertEquals(100, glassesOverallPercent(names, emptyMap(), perFile)) } @Test fun glassesOverallPercentUsesKnownSizes() { val names = listOf("video.mkv", "audio-0.ogg") val known = mapOf("video.mkv" to 100L, "audio-0.ogg" to 100L) val perFile = mapOf( "video.mkv" to DownloadProgress("i", "video.mkv", 100, 100, 100, DownloadPhase.DONE), "audio-0.ogg" to DownloadProgress("i", "audio-0.ogg", 25, 25, 100, DownloadPhase.DOWNLOADING), ) assertEquals(62, glassesOverallPercent(names, known, perFile)) // 125/200 } @Test fun glassesOverallPercentFallsBackToStartedTotals() { val names = listOf("video.mkv", "audio-0.ogg") val perFile = mapOf( "video.mkv" to DownloadProgress("i", "video.mkv", 50, 50, 100, DownloadPhase.DOWNLOADING), ) assertEquals(50, glassesOverallPercent(names, emptyMap(), perFile)) } @Test fun glassesLivePercentRejectsEmpty() { assertNull(glassesLivePercent(emptyMap())) } @Test fun glassesLivePercentAllDoneIsHundred() { val perFile = mapOf( "video.mkv" to DownloadProgress("i", "video.mkv", 100, 100, 100, DownloadPhase.DONE), ) assertEquals(100, glassesLivePercent(perFile)) } }