diff --git a/library/build.gradle b/library/build.gradle index d7a00eb4..047aa604 100755 --- a/library/build.gradle +++ b/library/build.gradle @@ -30,8 +30,10 @@ android { versionCode 1 versionName '1.3.0' buildConfigField("String", "CLIENT_VERSION", "\"cioand-${versionName}\"") - buildConfigField("String", "AUTOCOMPLETE_SECTION", "\"Products\"") - buildConfigField("String", "BASE_API_URL", "\"https://ac.cnstrc.com\"") + buildConfigField("String", "DEFAULT_ITEM_SECTION", "\"Products\"") + buildConfigField("String", "SERVICE_URL", "\"ac.cnstrc.com\"") + buildConfigField("Integer", "SERVICE_PORT", "443") + buildConfigField("String", "SERVICE_SCHEME", "\"https\"") } buildTypes { diff --git a/library/src/main/java/io/constructor/core/ConstructorIo.kt b/library/src/main/java/io/constructor/core/ConstructorIo.kt index b2a0e689..86108ad8 100755 --- a/library/src/main/java/io/constructor/core/ConstructorIo.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIo.kt @@ -53,17 +53,23 @@ object ConstructorIo { throw IllegalStateException("context is null, please init library using ConstructorIo.with(context)") } this.context = context.applicationContext - dataManager = component.dataManager() - preferenceHelper = component.preferenceHelper() + configMemoryHolder = component.configMemoryHolder() configMemoryHolder.autocompleteResultCount = constructorIoConfig.autocompleteResultCount configMemoryHolder.testCellParams = constructorIoConfig.testCells - preferenceHelper.apiKey = constructorIoConfig.apiKey + preferenceHelper = component.preferenceHelper() + preferenceHelper.apiKey = constructorIoConfig.apiKey + preferenceHelper.serviceUrl = constructorIoConfig.serviceUrl + preferenceHelper.port = constructorIoConfig.servicePort + preferenceHelper.scheme = constructorIoConfig.serviceScheme preferenceHelper.defaultItemSection = constructorIoConfig.defaultItemSection if (preferenceHelper.id.isBlank()) { preferenceHelper.id = UUID.randomUUID().toString() } + + // Instantiate the data manager last (depends on the preferences helper) + dataManager = component.dataManager() } fun getSessionId() = preferenceHelper.getSessionId() diff --git a/library/src/main/java/io/constructor/core/ConstructorIoConfig.kt b/library/src/main/java/io/constructor/core/ConstructorIoConfig.kt index 61356839..c80a5871 100644 --- a/library/src/main/java/io/constructor/core/ConstructorIoConfig.kt +++ b/library/src/main/java/io/constructor/core/ConstructorIoConfig.kt @@ -3,6 +3,9 @@ package io.constructor.core import io.constructor.BuildConfig data class ConstructorIoConfig(val apiKey: String, + val serviceUrl: String = BuildConfig.SERVICE_URL, val autocompleteResultCount: Map = mapOf(Constants.QueryValues.SEARCH_SUGGESTIONS to 10, Constants.QueryValues.PRODUCTS to 0), - val defaultItemSection: String = BuildConfig.AUTOCOMPLETE_SECTION, - val testCells: List> = emptyList()) \ No newline at end of file + val defaultItemSection: String = BuildConfig.DEFAULT_ITEM_SECTION, + val testCells: List> = emptyList(), + val servicePort: Int = BuildConfig.SERVICE_PORT, + val serviceScheme: String = BuildConfig.SERVICE_SCHEME) \ No newline at end of file diff --git a/library/src/main/java/io/constructor/data/DataManager.kt b/library/src/main/java/io/constructor/data/DataManager.kt index aa1811e7..a0077e4c 100755 --- a/library/src/main/java/io/constructor/data/DataManager.kt +++ b/library/src/main/java/io/constructor/data/DataManager.kt @@ -1,7 +1,6 @@ package io.constructor.data import com.squareup.moshi.Moshi -import io.constructor.BuildConfig import io.constructor.data.model.Suggestion import io.constructor.data.model.search.SearchResponse import io.constructor.data.remote.ApiPaths @@ -30,7 +29,7 @@ constructor(private val constructorApi: ConstructorApi, private val moshi: Moshi }.toObservable() fun getSearchResults(text: String, encodedParams: Array> = arrayOf()): Observable> { - var dynamicUrl = BuildConfig.BASE_API_URL + "/${ApiPaths.URL_SEARCH.format(text)}" + var dynamicUrl = "/${ApiPaths.URL_SEARCH.format(text)}" encodedParams.forEachIndexed { index, pair -> dynamicUrl += "${if (index != 0) "&" else "?" }${pair.first}=${pair.second}" } diff --git a/library/src/main/java/io/constructor/data/interceptor/RequestInterceptor.kt b/library/src/main/java/io/constructor/data/interceptor/RequestInterceptor.kt index 82878ed0..c147b4cd 100755 --- a/library/src/main/java/io/constructor/data/interceptor/RequestInterceptor.kt +++ b/library/src/main/java/io/constructor/data/interceptor/RequestInterceptor.kt @@ -15,6 +15,7 @@ class RequestInterceptor(val context: Context, private val preferencesHelper: Pr override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() val builder = request.url().newBuilder() + .port(preferencesHelper.port) .addQueryParameter(Constants.QueryConstants.API_KEY, preferencesHelper.apiKey) .addQueryParameter(Constants.QueryConstants.IDENTITY, preferencesHelper.id) diff --git a/library/src/main/java/io/constructor/data/local/PreferencesHelper.kt b/library/src/main/java/io/constructor/data/local/PreferencesHelper.kt index 28600b26..170a5b69 100755 --- a/library/src/main/java/io/constructor/data/local/PreferencesHelper.kt +++ b/library/src/main/java/io/constructor/data/local/PreferencesHelper.kt @@ -30,6 +30,18 @@ constructor(@ApplicationContext context: Context, prefFileName: String = PREF_FI get() = preferences.getLong(SESSION_LAST_ACCESS, System.currentTimeMillis()) set(value) = preferences.edit().putLong(SESSION_LAST_ACCESS, value).apply() + var serviceUrl: String? + get() = preferences.getString(PREF_SERVICE_URL, "") + set(value) = preferences.edit().putString(PREF_SERVICE_URL, value).apply() + + var port: Int + get() = preferences.getInt(PREF_SERVICE_PORT, 443) + set(value) = preferences.edit().putInt(PREF_SERVICE_PORT, value).apply() + + var scheme: String? + get() = preferences.getString(PREF_SERVICE_SCHEME, "https") + set(value) = preferences.edit().putString(PREF_SERVICE_SCHEME, value).apply() + fun getSessionId(sessionIncrementAction: ((String) -> Unit)? = null, forceIncrement: Boolean = false): Int { if (!preferences.contains(SESSION_ID)) { return resetSession(sessionIncrementAction) @@ -65,6 +77,9 @@ constructor(@ApplicationContext context: Context, prefFileName: String = PREF_FI const val SESSION_ID = "session_id" const val SESSION_LAST_ACCESS = "session_last_access" const val SESSION_TIME_THRESHOLD = 1000 * 60 * 30 + const val PREF_SERVICE_URL = "service_url" + const val PREF_SERVICE_PORT = "service_port" + const val PREF_SERVICE_SCHEME = "service_scheme" } } \ No newline at end of file diff --git a/library/src/main/java/io/constructor/injection/module/NetworkModule.kt b/library/src/main/java/io/constructor/injection/module/NetworkModule.kt index bf0092f3..1889b78d 100755 --- a/library/src/main/java/io/constructor/injection/module/NetworkModule.kt +++ b/library/src/main/java/io/constructor/injection/module/NetworkModule.kt @@ -23,9 +23,9 @@ class NetworkModule(private val context: Context) { @Provides @Singleton - internal fun provideRetrofit(okHttpClient: OkHttpClient, moshi: Moshi): Retrofit = + internal fun provideRetrofit(okHttpClient: OkHttpClient, moshi: Moshi, preferencesHelper: PreferencesHelper): Retrofit = Retrofit.Builder() - .baseUrl(BuildConfig.BASE_API_URL) + .baseUrl(preferencesHelper.scheme + "://" + preferencesHelper.serviceUrl) .client(okHttpClient) .addConverterFactory(MoshiConverterFactory.create(moshi)) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) diff --git a/library/src/test/java/io/constructor/core/ConstructorIoAutocompleteTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoAutocompleteTest.kt index 9f097ee5..ce51e452 100644 --- a/library/src/test/java/io/constructor/core/ConstructorIoAutocompleteTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoAutocompleteTest.kt @@ -29,18 +29,25 @@ class ConstructorIoAutocompleteTest { @Before fun setup() { + mockServer = MockWebServer() + mockServer.start() + every { ctx.applicationContext } returns ctx + every { preferencesHelper.apiKey } returns "golden-key" every { preferencesHelper.id } returns "guido-the-guid" + every { preferencesHelper.serviceUrl } returns mockServer.hostName + every { preferencesHelper.port } returns mockServer.port + every { preferencesHelper.scheme } returns "http" + every { preferencesHelper.defaultItemSection } returns "Products" every { preferencesHelper.getSessionId(any(), any()) } returns 79 + every { configMemoryHolder.autocompleteResultCount } returns null every { configMemoryHolder.userId } returns "player-one" every { configMemoryHolder.testCellParams } returns emptyList() - mockServer = MockWebServer() - mockServer.start() val config = ConstructorIoConfig("dummyKey") - val dataManager = createTestDataManager(mockServer, preferencesHelper, configMemoryHolder, ctx) + val dataManager = createTestDataManager(preferencesHelper, configMemoryHolder, ctx) constructorIo.testInit(ctx, config, dataManager, preferencesHelper, configMemoryHolder) } diff --git a/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt b/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt index 36955b83..4fe202b1 100755 --- a/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorIoTrackingTest.kt @@ -29,19 +29,25 @@ class ConstructorIoTest { @Before fun setup() { + mockServer = MockWebServer() + mockServer.start() + every { ctx.applicationContext } returns ctx + every { preferencesHelper.apiKey } returns "copper-key" every { preferencesHelper.id } returns "wacko-the-guid" + every { preferencesHelper.serviceUrl } returns mockServer.hostName + every { preferencesHelper.port } returns mockServer.port + every { preferencesHelper.scheme } returns "http" + every { preferencesHelper.defaultItemSection } returns "Products" every { preferencesHelper.getSessionId(any(), any()) } returns 67 - every { preferencesHelper.defaultItemSection } returns "Products" + every { configMemoryHolder.autocompleteResultCount } returns null every { configMemoryHolder.userId } returns "player-three" every { configMemoryHolder.testCellParams } returns emptyList() - mockServer = MockWebServer() - mockServer.start() val config = ConstructorIoConfig("dummyKey") - val dataManager = createTestDataManager(mockServer, preferencesHelper, configMemoryHolder, ctx) + val dataManager = createTestDataManager(preferencesHelper, configMemoryHolder, ctx) constructorIo.testInit(ctx, config, dataManager, preferencesHelper, configMemoryHolder) } diff --git a/library/src/test/java/io/constructor/core/ConstructorioSearchTest.kt b/library/src/test/java/io/constructor/core/ConstructorioSearchTest.kt index d85c1010..cb4389cf 100644 --- a/library/src/test/java/io/constructor/core/ConstructorioSearchTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorioSearchTest.kt @@ -29,18 +29,25 @@ class ConstructorIoSearchTest { @Before fun setup() { + mockServer = MockWebServer() + mockServer.start() + every { ctx.applicationContext } returns ctx + every { preferencesHelper.apiKey } returns "silver-key" every { preferencesHelper.id } returns "guapo-the-guid" + every { preferencesHelper.serviceUrl } returns mockServer.hostName + every { preferencesHelper.port } returns mockServer.port + every { preferencesHelper.scheme } returns "http" + every { preferencesHelper.defaultItemSection } returns "Products" every { preferencesHelper.getSessionId(any(), any()) } returns 92 + every { configMemoryHolder.autocompleteResultCount } returns null every { configMemoryHolder.userId } returns "player-two" every { configMemoryHolder.testCellParams } returns emptyList() - mockServer = MockWebServer() - mockServer.start() val config = ConstructorIoConfig("dummyKey") - val dataManager = createTestDataManager(mockServer, preferencesHelper, configMemoryHolder, ctx) + val dataManager = createTestDataManager(preferencesHelper, configMemoryHolder, ctx) constructorIo.testInit(ctx, config, dataManager, preferencesHelper, configMemoryHolder) } diff --git a/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt b/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt index a2da62d9..f69e395e 100644 --- a/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt +++ b/library/src/test/java/io/constructor/core/ConstructorioTestCellTest.kt @@ -28,19 +28,25 @@ class ConstructorioTestCellTest { @Before fun setup() { + mockServer = MockWebServer() + mockServer.start() + every { ctx.applicationContext } returns ctx + every { preferencesHelper.apiKey } returns "aluminium-key" every { preferencesHelper.id } returns "koopa-the-guid" + every { preferencesHelper.serviceUrl } returns mockServer.hostName + every { preferencesHelper.port } returns mockServer.port + every { preferencesHelper.scheme } returns "http" + every { preferencesHelper.defaultItemSection } returns "Products" every { preferencesHelper.getSessionId(any(), any()) } returns 14 - every { preferencesHelper.defaultItemSection } returns "Products" + every { configMemoryHolder.autocompleteResultCount } returns null every { configMemoryHolder.userId } returns "player-two" every { configMemoryHolder.testCellParams } returns listOf("cellone" to "vanilla", "celltwo" to "whipped-cream") - mockServer = MockWebServer() - mockServer.start() - val config = ConstructorIoConfig("dummyKey", testCells = listOf("cellone" to "vanilla", "celltwo" to "whipped-cream")) - val dataManager = createTestDataManager(mockServer, preferencesHelper, configMemoryHolder, ctx) + val config = ConstructorIoConfig("dummyKey") + val dataManager = createTestDataManager(preferencesHelper, configMemoryHolder, ctx) constructorIo.testInit(ctx, config, dataManager, preferencesHelper, configMemoryHolder) } diff --git a/library/src/test/java/io/constructor/test/helpers.kt b/library/src/test/java/io/constructor/test/helpers.kt index c13ab139..b32021c3 100644 --- a/library/src/test/java/io/constructor/test/helpers.kt +++ b/library/src/test/java/io/constructor/test/helpers.kt @@ -6,40 +6,24 @@ import io.constructor.data.local.PreferencesHelper import io.constructor.data.memory.ConfigMemoryHolder import io.constructor.data.remote.ConstructorApi import io.constructor.injection.module.NetworkModule -import okhttp3.HttpUrl -import okhttp3.mockwebserver.MockWebServer import java.util.concurrent.TimeUnit /** * Creates a data manager that communicates with a Mock Web Server */ -fun createTestDataManager(mockServer : MockWebServer, - preferencesHelper: PreferencesHelper, +fun createTestDataManager(preferencesHelper: PreferencesHelper, configMemoryHolder: ConfigMemoryHolder, ctx: Context ): DataManager { - - val basePath = mockServer.url("") val networkModule = NetworkModule(ctx); val loggingInterceptor = networkModule.provideHttpLoggingInterceptor() val requestInterceptor = networkModule.provideRequestInterceptor(preferencesHelper, configMemoryHolder) val moshi = networkModule.provideMoshi() - - // Intercept all requests to the Constructor API and point them to a mock web server val okHttpClient = networkModule.provideOkHttpClient(loggingInterceptor, requestInterceptor).newBuilder().addInterceptor { chain -> var request = chain.request() - val requestUrl = request.url() - val newRequestUrl = HttpUrl.Builder().scheme(basePath.scheme()) - .encodedQuery(requestUrl.encodedQuery()) - .host(basePath.host()) - .port(basePath.port()) - .encodedPath(requestUrl.encodedPath()).build() - request = request.newBuilder() - .url(newRequestUrl) - .build() chain.proceed(request) }.readTimeout(1, TimeUnit.SECONDS).build() - val retrofit = networkModule.provideRetrofit(okHttpClient, moshi) + val retrofit = networkModule.provideRetrofit(okHttpClient, moshi, preferencesHelper) val constructorApi = retrofit.create(ConstructorApi::class.java) return DataManager(constructorApi, moshi); } \ No newline at end of file