package net.siteed.audiostream import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNotNull import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Test /** * Unit tests for the new top-level `compression` field on [RecordingConfig] * and [CompressionConfig.fromMap] validation. */ class RecordingConfigCompressionTest { @Test fun acceptsValidCompressionConfig() { val options = mapOf( "sampleRate" to 16_000, "channels" to 1, "encoding" to "pcm_16bit", "compression" to mapOf( "format" to "aac", "bitrate" to 32_000, "container" to "adts" ) ) val result = RecordingConfig.fromMap(options) assertTrue("Expected parse success, got: ${result.exceptionOrNull()?.message}", result.isSuccess) val (config, _) = result.getOrNull()!! val compression = config.compression assertNotNull(compression) assertEquals("aac", compression!!.format) assertEquals(32_000, compression.bitrate) assertEquals("adts", compression.container) } @Test fun rejectsUnsupportedContainer() { val options = mapOf( "sampleRate" to 16_000, "compression" to mapOf( "format" to "aac", "bitrate" to 32_000, "container" to "m4a" ) ) val result = RecordingConfig.fromMap(options) assertTrue(result.isFailure) } @Test fun rejectsUnsupportedFormat() { val options = mapOf( "sampleRate" to 16_000, "compression" to mapOf( "format" to "opus", "bitrate" to 32_000, "container" to "adts" ) ) val result = RecordingConfig.fromMap(options) assertTrue(result.isFailure) } @Test fun rejectsBitrateBelowMin() { val options = mapOf( "sampleRate" to 16_000, "compression" to mapOf( "format" to "aac", "bitrate" to 8_000, "container" to "adts" ) ) val result = RecordingConfig.fromMap(options) assertTrue(result.isFailure) } @Test fun rejectsBitrateAboveMax() { val options = mapOf( "sampleRate" to 16_000, "compression" to mapOf( "format" to "aac", "bitrate" to 256_000, "container" to "adts" ) ) val result = RecordingConfig.fromMap(options) assertTrue(result.isFailure) } @Test fun rejectsSampleRateNotInAdtsTable() { // Note: RecordingConfig.fromMap enforces sample rate in {16000, 44100, 48000} // BEFORE validating compression, so a sample rate that the library doesn't // allow at all will hit that earlier failure. Use 44100 to confirm the // compression path succeeds for a rate that is in both the library's // allowlist and the ADTS table. val options = mapOf( "sampleRate" to 44_100, "compression" to mapOf( "format" to "aac", "bitrate" to 32_000, "container" to "adts" ) ) val result = RecordingConfig.fromMap(options) assertTrue("44100 Hz should be accepted for ADTS", result.isSuccess) } @Test fun defaultsMissingCompressionToNull() { val options = mapOf( "sampleRate" to 16_000 ) val result = RecordingConfig.fromMap(options) assertTrue(result.isSuccess) assertNull(result.getOrNull()!!.first.compression) } @Test fun disablesLegacyCompressedWhenNewCompressionSet() { val options = mapOf( "sampleRate" to 16_000, "output" to mapOf( "compressed" to mapOf( "enabled" to true, "format" to "aac", "bitrate" to 128_000 ) ), "compression" to mapOf( "format" to "aac", "bitrate" to 32_000, "container" to "adts" ) ) val result = RecordingConfig.fromMap(options) assertTrue("Expected parse success, got: ${result.exceptionOrNull()?.message}", result.isSuccess) val (config, _) = result.getOrNull()!! assertNotNull(config.compression) assertFalse("Legacy output.compressed must be disabled when new compression is set", config.output.compressed.enabled) } @Test fun acceptsCustomOutputDirectory() { val options = mapOf( "sampleRate" to 16_000, "compression" to mapOf( "format" to "aac", "bitrate" to 32_000, "container" to "adts", "outputDirectory" to "/tmp/custom-aac-dir" ) ) val result = RecordingConfig.fromMap(options) assertTrue(result.isSuccess) assertEquals("/tmp/custom-aac-dir", result.getOrNull()!!.first.compression?.outputDirectory) } }