2844d6a3ac
Телефон качает audio-N.ogg (audioKeys вместо fileKeys, стадия «звук»), очки получают DownloadFiles только с video.mkv (buildGlassesFileSpecs). Watch проверяет готовность обоих: телефон — audioReady(), очки — как было; отказ с подсказкой «Скачать на телефон/очки». Тесты: lib-core 19, phone 36.
166 lines
5.8 KiB
Kotlin
166 lines
5.8 KiB
Kotlin
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))
|
|
}
|
|
}
|