Coverage Summary for Class: SdkValidation (cloud.mindbox.mobile_sdk)
| Class |
Method, %
|
Branch, %
|
Line, %
|
Instruction, %
|
| SdkValidation |
66.7%
(4/6)
|
100%
(6/6)
|
84.6%
(11/13)
|
83.9%
(78/93)
|
| SdkValidation$Error |
0%
(0/3)
|
|
0%
(0/9)
|
0%
(0/83)
|
| SdkValidation$validateConfiguration$1 |
0%
(0/1)
|
0%
(0/24)
|
0%
(0/16)
|
0%
(0/106)
|
| Total |
40%
(4/10)
|
20%
(6/30)
|
28.9%
(11/38)
|
27.7%
(78/282)
|
package cloud.mindbox.mobile_sdk
import androidx.core.util.PatternsCompat
import cloud.mindbox.mobile_sdk.utils.LoggingExceptionHandler
internal object SdkValidation {
enum class Error(val critical: Boolean, val message: String) {
EMPTY_DOMAIN(true, "Domain must not be empty"),
INVALID_FORMAT_DOMAIN(true, "The domain format is not valid"),
INVALID_DOMAIN(true, "The domain is not valid"),
EMPTY_ENDPOINT(true, "Endpoint must not be empty"),
INVALID_DEVICE_ID(false, "Invalid previous device UUID format"),
INVALID_INSTALLATION_ID(false, "Invalid UUID format of previous installationId"),
INVALID_OPERATIONS_DOMAIN(true, "The operationsDomain is not valid");
override fun toString() = "$name(critical=$critical, message=$message)"
}
/**
* Strips http:// or https:// scheme and trailing slashes from [input].
* "https://api.mindbox.ru/" → "api.mindbox.ru"
* "api.mindbox.ru/" → "api.mindbox.ru"
*/
fun extractHost(input: String): String =
input.trim()
.removePrefix("https://")
.removePrefix("http://")
.trimEnd('/')
/**
* Returns a full base URL. If [hostOrUrl] already contains a scheme (http:// or https://),
* it is preserved. Otherwise https:// is prepended.
* "api.mindbox.ru" → "https://api.mindbox.ru"
* "http://proxy.example.com" → "http://proxy.example.com"
*/
fun toBaseUrl(hostOrUrl: String): String {
val trimmed = hostOrUrl.trim()
return if (trimmed.startsWith("http://") || trimmed.startsWith("https://")) {
trimmed.trimEnd('/')
} else {
"https://${trimmed.trimEnd('/')}"
}
}
/**
* Returns true if [domain] is a valid domain host, accepting optional http:// or https:// prefix
* and optional trailing slash.
*/
fun isValidDomain(domain: String): Boolean {
val host = extractHost(domain)
return host.isNotBlank() && isDomainValid(host)
}
fun validateConfiguration(
domain: String,
endpointId: String,
previousDeviceUUID: String,
previousInstallationId: String,
operationsDomain: String? = null,
) = LoggingExceptionHandler.runCatching(defaultValue = listOf()) {
mutableListOf<Error>().apply {
when {
domain.isBlank() -> add(Error.EMPTY_DOMAIN)
else -> {
val host = extractHost(domain)
when {
host.isBlank() -> add(Error.INVALID_FORMAT_DOMAIN)
!isDomainValid(host) -> add(Error.INVALID_DOMAIN)
}
}
}
if (endpointId.isBlank()) {
add(Error.EMPTY_ENDPOINT)
}
if (previousDeviceUUID.isNotEmpty() && !previousDeviceUUID.isUuid()) {
add(Error.INVALID_DEVICE_ID)
}
if (previousInstallationId.isNotEmpty() && !previousInstallationId.isUuid()) {
add(Error.INVALID_INSTALLATION_ID)
}
if (operationsDomain != null && !isValidDomain(operationsDomain)) {
add(Error.INVALID_OPERATIONS_DOMAIN)
}
}
}
private fun isDomainValid(domain: String) = PatternsCompat.DOMAIN_NAME.matcher(domain).matches()
}