package com.suno.android.gating import com.suno.android.gating.statsig.FeatureValue import com.suno.android.gating.statsig.StatsigFeatureDataSource import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic import org.junit.Assert import org.junit.Test class DefaultFeatureManagerTest { val statsigManager = mockk(relaxed = true) @Test fun `hasFeature returns correct gate boolean`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val enabledFeature = setupGateBooleanFeature(true) val disabledFeature = setupGateBooleanFeature(false) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val enabledActual = subject.hasFeature(enabledFeature) val disabledActual = subject.hasFeature(disabledFeature) Assert.assertTrue(enabledActual) Assert.assertFalse(disabledActual) } @Test fun `getFeatureValue returns correct gate boolean`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val enabledFeature = setupGateBooleanFeature(true) val disabledFeature = setupGateBooleanFeature(false) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val enabledActual = subject.getFeatureValue(enabledFeature) val disabledActual = subject.getFeatureValue(disabledFeature) Assert.assertEquals(FeatureValue.Boolean(true), enabledActual) Assert.assertEquals(FeatureValue.Boolean(false), disabledActual) } @Test fun `getFeatureValue returns correct parameterStore string`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val featureValue = FeatureValue.String("some string") val feature = setupParameterStoreFeature(featureValue) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(featureValue, actual) } @Test fun `hasFeature returns true for enabled experimentParam`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupExperimentParamFeature(FeatureValue.Boolean(true)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.hasFeature(feature) Assert.assertTrue(actual) } @Test fun `hasFeature returns false for disabled experimentParam`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupExperimentParamFeature(FeatureValue.Boolean(false)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.hasFeature(feature) Assert.assertFalse(actual) } @Test fun `hasFeature returns true for enabled parameterStore`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupParameterStoreFeature(FeatureValue.Boolean(true)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.hasFeature(feature) Assert.assertTrue(actual) } @Test fun `hasFeature returns false for disabled parameterStore`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupParameterStoreFeature(FeatureValue.Boolean(false)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.hasFeature(feature) Assert.assertFalse(actual) } @Test fun `getFeatureValue returns true for enabled experimentParam boolean`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupExperimentParamFeature(FeatureValue.Boolean(true)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(FeatureValue.Boolean(true), actual) } @Test fun `getFeatureValue returns false for disabled experimentParam boolean`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupExperimentParamFeature(FeatureValue.Boolean(false)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(FeatureValue.Boolean(false), actual) } @Test fun `getFeatureValue returns correct experimentParam string`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val featureValue = FeatureValue.String("experiment value") val feature = setupExperimentParamFeature(featureValue) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(featureValue, actual) } @Test fun `getFeatureValue returns correct experimentParam double`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val featureValue = FeatureValue.Double(42.5) val feature = setupExperimentParamFeature(featureValue) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(FeatureValue.Double(42.5), actual) } @Test fun `getFeatureValue returns true for enabled parameterStore boolean`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupParameterStoreFeature(FeatureValue.Boolean(true)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(FeatureValue.Boolean(true), actual) } @Test fun `getFeatureValue returns false for disabled parameterStore boolean`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val feature = setupParameterStoreFeature(FeatureValue.Boolean(false)) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(FeatureValue.Boolean(false), actual) } @Test fun `getFeatureValue returns correct parameterStore double`() { mockkStatic("com.suno.android.gating.FeatureManagerKt") val featureValue = FeatureValue.Double(123.45) val feature = setupParameterStoreFeature(featureValue) val subject = DefaultFeatureManager( statsigManager = statsigManager, ) val actual = subject.getFeatureValue(feature) Assert.assertEquals(featureValue, actual) } // Helper functions to reduce test duplication private fun setupGateBooleanFeature( value: Boolean, ): Feature { val feature = mockk>() val accessor = mockk(relaxed = true) every { feature.toStatsigAccessor() } returns accessor every { statsigManager.checkGate(accessor.featureGate) } returns value return feature } private fun setupExperimentParamFeature( statsigValue: T, ): Feature { val feature = mockk>() val accessor = mockk>(relaxed = true) every { feature.toStatsigAccessor() } returns accessor every { statsigManager.fetchExperimentParam(accessor.experiment) } returns statsigValue return feature } private fun setupParameterStoreFeature( statsigValue: T, ): Feature { val feature = mockk>() val accessor = mockk>(relaxed = true) every { feature.toStatsigAccessor() } returns accessor every { statsigManager.fetchParamStoreValue(accessor.paramStoreAccessor) } returns statsigValue return feature } }