package com.stevesoltys.backup.metadata import com.stevesoltys.backup.Utf8 import com.stevesoltys.backup.crypto.Crypto import com.stevesoltys.backup.getRandomString import io.mockk.mockk import org.json.JSONObject import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Test import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import kotlin.random.Random @TestInstance(PER_CLASS) class MetadataDecoderTest { private val crypto = mockk<Crypto>() private val encoder = MetadataWriterImpl(crypto) private val decoder = MetadataDecoderImpl() private val metadata = BackupMetadata( version = 1.toByte(), token = Random.nextLong(), androidVersion = Random.nextInt(), deviceName = getRandomString() ) private val metadataByteArray = encoder.encode(metadata) @Test fun `unexpected version should throw SecurityException`() { assertThrows(SecurityException::class.java) { decoder.decode(metadataByteArray, 2.toByte(), metadata.token) } } @Test fun `unexpected token should throw SecurityException`() { assertThrows(SecurityException::class.java) { decoder.decode(metadataByteArray, metadata.version, metadata.token - 1) } } @Test fun `expected version and token do not throw SecurityException`() { decoder.decode(metadataByteArray, metadata.version, metadata.token) } @Test fun `malformed JSON throws FormatException`() { assertThrows(FormatException::class.java) { decoder.decode("{".toByteArray(Utf8), metadata.version, metadata.token) } } @Test fun `missing fields throws FormatException`() { val json = JSONObject() json.put(JSON_VERSION, metadata.version.toInt()) json.put(JSON_TOKEN, metadata.token) json.put(JSON_ANDROID_VERSION, metadata.androidVersion) val jsonBytes = json.toString().toByteArray(Utf8) assertThrows(FormatException::class.java) { decoder.decode(jsonBytes, metadata.version, metadata.token) } } }