Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
63 changes: 55 additions & 8 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@ val perfAnalysis = project.hasProperty("perfAnalysis")

plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.google.services)
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.spotless)
alias(libs.plugins.kapt)
alias(libs.plugins.ksp)
alias(libs.plugins.kotlin.serialization)
alias(libs.plugins.kotlin.parcelize)
alias(libs.plugins.jetbrains.kotlin.android)
alias(libs.plugins.spotbugs)
alias(libs.plugins.detekt)
// needed to make renovate run without shot, as shot requires Android SDK
Expand Down Expand Up @@ -149,9 +152,27 @@ android {
dimension = "default"
}

// IONOS HiDrive Next brand. Shared white-label base lives in src/gplay,
// Payload in src/brandIonos
register("gplay") {
applicationId = "com.nextcloud.client"
applicationId = "com.ionos.hidrivenext"
dimension = "default"
versionCode = 20
val releaseNumber = 4
versionName = "$versionMajor.$versionMinor.$versionPatch.$releaseNumber"
isDefault = true
resConfigs("en", "de", "es", "fr", "it", "en-rUS", "es-rUS", "en-rCA", "fr-rCA", "es-rMX")
}

// HiDrive Next brand
// Payload in src/brandStrato
register("hidriveNext") {
applicationId = "com.strato.hidrivenext"
dimension = "default"
versionCode = 1
val releaseNumber = 1
versionName = "$versionMajor.$versionMinor.$versionPatch.$releaseNumber"
resConfigs("en", "de", "es", "fr", "it")
}

register("huawei") {
Expand Down Expand Up @@ -233,14 +254,29 @@ android {
getByName("androidTest") {
assets.srcDirs(files("$projectDir/schemas"))
}

// src/gplay holds the shared white-label base
getByName("gplay") {
res.srcDir("src/brandIonos/res")
assets.srcDir("src/brandIonos/assets")
}
getByName("hidriveNext") {
manifest.srcFile("src/gplay/AndroidManifest.xml")
java.srcDir("src/gplay/java")
res.srcDir("src/gplay/res")
res.srcDir("src/brandStrato/res")
assets.srcDir("src/brandStrato/assets")
}
getByName("androidTestHidriveNext") {
java.srcDir("src/androidTestGplay/java")
}
}

}

ksp.arg("room.schemaLocation", "$projectDir/schemas")
kapt.useBuildCache = true

// Configure KSP for test variants
ksp.arg("dagger.moduleName", project.name)
ksp.arg("room.schemaLocation", "$projectDir/schemas")

kotlin.compilerOptions.jvmTarget.set(JvmTarget.JVM_21)

Expand All @@ -251,6 +287,12 @@ spotless.kotlin {

detekt.config.setFrom("detekt.yml")

// Firebase config comes from google-services.json; flavors without the file keep their Firebase strings
googleServices {
missingGoogleServicesStrategy =
com.google.gms.googleservices.GoogleServicesPlugin.MissingGoogleServicesStrategy.WARN
}

if (shotTest) configure<ShotExtension> {
showOnlyFailingTestsInReports = ciBuild
// CI environment renders some shadows slightly different from local VMs
Expand Down Expand Up @@ -430,9 +472,9 @@ dependencies {

// region AppScan, document scanner not available on FDroid (generic) due to OpenCV binaries
// To enable the feature for another variant, add it here.
"gplayImplementation"(project(":appscan"))
"huaweiImplementation"(project(":appscan"))
"qaImplementation"(project(":appscan"))
"implementation"(project(":scanbot"))
// endregion

// region SpotBugs
Expand All @@ -444,9 +486,8 @@ dependencies {
implementation(libs.dagger)
implementation(libs.dagger.android)
implementation(libs.dagger.android.support)
ksp(libs.dagger.compiler)
ksp(libs.dagger.processor)
kspAndroidTest(libs.dagger.compiler)
kapt(libs.dagger.compiler)
kapt(libs.dagger.processor)
// endregion

// region Crypto
Expand Down Expand Up @@ -510,6 +551,7 @@ dependencies {

// region Google Play dependencies, upon each update first test: new registration, receive push
"gplayImplementation"(libs.bundles.gplay)
"hidriveNextImplementation"(libs.bundles.gplay)
// endregion

// region common
Expand All @@ -523,4 +565,9 @@ dependencies {

// kotlinx.serialization
implementation(libs.kotlinx.serialization.json)
implementation(libs.kotlinx.coroutines.guava)

// reactivex
implementation(libs.rxjava)
implementation(libs.rxandroid)
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,64 @@

package com.nextcloud.client.di

import com.ionos.scanbot.availability.Availability
import com.ionos.scanbot.di.qualifiers.Scanbot
import com.ionos.scanbot.di.qualifiers.ScanbotLicense
import com.nextcloud.client.documentscan.AppScanOptionalFeature
import dagger.BindsInstance
import dagger.Component
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertThrows
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

/**
* Unit test for [VariantModule] that tests the reflection-based approach
* to conditionally load the ScanPageContract.
*/
class VariantModuleTest {

private lateinit var component: TestVariantComponent
@Test
fun testAppScanWhenScanbotFeatureAndLicenseAvailableShouldBeAvailable() {
val feature = createAppScanOptionalFeature(isFeatureAvailable = true, isLicenseAvailable = true)

@Before
fun setup() {
component = DaggerVariantModuleTest_TestVariantComponent.create()
assertTrue(feature.isAvailable)
}

@Test
fun testAppScanWhenAvailableShouldReturnContract() {
val feature = component.appScanOptionalFeature()
fun testAppScanWhenScanbotFeatureNotAvailableShouldNotBeAvailable() {
val feature = createAppScanOptionalFeature(isFeatureAvailable = false, isLicenseAvailable = true)

assertTrue(feature.isAvailable)
assertNotEquals(AppScanOptionalFeature.Stub, feature)
assertFalse(feature.isAvailable)
}

@Test
fun testAppScanWhenScanbotLicenseNotAvailableShouldNotBeAvailable() {
val feature = createAppScanOptionalFeature(isFeatureAvailable = true, isLicenseAvailable = false)

assertNotNull(feature.getScanContract())
assertFalse(feature.isAvailable)
}

@Test
fun testAppScanShouldNotProvideScanContract() {
val feature = createAppScanOptionalFeature(isFeatureAvailable = true, isLicenseAvailable = true)

assertThrows(UnsupportedOperationException::class.java) { feature.getScanContract() }
}

private fun createAppScanOptionalFeature(
isFeatureAvailable: Boolean,
isLicenseAvailable: Boolean
): AppScanOptionalFeature = DaggerVariantModuleTest_TestVariantComponent.factory()
.create(Availability { isFeatureAvailable }, Availability { isLicenseAvailable })
.appScanOptionalFeature()

@Component(modules = [VariantModule::class])
interface TestVariantComponent {
fun appScanOptionalFeature(): AppScanOptionalFeature

@Component.Factory
interface Factory {
fun create(
@BindsInstance @Scanbot featureAvailability: Availability,
@BindsInstance @ScanbotLicense licenseAvailability: Availability
): TestVariantComponent
}
}
}
23 changes: 23 additions & 0 deletions app/src/brandIonos/assets/branding/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"version": 1,
"loginUrls": {
"byCountry": {
"DE": "https://storage.ionos.de/index.php/login/v2",
"GB": "https://storage.ionos.co.uk/index.php/login/v2",
"ES": "https://storage.ionos.es/index.php/login/v2",
"FR": "https://storage.ionos.fr/index.php/login/v2",
"IT": "https://storage.ionos.it/index.php/login/v2",
"US": "https://storage.ionos.com/index.php/login/v2",
"CA": "https://storage.ionos.ca/index.php/login/v2",
"MX": "https://storage.ionos.mx/index.php/login/v2"
},
"byLanguage": {
"de": "https://storage.ionos.de/index.php/login/v2",
"en": "https://storage.ionos.co.uk/index.php/login/v2",
"es": "https://storage.ionos.es/index.php/login/v2",
"fr": "https://storage.ionos.fr/index.php/login/v2",
"it": "https://storage.ionos.it/index.php/login/v2"
},
"default": "https://storage.ionos.co.uk/index.php/login/v2"
}
}
Loading
Loading