diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/EntityLabels.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/EntityLabels.kt new file mode 100644 index 0000000000..567504e581 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/EntityLabels.kt @@ -0,0 +1,14 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +data class EntityLabels( + val sensitivity: SensitivityLabelInfo?, + val retention: List, + val hold: List +) diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableHoldLabelsRemoteOperation.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableHoldLabelsRemoteOperation.kt new file mode 100644 index 0000000000..65fd60da35 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableHoldLabelsRemoteOperation.kt @@ -0,0 +1,72 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.reflect.TypeToken +import com.nextcloud.common.NextcloudClient +import com.nextcloud.operations.GetMethod +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.resources.OCSRemoteOperation +import org.apache.commons.httpclient.HttpStatus + +/** + * Get the hold labels the user may apply to an entity + */ +class GetAvailableHoldLabelsRemoteOperation( + private val entityType: String, + private val entityId: Long +) : OCSRemoteOperation>() { + @Suppress("TooGenericExceptionCaught") + override fun run(client: NextcloudClient): RemoteOperationResult> { + var result: RemoteOperationResult> + var getMethod: GetMethod? = null + try { + getMethod = + GetMethod( + client.baseUri.toString() + ENDPOINT + entityType + "/" + entityId + + HOLD_AVAILABLE + JSON_FORMAT, + true + ) + val status = client.execute(getMethod) + if (status == HttpStatus.SC_OK) { + val labels = + getServerResponse( + getMethod, + object : TypeToken>>() {} + )?.ocs?.data + + if (labels != null) { + result = RemoteOperationResult(true, getMethod) + result.setResultData(labels) + } else { + result = RemoteOperationResult(false, getMethod) + } + } else { + result = RemoteOperationResult(false, getMethod) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Get available hold labels failed: " + result.logMessage, + result.exception + ) + } finally { + getMethod?.releaseConnection() + } + return result + } + + companion object { + private val TAG = GetAvailableHoldLabelsRemoteOperation::class.java.simpleName + private const val ENDPOINT = "/ocs/v2.php/apps/governance/v1/labels/" + private const val HOLD_AVAILABLE = "/hold/available" + } +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableRetentionLabelsRemoteOperation.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableRetentionLabelsRemoteOperation.kt new file mode 100644 index 0000000000..787940de5c --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableRetentionLabelsRemoteOperation.kt @@ -0,0 +1,72 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.reflect.TypeToken +import com.nextcloud.common.NextcloudClient +import com.nextcloud.operations.GetMethod +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.resources.OCSRemoteOperation +import org.apache.commons.httpclient.HttpStatus + +/** + * Get the retention labels the user may apply to an entity + */ +class GetAvailableRetentionLabelsRemoteOperation( + private val entityType: String, + private val entityId: Long +) : OCSRemoteOperation>() { + @Suppress("TooGenericExceptionCaught") + override fun run(client: NextcloudClient): RemoteOperationResult> { + var result: RemoteOperationResult> + var getMethod: GetMethod? = null + try { + getMethod = + GetMethod( + client.baseUri.toString() + ENDPOINT + entityType + "/" + entityId + + RETENTION_AVAILABLE + JSON_FORMAT, + true + ) + val status = client.execute(getMethod) + if (status == HttpStatus.SC_OK) { + val labels = + getServerResponse( + getMethod, + object : TypeToken>>() {} + )?.ocs?.data + + if (labels != null) { + result = RemoteOperationResult(true, getMethod) + result.setResultData(labels) + } else { + result = RemoteOperationResult(false, getMethod) + } + } else { + result = RemoteOperationResult(false, getMethod) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Get available retention labels failed: " + result.logMessage, + result.exception + ) + } finally { + getMethod?.releaseConnection() + } + return result + } + + companion object { + private val TAG = GetAvailableRetentionLabelsRemoteOperation::class.java.simpleName + private const val ENDPOINT = "/ocs/v2.php/apps/governance/v1/labels/" + private const val RETENTION_AVAILABLE = "/retention/available" + } +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableSensitivityLabelsRemoteOperation.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableSensitivityLabelsRemoteOperation.kt new file mode 100644 index 0000000000..f95ab4778b --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetAvailableSensitivityLabelsRemoteOperation.kt @@ -0,0 +1,72 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.reflect.TypeToken +import com.nextcloud.common.NextcloudClient +import com.nextcloud.operations.GetMethod +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.resources.OCSRemoteOperation +import org.apache.commons.httpclient.HttpStatus + +/** + * Get the sensitivity labels the user may apply to an entity + */ +class GetAvailableSensitivityLabelsRemoteOperation( + private val entityType: String, + private val entityId: Long +) : OCSRemoteOperation>() { + @Suppress("TooGenericExceptionCaught") + override fun run(client: NextcloudClient): RemoteOperationResult> { + var result: RemoteOperationResult> + var getMethod: GetMethod? = null + try { + getMethod = + GetMethod( + client.baseUri.toString() + ENDPOINT + entityType + "/" + entityId + + SENSITIVITY_AVAILABLE + JSON_FORMAT, + true + ) + val status = client.execute(getMethod) + if (status == HttpStatus.SC_OK) { + val labels = + getServerResponse( + getMethod, + object : TypeToken>>() {} + )?.ocs?.data + + if (labels != null) { + result = RemoteOperationResult(true, getMethod) + result.setResultData(labels) + } else { + result = RemoteOperationResult(false, getMethod) + } + } else { + result = RemoteOperationResult(false, getMethod) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Get available sensitivity labels failed: " + result.logMessage, + result.exception + ) + } finally { + getMethod?.releaseConnection() + } + return result + } + + companion object { + private val TAG = GetAvailableSensitivityLabelsRemoteOperation::class.java.simpleName + private const val ENDPOINT = "/ocs/v2.php/apps/governance/v1/labels/" + private const val SENSITIVITY_AVAILABLE = "/sensitivity/available" + } +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetEntityLabelsRemoteOperation.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetEntityLabelsRemoteOperation.kt new file mode 100644 index 0000000000..61c19fdbed --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GetEntityLabelsRemoteOperation.kt @@ -0,0 +1,70 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.reflect.TypeToken +import com.nextcloud.common.NextcloudClient +import com.nextcloud.operations.GetMethod +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.resources.OCSRemoteOperation +import org.apache.commons.httpclient.HttpStatus + +/** + * Get all labels applied to an entity, grouped by type, filtered to those visible to the calling user + */ +class GetEntityLabelsRemoteOperation( + private val entityType: String, + private val entityId: String +) : OCSRemoteOperation() { + @Suppress("TooGenericExceptionCaught") + override fun run(client: NextcloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var getMethod: GetMethod? = null + try { + getMethod = + GetMethod( + client.baseUri.toString() + ENDPOINT + entityType + "/" + entityId + JSON_FORMAT, + true + ) + val status = client.execute(getMethod) + if (status == HttpStatus.SC_OK) { + val entityLabels = + getServerResponse( + getMethod, + object : TypeToken>() {} + )?.ocs?.data + + if (entityLabels != null) { + result = RemoteOperationResult(true, getMethod) + result.setResultData(entityLabels) + } else { + result = RemoteOperationResult(false, getMethod) + } + } else { + result = RemoteOperationResult(false, getMethod) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Get entity labels failed: " + result.logMessage, + result.exception + ) + } finally { + getMethod?.releaseConnection() + } + return result + } + + companion object { + private val TAG = GetEntityLabelsRemoteOperation::class.java.simpleName + private const val ENDPOINT = "/ocs/v2.php/apps/governance/v1/labels/" + } +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/GovernanceLabelResponse.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GovernanceLabelResponse.kt new file mode 100644 index 0000000000..7bfa0fbeb1 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/GovernanceLabelResponse.kt @@ -0,0 +1,12 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +data class GovernanceLabelResponse( + val message: String +) diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/HoldLabelInfo.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/HoldLabelInfo.kt new file mode 100644 index 0000000000..75221e4047 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/HoldLabelInfo.kt @@ -0,0 +1,17 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +data class HoldLabelInfo( + val id: String, + val name: String, + val priority: Long, + val description: String, + val color: String, + val scopes: List +) diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/LabelScope.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/LabelScope.kt new file mode 100644 index 0000000000..50bea0e191 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/LabelScope.kt @@ -0,0 +1,18 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.annotations.SerializedName + +enum class LabelScope { + @SerializedName("FILES") + FILES, + + @SerializedName("MAILS") + MAILS +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/LabelType.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/LabelType.kt new file mode 100644 index 0000000000..1e7f1f4276 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/LabelType.kt @@ -0,0 +1,14 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +enum class LabelType(val value: String) { + SENSITIVITY("SENSITIVITY"), + RETENTION("RETENTION"), + HOLD("HOLD") +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/RemoveLabelRemoteOperation.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/RemoveLabelRemoteOperation.kt new file mode 100644 index 0000000000..38682a063c --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/RemoveLabelRemoteOperation.kt @@ -0,0 +1,73 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.reflect.TypeToken +import com.nextcloud.common.NextcloudClient +import com.nextcloud.operations.DeleteMethod +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.resources.OCSRemoteOperation +import org.apache.commons.httpclient.HttpStatus + +/** + * Remove a label from an entity + */ +class RemoveLabelRemoteOperation( + private val entityType: String, + private val entityId: Long, + private val labelType: LabelType, + private val labelId: String +) : OCSRemoteOperation() { + @Suppress("TooGenericExceptionCaught") + override fun run(client: NextcloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var deleteMethod: DeleteMethod? = null + try { + deleteMethod = + DeleteMethod( + client.baseUri.toString() + ENDPOINT + entityType + "/" + entityId + "/" + + labelType.value + "/" + labelId + JSON_FORMAT, + true + ) + val status = client.execute(deleteMethod) + if (status == HttpStatus.SC_OK) { + val response = + getServerResponse( + deleteMethod, + object : TypeToken>() {} + )?.ocs?.data + + if (response != null) { + result = RemoteOperationResult(true, deleteMethod) + result.resultData = response + } else { + result = RemoteOperationResult(false, deleteMethod) + } + } else { + result = RemoteOperationResult(false, deleteMethod) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Remove label from entity failed: " + result.logMessage, + result.exception + ) + } finally { + deleteMethod?.releaseConnection() + } + return result + } + + companion object { + private val TAG = RemoveLabelRemoteOperation::class.java.simpleName + private const val ENDPOINT = "/ocs/v2.php/apps/governance/v1/labels/" + } +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/RetentionLabelInfo.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/RetentionLabelInfo.kt new file mode 100644 index 0000000000..b9151bc3f8 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/RetentionLabelInfo.kt @@ -0,0 +1,17 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +data class RetentionLabelInfo( + val id: String, + val name: String, + val priority: Long, + val description: String, + val color: String, + val scopes: List +) diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelInfo.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelInfo.kt new file mode 100644 index 0000000000..c6a3a556b7 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelInfo.kt @@ -0,0 +1,17 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +data class SensitivityLabelInfo( + val id: String, + val name: String, + val priority: Long, + val description: String, + val color: String, + val scopes: List +) diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelScope.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelScope.kt new file mode 100644 index 0000000000..9ef8ae4cd4 --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelScope.kt @@ -0,0 +1,18 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.annotations.SerializedName + +enum class SensitivityLabelScope { + @SerializedName("FILES") + FILES, + + @SerializedName("MAILS") + MAILS +} diff --git a/library/src/main/java/com/nextcloud/android/lib/resources/governance/SetLabelRemoteOperation.kt b/library/src/main/java/com/nextcloud/android/lib/resources/governance/SetLabelRemoteOperation.kt new file mode 100644 index 0000000000..38ee9ef57f --- /dev/null +++ b/library/src/main/java/com/nextcloud/android/lib/resources/governance/SetLabelRemoteOperation.kt @@ -0,0 +1,77 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.reflect.TypeToken +import com.nextcloud.common.NextcloudClient +import com.nextcloud.operations.PostMethod +import com.owncloud.android.lib.common.operations.RemoteOperationResult +import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.ocs.ServerResponse +import com.owncloud.android.lib.resources.OCSRemoteOperation +import okhttp3.MediaType.Companion.toMediaTypeOrNull +import okhttp3.RequestBody.Companion.toRequestBody +import org.apache.commons.httpclient.HttpStatus + +/** + * Apply a label to an entity + */ +class SetLabelRemoteOperation( + private val entityType: String, + private val entityId: Long, + private val labelType: LabelType, + private val labelId: String +) : OCSRemoteOperation() { + @Suppress("TooGenericExceptionCaught") + override fun run(client: NextcloudClient): RemoteOperationResult { + var result: RemoteOperationResult + var postMethod: PostMethod? = null + try { + val body = "".toRequestBody("application/json".toMediaTypeOrNull()) + postMethod = + PostMethod( + client.baseUri.toString() + ENDPOINT + entityType + "/" + entityId + "/" + + labelType.value + "/" + labelId + JSON_FORMAT, + true, + body + ) + val status = client.execute(postMethod) + if (status == HttpStatus.SC_OK) { + val response = + getServerResponse( + postMethod, + object : TypeToken>() {} + )?.ocs?.data + + if (response != null) { + result = RemoteOperationResult(true, postMethod) + result.resultData = response + } else { + result = RemoteOperationResult(false, postMethod) + } + } else { + result = RemoteOperationResult(false, postMethod) + } + } catch (e: Exception) { + result = RemoteOperationResult(e) + Log_OC.e( + TAG, + "Apply label to entity failed: " + result.logMessage, + result.exception + ) + } finally { + postMethod?.releaseConnection() + } + return result + } + + companion object { + private val TAG = SetLabelRemoteOperation::class.java.simpleName + private const val ENDPOINT = "/ocs/v2.php/apps/governance/v1/labels/" + } +} diff --git a/library/src/main/java/com/owncloud/android/lib/resources/status/GetCapabilitiesRemoteOperation.java b/library/src/main/java/com/owncloud/android/lib/resources/status/GetCapabilitiesRemoteOperation.java index 3aca2ca3f7..d1a96fce37 100644 --- a/library/src/main/java/com/owncloud/android/lib/resources/status/GetCapabilitiesRemoteOperation.java +++ b/library/src/main/java/com/owncloud/android/lib/resources/status/GetCapabilitiesRemoteOperation.java @@ -162,6 +162,9 @@ public class GetCapabilitiesRemoteOperation extends RemoteOperation>() {}.type + val response: ServerResponse = Gson().fromJson(element, type) + + val data = response.ocs?.data + assertNotNull(data) + assertEquals("Label applied", data!!.message) + } +} diff --git a/library/src/test/java/com/nextcloud/android/lib/resources/governance/HoldLabelInfoParsingTest.kt b/library/src/test/java/com/nextcloud/android/lib/resources/governance/HoldLabelInfoParsingTest.kt new file mode 100644 index 0000000000..9efe0d9bce --- /dev/null +++ b/library/src/test/java/com/nextcloud/android/lib/resources/governance/HoldLabelInfoParsingTest.kt @@ -0,0 +1,66 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.Gson +import com.google.gson.JsonParser +import com.google.gson.reflect.TypeToken +import com.owncloud.android.lib.ocs.ServerResponse +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Test + +class HoldLabelInfoParsingTest { + @Test + fun parsesAvailableHoldLabelsResponse() { + val json = + """ + { + "ocs": { + "meta": { "status": "ok", "statuscode": 200, "message": "OK" }, + "data": [ + { + "id": "litigation-hold", + "name": "Litigation hold", + "priority": 30, + "description": "Preserve for legal proceedings", + "color": "#ff0000", + "scopes": ["FILES", "MAILS"] + }, + { + "id": "no-hold", + "name": "No hold", + "priority": 10, + "description": "No legal hold applied", + "color": "#00ff00", + "scopes": ["FILES"] + } + ] + } + } + """.trimIndent() + + val element = JsonParser.parseString(json) + val type = object : TypeToken>>() {}.type + val response: ServerResponse> = Gson().fromJson(element, type) + + val labels = response.ocs?.data + assertNotNull(labels) + assertEquals(2, labels!!.size) + + val first = labels[0] + assertEquals("litigation-hold", first.id) + assertEquals("Litigation hold", first.name) + assertEquals(30L, first.priority) + assertEquals("Preserve for legal proceedings", first.description) + assertEquals("#ff0000", first.color) + assertEquals(listOf(LabelScope.FILES, LabelScope.MAILS), first.scopes) + + assertEquals(listOf(LabelScope.FILES), labels[1].scopes) + } +} diff --git a/library/src/test/java/com/nextcloud/android/lib/resources/governance/LabelTypeTest.kt b/library/src/test/java/com/nextcloud/android/lib/resources/governance/LabelTypeTest.kt new file mode 100644 index 0000000000..9cfccf5dc9 --- /dev/null +++ b/library/src/test/java/com/nextcloud/android/lib/resources/governance/LabelTypeTest.kt @@ -0,0 +1,20 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import org.junit.Assert.assertEquals +import org.junit.Test + +class LabelTypeTest { + @Test + fun pathValuesMatchSpecEnum() { + assertEquals("SENSITIVITY", LabelType.SENSITIVITY.value) + assertEquals("RETENTION", LabelType.RETENTION.value) + assertEquals("HOLD", LabelType.HOLD.value) + } +} diff --git a/library/src/test/java/com/nextcloud/android/lib/resources/governance/RetentionLabelInfoParsingTest.kt b/library/src/test/java/com/nextcloud/android/lib/resources/governance/RetentionLabelInfoParsingTest.kt new file mode 100644 index 0000000000..14fd7df4dd --- /dev/null +++ b/library/src/test/java/com/nextcloud/android/lib/resources/governance/RetentionLabelInfoParsingTest.kt @@ -0,0 +1,66 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.Gson +import com.google.gson.JsonParser +import com.google.gson.reflect.TypeToken +import com.owncloud.android.lib.ocs.ServerResponse +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Test + +class RetentionLabelInfoParsingTest { + @Test + fun parsesAvailableRetentionLabelsResponse() { + val json = + """ + { + "ocs": { + "meta": { "status": "ok", "statuscode": 200, "message": "OK" }, + "data": [ + { + "id": "keep-10-years", + "name": "Keep 10 years", + "priority": 30, + "description": "Retain for ten years", + "color": "#ff0000", + "scopes": ["FILES", "MAILS"] + }, + { + "id": "no-retention", + "name": "No retention", + "priority": 10, + "description": "May be deleted any time", + "color": "#00ff00", + "scopes": ["FILES"] + } + ] + } + } + """.trimIndent() + + val element = JsonParser.parseString(json) + val type = object : TypeToken>>() {}.type + val response: ServerResponse> = Gson().fromJson(element, type) + + val labels = response.ocs?.data + assertNotNull(labels) + assertEquals(2, labels!!.size) + + val first = labels[0] + assertEquals("keep-10-years", first.id) + assertEquals("Keep 10 years", first.name) + assertEquals(30L, first.priority) + assertEquals("Retain for ten years", first.description) + assertEquals("#ff0000", first.color) + assertEquals(listOf(LabelScope.FILES, LabelScope.MAILS), first.scopes) + + assertEquals(listOf(LabelScope.FILES), labels[1].scopes) + } +} diff --git a/library/src/test/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelInfoParsingTest.kt b/library/src/test/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelInfoParsingTest.kt new file mode 100644 index 0000000000..b7659bae5b --- /dev/null +++ b/library/src/test/java/com/nextcloud/android/lib/resources/governance/SensitivityLabelInfoParsingTest.kt @@ -0,0 +1,66 @@ +/* + * Nextcloud Android Library + * + * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: MIT + */ + +package com.nextcloud.android.lib.resources.governance + +import com.google.gson.Gson +import com.google.gson.JsonParser +import com.google.gson.reflect.TypeToken +import com.owncloud.android.lib.ocs.ServerResponse +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Test + +class SensitivityLabelInfoParsingTest { + @Test + fun parsesAvailableSensitivityLabelsResponse() { + val json = + """ + { + "ocs": { + "meta": { "status": "ok", "statuscode": 200, "message": "OK" }, + "data": [ + { + "id": "confidential", + "name": "Confidential", + "priority": 30, + "description": "Restricted to a small group", + "color": "#ff0000", + "scopes": ["FILES", "MAILS"] + }, + { + "id": "public", + "name": "Public", + "priority": 10, + "description": "Anyone may access", + "color": "#00ff00", + "scopes": ["FILES"] + } + ] + } + } + """.trimIndent() + + val element = JsonParser.parseString(json) + val type = object : TypeToken>>() {}.type + val response: ServerResponse> = Gson().fromJson(element, type) + + val labels = response.ocs?.data + assertNotNull(labels) + assertEquals(2, labels!!.size) + + val first = labels[0] + assertEquals("confidential", first.id) + assertEquals("Confidential", first.name) + assertEquals(30L, first.priority) + assertEquals("Restricted to a small group", first.description) + assertEquals("#ff0000", first.color) + assertEquals(listOf(SensitivityLabelScope.FILES, SensitivityLabelScope.MAILS), first.scopes) + + assertEquals(listOf(SensitivityLabelScope.FILES), labels[1].scopes) + } +}