feat(mindmachine): implement Android MVP app scaffold, session flows, safety gating, and tests

This commit is contained in:
Tretzi
2026-03-10 22:50:50 -05:00
commit 83a0586d26
22 changed files with 2671 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
package com.mindmachine.mvp
import com.mindmachine.mvp.domain.Presets
import com.mindmachine.mvp.domain.VisualPattern
import org.junit.Assert.assertEquals
import org.junit.Test
class PresetDefaultsTest {
@Test
fun mvp_has_exactly_three_presets_with_spec_defaults() {
assertEquals(3, Presets.builtIn.size)
val relax = Presets.builtIn.first { it.id == "relax" }
val focus = Presets.builtIn.first { it.id == "focus" }
val sleep = Presets.builtIn.first { it.id == "sleep" }
assertEquals(10 * 60, relax.defaultDurationSec)
assertEquals(VisualPattern.PULSE, relax.visualPatternType)
assertEquals(6f, relax.blinkFrequencyHz)
assertEquals(15 * 60, focus.defaultDurationSec)
assertEquals(VisualPattern.FLASH, focus.visualPatternType)
assertEquals(10f, focus.blinkFrequencyHz)
assertEquals(20 * 60, sleep.defaultDurationSec)
assertEquals(VisualPattern.PULSE, sleep.visualPatternType)
assertEquals(3f, sleep.blinkFrequencyHz)
}
}

View File

@@ -0,0 +1,46 @@
package com.mindmachine.mvp
import com.mindmachine.mvp.domain.SessionMode
import com.mindmachine.mvp.domain.VisualPattern
import com.mindmachine.mvp.domain.SessionConfig
import com.mindmachine.mvp.session.SessionValidator
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNull
import org.junit.Test
class SessionValidatorTest {
private val valid = SessionConfig(
presetId = "relax",
durationSec = 600,
mode = SessionMode.AUDIO_VISUAL,
visualPatternType = VisualPattern.PULSE,
blinkFrequencyHz = 6f,
intensityPercent = 50,
carrierFrequencyHz = 200f,
binauralDifferenceHz = 6f,
)
@Test
fun valid_with_headset_passes() {
assertNull(SessionValidator.validate(valid, headsetAvailable = true))
}
@Test
fun audio_without_headset_is_blocked() {
val error = SessionValidator.validate(valid, headsetAvailable = false)
assertEquals("Stereo headphones are required for binaural audio. Connect headphones or switch to Visual-only.", error)
}
@Test
fun visual_only_without_headset_passes() {
assertNull(SessionValidator.validate(valid.copy(mode = SessionMode.VISUAL_ONLY), headsetAvailable = false))
}
@Test
fun out_of_range_values_are_blocked() {
assertEquals("Duration must be 1 to 30 minutes.", SessionValidator.validate(valid.copy(durationSec = 59), true))
assertEquals("Blink frequency must be 1.0 to 20.0 Hz.", SessionValidator.validate(valid.copy(blinkFrequencyHz = 21f), true))
assertEquals("Carrier frequency must be 80 to 400 Hz.", SessionValidator.validate(valid.copy(carrierFrequencyHz = 79f), true))
assertEquals("Binaural difference must be 0.5 to 20 Hz.", SessionValidator.validate(valid.copy(binauralDifferenceHz = 0.1f), true))
}
}