Initial QSfera import

This commit is contained in:
Курнат Андрей
2026-06-07 10:20:04 +03:00
commit 2315f25754
16485 changed files with 4826827 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
compileSdkVersion sdkCompileVersion
defaultConfig {
minSdkVersion sdkMinVersion
targetSdkVersion sdkTargetVersion
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_17.toString()
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
namespace "eu.qsfera.android.testutil"
}
dependencies {
implementation project(':qsferaDomain')
implementation project(':qsferaData')
implementation project(':qsferaComLibrary')
implementation libs.kotlin.stdlib
implementation libs.androidx.lifecycle.livedata.ktx
// Detekt
detektPlugins libs.detekt.formatting
detektPlugins libs.detekt.libraries
}
tasks.withType(io.gitlab.arturbosch.detekt.Detekt).configureEach {
jvmTarget = "17"
}
+21
View File
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
@@ -0,0 +1 @@
<manifest />
@@ -0,0 +1,67 @@
/**
* qsfera Android client application
*
* @author David González Verdugo
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import android.accounts.Account
const val OC_ACCOUNT_ID = "username"
const val OC_ACCOUNT_NAME = "$OC_ACCOUNT_ID@demo.qsfera.eu"
/**
* Accounts
*/
val OC_ACCOUNT = getAccount()
fun getAccount(name: String = OC_ACCOUNT_NAME, type: String = "qsfera"): Account {
val account = Account(name, type)
// We need reflection or account will be Account(null, null) because name and type are final
with(account.javaClass.getDeclaredField("name")) {
isAccessible = true
set(account, name)
}
with(account.javaClass.getDeclaredField("type")) {
isAccessible = true
set(account, type)
}
return account
}
/**
* BasicCredentials
*/
const val OC_BASIC_USERNAME = "user"
const val OC_BASIC_PASSWORD = "password"
/**
* OAuth
*/
const val OC_OAUTH_SUPPORTED_TRUE = "TRUE"
const val OC_AUTH_TOKEN_TYPE = "qsfera.oauth2.access_token"
const val OC_ACCESS_TOKEN = "Asqweh12p93yehd10eu"
const val OC_REFRESH_TOKEN = "P3sd19DSsjdp1jwdd1"
const val OC_SCOPE = "email"
const val OC_REDIRECT_URI = "qsfera://android.qsfera"
const val OC_TOKEN_ENDPOINT = "https://qsfera.server/token"
const val OC_CLIENT_AUTH = "cl13nt4uth"
const val OC_CLIENT_SECRET = "cl13nts3cr3t"
const val OC_CLIENT_ID = "cl13nt1d"
const val OC_CLIENT_SECRET_EXPIRATION = 1611251163
@@ -0,0 +1,50 @@
package eu.qsfera.android.testutil
import eu.qsfera.android.data.appregistry.db.AppRegistryEntity
import eu.qsfera.android.domain.appregistry.model.AppRegistry
import eu.qsfera.android.domain.appregistry.model.AppRegistryMimeType
import eu.qsfera.android.lib.resources.appregistry.responses.AppRegistryMimeTypeResponse
import eu.qsfera.android.lib.resources.appregistry.responses.AppRegistryResponse
val OC_APP_REGISTRY_MIMETYPE = AppRegistryMimeType(
mimeType = "DIR",
ext = "appRegistryMimeTypes.ext",
appProviders = emptyList(),
name = "appRegistryMimeTypes.name",
icon = "appRegistryMimeTypes.icon",
description = "appRegistryMimeTypes.description",
allowCreation = true,
defaultApplication = "appRegistryMimeTypes.defaultApplication",
)
val OC_APP_REGISTRY_ENTITY = AppRegistryEntity(
accountName = OC_ACCOUNT_NAME,
mimeType = "DIR",
ext = "appRegistryMimeTypes.ext",
appProviders = "[]",
name = "appRegistryMimeTypes.name",
icon = "appRegistryMimeTypes.icon",
description = "appRegistryMimeTypes.description",
allowCreation = true,
defaultApplication = "appRegistryMimeTypes.defaultApplication",
)
val OC_APP_REGISTRY = AppRegistry(
accountName = OC_ACCOUNT_NAME,
mimetypes = listOf(OC_APP_REGISTRY_MIMETYPE)
)
val OC_APP_REGISTRY_RESPONSE = AppRegistryResponse(
value = listOf(
AppRegistryMimeTypeResponse(
mimeType = "DIR",
ext = "appRegistryMimeTypes.ext",
appProviders = emptyList(),
name = "appRegistryMimeTypes.name",
icon = "appRegistryMimeTypes.icon",
description = "appRegistryMimeTypes.description",
allowCreation = true,
defaultApplication = "appRegistryMimeTypes.defaultApplication",
)
)
)
@@ -0,0 +1,80 @@
/**
* qsfera Android client application
*
* @author Aitor Ballesteros Pavón
*
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.capabilities.model.CapabilityBooleanType
import eu.qsfera.android.domain.capabilities.model.OCCapability
val OC_CAPABILITY =
OCCapability(
accountName = OC_ACCOUNT_NAME,
versionMajor = 2,
versionMinor = 1,
versionMicro = 0,
versionString = "1.0.0",
versionEdition = "1.0.0",
corePollInterval = 0,
davChunkingVersion = "1.0",
filesSharingApiEnabled = CapabilityBooleanType.TRUE,
filesSharingPublicEnabled = CapabilityBooleanType.TRUE,
filesSharingPublicPasswordEnforced = CapabilityBooleanType.FALSE,
filesSharingPublicPasswordEnforcedReadOnly = CapabilityBooleanType.FALSE,
filesSharingPublicPasswordEnforcedReadWrite = CapabilityBooleanType.FALSE,
filesSharingPublicPasswordEnforcedUploadOnly = CapabilityBooleanType.FALSE,
filesSharingPublicExpireDateEnabled = CapabilityBooleanType.FALSE,
filesSharingPublicExpireDateDays = 0,
filesSharingPublicExpireDateEnforced = CapabilityBooleanType.FALSE,
filesSharingPublicUpload = CapabilityBooleanType.FALSE,
filesSharingPublicMultiple = CapabilityBooleanType.FALSE,
filesSharingPublicSupportsUploadOnly = CapabilityBooleanType.FALSE,
filesSharingResharing = CapabilityBooleanType.FALSE,
filesSharingFederationOutgoing = CapabilityBooleanType.FALSE,
filesSharingFederationIncoming = CapabilityBooleanType.FALSE,
filesSharingUserProfilePicture = CapabilityBooleanType.FALSE,
filesBigFileChunking = CapabilityBooleanType.FALSE,
filesUndelete = CapabilityBooleanType.FALSE,
filesVersioning = CapabilityBooleanType.FALSE,
filesPrivateLinks = CapabilityBooleanType.TRUE,
filesAppProviders = null,
filesTusSupport = null,
spaces = null,
passwordPolicy = null,
)
val OC_CAPABILITY_WITH_FILES_APP_PROVIDERS = OC_CAPABILITY.copy(
filesAppProviders = OCCapability.AppProviders(
enabled = true,
version = "1.1.1",
appsUrl = "/app-url",
openUrl = "/open-url",
openWebUrl = "/open-with-web",
newUrl = "/new-url",
)
)
val OC_CAPABILITY_WITH_MULTIPERSONAL_ENABLED = OC_CAPABILITY.copy(
spaces = OCCapability.Spaces(
enabled = true,
projects = true,
shareJail = null,
hasMultiplePersonalSpaces = true
)
)
@@ -0,0 +1,290 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.data.files.db.OCFileAndFileSync
import eu.qsfera.android.data.files.db.OCFileEntity
import eu.qsfera.android.data.files.db.OCFileSyncEntity
import eu.qsfera.android.domain.availableoffline.model.AvailableOfflineStatus
import eu.qsfera.android.domain.files.model.OCFile
import eu.qsfera.android.domain.files.model.OCFileWithSyncInfo
import eu.qsfera.android.domain.files.model.OCMetaFile
import eu.qsfera.android.lib.resources.files.RemoteFile
import eu.qsfera.android.lib.resources.files.RemoteMetaFile
val OC_FOLDER = OCFile(
id = 122,
parentId = 123,
remotePath = "/Photos",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2hay",
privateLink = "http://server.url/f/3",
creationTimestamp = 0,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688f",
remoteEtag = "5efb0c13c688f",
mimeType = "DIR",
length = 123123123
)
val OC_ROOT_FOLDER = OCFile(
id = 1,
parentId = 0,
remotePath = "/",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2hay4",
privateLink = "http://server.url/f/8",
creationTimestamp = 0,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688k",
remoteEtag = "5efb0c13c688k",
mimeType = "DIR",
length = 123123123
)
val OC_PARENT_FOLDER_WITH_SPACE_ID = OCFile(
id = 123,
parentId = 1,
remotePath = "/Folder",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2hay2",
privateLink = "http://server.url/f/5",
creationTimestamp = 0,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688g",
remoteEtag = "5efb0c13c688g",
mimeType = "DIR",
length = 123123123,
spaceId = OC_SPACE_PERSONAL.id
)
val OC_FOLDER_WITH_SPACE_ID = OCFile(
id = 125,
parentId = 123,
remotePath = "/Folder/Photos",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2hay3",
privateLink = "http://server.url/f/6",
creationTimestamp = 0,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688h",
remoteEtag = "5efb0c13c688h",
mimeType = "DIR",
length = 0,
spaceId = OC_SPACE_PERSONAL.id
)
val OC_FILE = OCFile(
id = 124,
parentId = 122,
remotePath = "/Photos/image.jpt",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2how",
privateLink = "http://server.url/f/4",
creationTimestamp = 1593510589000,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688f",
remoteEtag = "5efb0c13c688f",
mimeType = "image/jpeg",
length = 3000000,
availableOfflineStatus = AvailableOfflineStatus.NOT_AVAILABLE_OFFLINE,
)
val OC_FILE_AVAILABLE_OFFLINE = OCFile(
id = 124,
parentId = 122,
remotePath = "/Photos/image.jpt",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2how",
privateLink = "http://server.url/f/4",
creationTimestamp = 1593510589000,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688f",
remoteEtag = "5efb0c13c688f",
mimeType = "image/jpeg",
length = 3000000,
availableOfflineStatus = AvailableOfflineStatus.AVAILABLE_OFFLINE
)
val OC_FILE_DOWNLOADED = OC_FILE.copy(
storagePath = "/local/storage/path/username@demo.qsfera.eu/Photos/image.jpt"
)
val OC_FILE_WITH_SPACE_ID = OCFile(
id = 126,
parentId = 123,
remotePath = "/Folder/image2.jpt",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2hox",
privateLink = "http://server.url/f/7",
creationTimestamp = 1593510589000,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688i",
remoteEtag = "5efb0c13c688i",
mimeType = "image/jpeg",
length = 3000000,
availableOfflineStatus = AvailableOfflineStatus.NOT_AVAILABLE_OFFLINE,
spaceId = OC_SPACE_PERSONAL.id
)
val OC_FILE_WITH_SYNC_INFO = OCFileWithSyncInfo(
file = OC_FILE,
uploadWorkerUuid = null,
downloadWorkerUuid = null,
isSynchronizing = false,
)
val OC_FILE_WITH_SYNC_INFO_AND_SPACE = OCFileWithSyncInfo(
file = OC_FILE,
uploadWorkerUuid = null,
downloadWorkerUuid = null,
isSynchronizing = false,
space = OC_SPACE_PERSONAL
)
val OC_FILE_WITH_SYNC_INFO_AND_WITHOUT_PERSONAL_SPACE = OCFileWithSyncInfo(
file = OC_FILE,
uploadWorkerUuid = null,
downloadWorkerUuid = null,
isSynchronizing = false,
space = OC_SPACE_PROJECT_WITH_IMAGE
)
val OC_FILE_WITH_SYNC_INFO_AVAILABLE_OFFLINE = OCFileWithSyncInfo(
file = OC_FILE_AVAILABLE_OFFLINE,
space = OC_SPACE_PROJECT_WITH_IMAGE
)
val OC_META_FILE = OCMetaFile(
path = OC_FILE.remotePath
)
val OC_META_FILE_ROOT_FOLDER = OCMetaFile(
path = OC_ROOT_FOLDER.remotePath
)
val OC_FILES_WITH_SYNC_INFO = listOf(OC_FILE_WITH_SYNC_INFO, OC_FILE_WITH_SYNC_INFO, OC_FILE_WITH_SYNC_INFO)
val OC_AVAILABLE_OFFLINE_FILES = listOf(OC_FILE_AVAILABLE_OFFLINE, OC_FILE_AVAILABLE_OFFLINE, OC_FILE_AVAILABLE_OFFLINE)
val OC_FILES_EMPTY = emptyList<OCFile>()
val OC_FILES_WITH_SYNC_INFO_EMPTY = emptyList<OCFileWithSyncInfo>()
val OC_FOLDER_ENTITY = OCFileEntity(
parentId = 123,
remotePath = "/Photos",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2hay",
privateLink = "http://server.url/f/3",
creationTimestamp = 0,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688f",
remoteEtag = "5efb0c13c688f",
mimeType = "DIR",
length = 123123123,
availableOfflineStatus = AvailableOfflineStatus.NOT_AVAILABLE_OFFLINE.ordinal,
fileIsDownloading = false,
modifiedAtLastSyncForData = 0,
lastSyncDateForData = 0,
treeEtag = "",
name = "Photos",
).apply { this.id = 122 }
val OC_FILE_ENTITY = OCFileEntity(
parentId = 122,
remotePath = "/Photos/image.jpt",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2how",
privateLink = "http://server.url/f/4",
creationTimestamp = 1593510589000,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688f",
remoteEtag = "5efb0c13c688f",
mimeType = "image/jpeg",
length = 3000000,
availableOfflineStatus = AvailableOfflineStatus.NOT_AVAILABLE_OFFLINE.ordinal,
fileIsDownloading = false,
modifiedAtLastSyncForData = 0,
lastSyncDateForData = 0,
treeEtag = "",
name = "image.jpt",
).apply { this.id = 124 }
val OC_FILE_AVAILABLE_OFFLINE_ENTITY = OCFileEntity(
parentId = 122,
remotePath = "/Photos/image.jpt",
owner = OC_ACCOUNT_NAME,
permissions = "RDNVCK",
remoteId = "00000003oci9p7er2how",
privateLink = "http://server.url/f/4",
creationTimestamp = 1593510589000,
modificationTimestamp = 1593510589000,
etag = "5efb0c13c688f",
remoteEtag = "5efb0c13c688f",
mimeType = "image/jpeg",
length = 3000000,
availableOfflineStatus = AvailableOfflineStatus.AVAILABLE_OFFLINE.ordinal,
fileIsDownloading = false,
modifiedAtLastSyncForData = 0,
lastSyncDateForData = 0,
treeEtag = "",
name = "image.jpt",
).apply { this.id = 124 }
val OC_FILE_SYNC_ENTITY = OCFileSyncEntity(
fileId = OC_FILE.id!!,
uploadWorkerUuid = null,
downloadWorkerUuid = null,
isSynchronizing = false,
)
val OC_FILE_AND_FILE_SYNC = OCFileAndFileSync(
OC_FILE_ENTITY,
OC_FILE_SYNC_ENTITY,
SPACE_ENTITY_PERSONAL,
)
val REMOTE_FILE = RemoteFile(
remotePath = OC_FILE.remotePath,
mimeType = OC_FILE.mimeType,
length = OC_FILE.length,
creationTimestamp = OC_FILE.creationTimestamp!!,
modifiedTimestamp = OC_FILE.modificationTimestamp,
etag = OC_FILE.etag,
permissions = OC_FILE.permissions,
remoteId = OC_FILE.remoteId,
privateLink = OC_FILE.privateLink,
owner = OC_FILE.owner,
sharedByLink = OC_FILE.sharedByLink,
sharedWithSharee = OC_FILE.sharedWithSharee!!,
)
val REMOTE_META_FILE = RemoteMetaFile(
metaPathForUser = OC_FILE.remotePath,
)
@@ -0,0 +1,55 @@
/*
* qsfera Android client application
*
* @author Fernando Sanz Velasco
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.automaticuploads.model.FolderBackUpConfiguration
import eu.qsfera.android.domain.automaticuploads.model.UploadBehavior
import eu.qsfera.android.data.folderbackup.db.FolderBackUpEntity
import eu.qsfera.android.domain.automaticuploads.model.AutomaticUploadsConfiguration
val OC_BACKUP = FolderBackUpConfiguration(
accountName = "",
behavior = UploadBehavior.COPY,
sourcePath = "/Photos",
uploadPath = "/Photos",
wifiOnly = true,
chargingOnly = true,
lastSyncTimestamp = 1542628397,
name = "",
spaceId = null,
)
val OC_BACKUP_ENTITY = FolderBackUpEntity(
accountName = "",
behavior = UploadBehavior.COPY.name,
sourcePath = "/Photos",
uploadPath = "/Photos",
wifiOnly = true,
chargingOnly = true,
lastSyncTimestamp = 1542628397,
name = "",
spaceId = null,
)
val OC_AUTOMATIC_UPLOADS_CONFIGURATION = AutomaticUploadsConfiguration(
pictureUploadsConfiguration = OC_BACKUP,
videoUploadsConfiguration = OC_BACKUP
)
@@ -0,0 +1,24 @@
/**
* qsfera Android client application
*
* Copyright (C) 2022 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.lib.common.network.RedirectionPath
val OC_REDIRECTION_PATH = RedirectionPath(200, 1)
@@ -0,0 +1,79 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* @author Juan Carlos Garrote Gascón
* @author Jorge Aguado Recio
*
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.server.model.ServerInfo
import eu.qsfera.android.testutil.oauth.OC_OIDC_SERVER_CONFIGURATION
const val OC_SECURE_BASE_URL = "https://demo.qsfera.eu"
const val OC_INSECURE_BASE_URL = "http://demo.qsfera.eu"
val OC_SECURE_SERVER_INFO_BASIC_AUTH = ServerInfo.BasicServer(
baseUrl = OC_SECURE_BASE_URL,
qsferaVersion = "10.3.2.1",
)
val OC_INSECURE_SERVER_INFO_BASIC_AUTH = ServerInfo.BasicServer(
baseUrl = OC_INSECURE_BASE_URL,
qsferaVersion = "10.3.2.1",
)
val OC_SECURE_SERVER_INFO_BEARER_AUTH = ServerInfo.OAuth2Server(
baseUrl = OC_SECURE_BASE_URL,
qsferaVersion = "10.3.2.1",
)
val OC_INSECURE_SERVER_INFO_BEARER_AUTH = ServerInfo.OAuth2Server(
baseUrl = OC_INSECURE_BASE_URL,
qsferaVersion = "10.3.2.1",
)
val OC_SECURE_SERVER_INFO_OIDC_AUTH = ServerInfo.OIDCServer(
baseUrl = OC_SECURE_BASE_URL,
qsferaVersion = "10.3.2.1",
oidcServerConfiguration = OC_OIDC_SERVER_CONFIGURATION
)
const val OC_WEBFINGER_INSTANCE_URL = "WEBFINGER_INSTANCE"
val OC_SECURE_SERVER_INFO_BEARER_AUTH_WEBFINGER_INSTANCE = ServerInfo.OAuth2Server(
baseUrl = OC_WEBFINGER_INSTANCE_URL,
qsferaVersion = "10.3.2.1",
)
val OC_SECURE_SERVER_INFO_OIDC_AUTH_WEBFINGER_INSTANCE = ServerInfo.OIDCServer(
baseUrl = OC_SECURE_BASE_URL,
qsferaVersion = "10.12",
oidcServerConfiguration = OC_OIDC_SERVER_CONFIGURATION
)
const val OC_WEBFINGER_CLIENT_ID = "QSferaAndroid"
val OC_WEBFINGER_SCOPES = listOf("openid", "profile", "email", "offline_access")
val OC_SECURE_SERVER_INFO_OIDC_AUTH_WEBFINGER_INSTANCE_WITH_CLIENT = ServerInfo.OIDCServer(
baseUrl = OC_SECURE_BASE_URL,
qsferaVersion = "10.12",
oidcServerConfiguration = OC_OIDC_SERVER_CONFIGURATION,
webFingerClientId = OC_WEBFINGER_CLIENT_ID,
webFingerScopes = OC_WEBFINGER_SCOPES,
)
@@ -0,0 +1,52 @@
/**
* qsfera Android client application
*
* Copyright (C) 2022 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.sharing.shares.model.OCShare
import eu.qsfera.android.domain.sharing.shares.model.ShareType
val OC_SHARE = OCShare(
shareType = ShareType.USER, // Private share by default
shareWith = "",
path = "/Photos/image.jpg",
permissions = 1,
sharedDate = 1542628397,
expirationDate = 0,
token = "AnyToken",
sharedWithDisplayName = "",
sharedWithAdditionalInfo = "",
isFolder = false,
remoteId = "1",
name = "",
shareLink = ""
)
val OC_PRIVATE_SHARE = OC_SHARE.copy(
shareWith = "WhoEver",
permissions = -1,
sharedWithDisplayName = "anyDisplayName"
)
val OC_PUBLIC_SHARE = OC_SHARE.copy(
shareType = ShareType.PUBLIC_LINK,
expirationDate = 1000,
name = "Image link",
shareLink = "link"
)
@@ -0,0 +1,32 @@
/**
* qsfera Android client application
*
* @author Jorge Aguado Recio
*
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.sharing.sharees.model.OCSharee
import eu.qsfera.android.domain.sharing.shares.model.ShareType
val OC_SHAREE = OCSharee(
label = "",
shareType = ShareType.USER,
shareWith = "WhoEver",
additionalInfo = "",
isExactMatch = true
)
@@ -0,0 +1,304 @@
/**
* qsfera Android client application
*
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2024 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.data.spaces.db.SpaceQuotaEntity
import eu.qsfera.android.data.spaces.db.SpaceRootEntity
import eu.qsfera.android.data.spaces.db.SpaceSpecialEntity
import eu.qsfera.android.data.spaces.db.SpacesEntity
import eu.qsfera.android.data.spaces.db.SpacesWithSpecials
import eu.qsfera.android.domain.spaces.model.OCSpace
import eu.qsfera.android.domain.spaces.model.OCSpace.Companion.SPACE_ID_SHARES
import eu.qsfera.android.domain.spaces.model.SpaceDeleted
import eu.qsfera.android.domain.spaces.model.SpaceFile
import eu.qsfera.android.domain.spaces.model.SpaceOwner
import eu.qsfera.android.domain.spaces.model.SpaceQuota
import eu.qsfera.android.domain.spaces.model.SpaceRoot
import eu.qsfera.android.domain.spaces.model.SpaceSpecial
import eu.qsfera.android.domain.spaces.model.SpaceSpecialFolder
import eu.qsfera.android.domain.spaces.model.SpaceUser
import eu.qsfera.android.lib.resources.spaces.responses.QuotaResponse
import eu.qsfera.android.lib.resources.spaces.responses.RootResponse
import eu.qsfera.android.lib.resources.spaces.responses.SpaceResponse
const val WEB_DAV_URL = "https://server.url/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f3805bca744-d89f-4e9c-a990-25a0d7f03fe9"
val OC_SPACE_SPECIAL_README = SpaceSpecial(
eTag = "71f78349c3598c9e431a67de5a283fc0",
file = SpaceFile(
mimeType = "text/markdown"
),
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199!1c7bbc13-469f-482c-8f13-55ae1402b4c3",
lastModifiedDateTime = "2023-01-01T00:00:00.00000000Z",
name = "readme.md",
size = 50,
specialFolder = SpaceSpecialFolder(
name = "readme"
),
webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$" +
"0aa0e03c-ec36-498c-bb9f-857315568199%210aa0e03c-ec36-498c-bb9f-857315568199/.space/readme.md"
)
val OC_SPACE_SPECIAL_IMAGE = SpaceSpecial(
eTag = "26ad7e0b49f9c0f163a6f227af3f130a",
file = SpaceFile(
mimeType = "image/jpeg"
),
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199!2597f35a-350f-4cf0-ace1-54b0e6bc377c",
lastModifiedDateTime = "2023-01-01T00:00:00.00000000Z",
name = "image.jpg",
size = 50000,
specialFolder = SpaceSpecialFolder(
name = "image"
),
webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$" +
"0aa0e03c-ec36-498c-bb9f-857315568199%210aa0e03c-ec36-498c-bb9f-857315568199/.space/image.jpg"
)
val OC_SPACE_PROJECT_WITH_IMAGE = OCSpace(
accountName = OC_ACCOUNT_NAME,
driveAlias = "project/space",
driveType = "project",
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
lastModifiedDateTime = "2023-01-01T00:00:00.00000000Z",
name = "Space",
owner = SpaceOwner(
user = SpaceUser(
id = "0aa0e03c-ec36-498c-bb9f-857315568199"
)
),
quota = SpaceQuota(
remaining = 999999995,
state = "normal",
total = 1000000000,
used = 5
),
root = SpaceRoot(
eTag = "989c7968dbbbde8c5fd9849b9123c384",
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
deleted = null
),
webUrl = "https://server.com/f/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
description = "This is the description of the space",
special = listOf(
OC_SPACE_SPECIAL_IMAGE,
OC_SPACE_SPECIAL_README
)
)
val OC_SPACE_PROJECT_WITHOUT_IMAGE = OC_SPACE_PROJECT_WITH_IMAGE.copy(
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-1234566789",
name = "Space without image",
root = SpaceRoot(
eTag = "989c7968dbbbde8c5fd9849b9123c384",
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-1234566789",
webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-1234566789",
deleted = null
),
webUrl = "https://server.com/f/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-1234566789",
special = listOf(OC_SPACE_SPECIAL_README)
)
val OC_SPACE_PERSONAL = OC_SPACE_PROJECT_WITH_IMAGE.copy(
driveAlias = "personal/admin",
driveType = "personal",
name = "Admin",
description = null,
special = null
)
val OC_SPACE_PERSONAL_WITH_UNLIMITED_QUOTA = OC_SPACE_PERSONAL.copy(
quota = SpaceQuota(
remaining = 0,
state = "normal",
total = 0,
used = 5_000
)
)
val OC_SPACE_PERSONAL_WITH_LIMITED_QUOTA = OC_SPACE_PERSONAL.copy(
quota = SpaceQuota(
remaining = 200_000,
state = "normal",
total = 280_000,
used = 80_000
)
)
val OC_SPACE_SHARES = OCSpace(
accountName = OC_ACCOUNT_NAME,
driveAlias = "virtual/shares",
driveType = "virtual",
id = "a0ca6a90-a365-4782-871e-d44447bbc668\$a0ca6a90-a365-4782-871e-d44447bbc668",
lastModifiedDateTime = "2024-01-01T00:00:00.00000000Z",
name = "Shares",
owner = null,
quota = null,
root = SpaceRoot(
eTag = "989c7968dbbbde8c5fd9849b9123c384",
id = "a0ca6a90-a365-4782-871e-d44447bbc668\$a0ca6a90-a365-4782-871e-d44447bbc668",
webDavUrl = "https://server.com/dav/spaces/a0ca6a90-a365-4782-871e-d44447bbc668\$a0ca6a90-a365-4782-871e-d44447bbc668",
deleted = null
),
webUrl = "https://server.com/f/a0ca6a90-a365-4782-871e-d44447bbc668\$a0ca6a90-a365-4782-871e-d44447bbc669",
description = null,
special = null
)
val OC_SPACE_PROJECT_DISABLED = OC_SPACE_PROJECT_WITH_IMAGE.copy(
quota = SpaceQuota(
remaining = null,
state = null,
total = 1000000000,
used = null
),
root = SpaceRoot(
eTag = "989c7968dbbbde8c5fd9849b9123c384",
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
deleted = SpaceDeleted(
state = "trashed"
)
),
special = null
)
val SPACE_ENTITY_WITH_SPECIALS = SpacesWithSpecials(
SpacesEntity(
accountName = OC_ACCOUNT_NAME,
driveAlias = "driveAlias",
driveType = "driveType",
id = OC_ACCOUNT_ID,
ownerId = OC_CLIENT_ID,
lastModifiedDateTime = "lastModifiedDateTime",
name = "name",
quota = null,
root = SpaceRootEntity(
eTag = "eTag",
id = "id",
webDavUrl = WEB_DAV_URL,
deleteState = "state"
),
webUrl = "webUrl",
description = "description"
),
listOf(
SpaceSpecialEntity(
accountName = OC_ACCOUNT_NAME,
eTag = "eTag",
fileMimeType = "fileMimeType",
id = OC_ACCOUNT_ID,
spaceId = OC_SPACE_PERSONAL.id,
lastModifiedDateTime = "lastModifiedDateTime",
name = "name",
webDavUrl = WEB_DAV_URL,
size = 100,
specialFolderName = OC_SPACE_SPECIAL_IMAGE.name
)
)
)
val SPACE_ENTITY_PERSONAL = SpacesEntity(
accountName = OC_ACCOUNT_NAME,
driveAlias = "personal/admin",
driveType = "personal",
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
ownerId = "0aa0e03c-ec36-498c-bb9f-857315568199",
lastModifiedDateTime = "2023-01-01T00:00:00.00000000Z",
name = "Admin",
quota = SpaceQuotaEntity(
remaining = 999999995,
state = "normal",
total = 1000000000,
used = 5,
),
root = SpaceRootEntity(
eTag = "989c7968dbbbde8c5fd9849b9123c384",
id = "8871f4f3-fc6f-4a66-8bed-62f175f76f38\$0aa0e03c-ec36-498c-bb9f-857315568199",
webDavUrl = "https://server.com/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
deleteState = null
),
webUrl = "https://server.com/f/8871f4f3-fc6f-4a66-8bed-62f175f76f38$0aa0e03c-ec36-498c-bb9f-857315568199",
description = null
)
val SPACE_ENTITY_SHARE = SpacesWithSpecials(
SpacesEntity(
accountName = OC_ACCOUNT_NAME,
driveAlias = "driveAlias",
driveType = "driveType",
id = SPACE_ID_SHARES,
ownerId = OC_CLIENT_ID,
lastModifiedDateTime = "lastModifiedDateTime",
name = "name",
quota = null,
root = SpaceRootEntity(
eTag = "eTag",
id = "id",
webDavUrl = WEB_DAV_URL,
deleteState = "state"
),
webUrl = "webUrl",
description = "description"
),
listOf(
SpaceSpecialEntity(
accountName = OC_ACCOUNT_NAME,
eTag = "eTag",
fileMimeType = "fileMimeType",
id = OC_ACCOUNT_ID,
spaceId = OC_SPACE_PERSONAL.id,
lastModifiedDateTime = "lastModifiedDateTime",
name = "name",
webDavUrl = WEB_DAV_URL,
size = 100,
specialFolderName = OC_SPACE_SPECIAL_IMAGE.name
)
)
)
val SPACE_RESPONSE =
SpaceResponse(
driveAlias = "driveAlias",
driveType = "driveType",
id = OC_ACCOUNT_ID,
lastModifiedDateTime = "lastModifiedDateTime",
name = "name",
webUrl = "webUrl",
description = "description",
owner = null,
root = RootResponse(
eTag = "eTag",
id = OC_ACCOUNT_ID,
webDavUrl = "https://server.url/dav/spaces/8871f4f3-fc6f-4a66-8bed-62f175f76f3805bca744-d89f-4e9c-a990-25a0d7f03fe9",
deleted = null
),
quota = QuotaResponse(
remaining = 1,
state = "state",
total = 10,
used = 1
),
special = null,
)
@@ -0,0 +1,55 @@
/**
* qsfera Android client application
*
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2023 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.automaticuploads.model.UploadBehavior
import eu.qsfera.android.domain.transfers.model.OCTransfer
import eu.qsfera.android.domain.transfers.model.TransferStatus
import eu.qsfera.android.domain.transfers.model.UploadEnqueuedBy
import java.io.File
private fun absolutePath(vararg parts: String): String =
parts.joinToString(File.separator, prefix = File.separator)
val OC_TRANSFER = OCTransfer(
id = 0L,
localPath = absolutePath("local", "path"),
remotePath = absolutePath("remote", "path"),
accountName = OC_ACCOUNT_NAME,
fileSize = 1024L,
status = TransferStatus.TRANSFER_IN_PROGRESS,
localBehaviour = UploadBehavior.MOVE,
forceOverwrite = true,
createdBy = UploadEnqueuedBy.ENQUEUED_BY_USER,
sourcePath = absolutePath("source", "path"),
)
val OC_FINISHED_TRANSFER = OC_TRANSFER.copy(
status = TransferStatus.TRANSFER_SUCCEEDED
)
val OC_FAILED_TRANSFER = OC_TRANSFER.copy(
status = TransferStatus.TRANSFER_FAILED
)
val OC_PENDING_TRANSFER = OC_TRANSFER.copy(
status = TransferStatus.TRANSFER_QUEUED
)
@@ -0,0 +1,67 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* @author Jorge Aguado Recio
*
* Copyright (C) 2025 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil
import eu.qsfera.android.domain.user.model.UserAvatar
import eu.qsfera.android.domain.user.model.UserInfo
import eu.qsfera.android.domain.user.model.UserQuota
import eu.qsfera.android.domain.user.model.UserQuotaState
val OC_USER_INFO = UserInfo(
id = "admin",
displayName = "adminOc",
email = null
)
val OC_USER_QUOTA = UserQuota(
accountName = OC_ACCOUNT_NAME,
available = 200_000,
used = 80_000,
total = 280_000,
state = null
)
val OC_USER_QUOTA_WITHOUT_PERSONAL = UserQuota(
accountName = OC_ACCOUNT_NAME,
available = -4L,
used = 0,
total = 0,
state = UserQuotaState.NORMAL
)
val OC_USER_QUOTA_UNLIMITED = UserQuota(
accountName = OC_ACCOUNT_NAME,
available = -3L,
used = 5_000,
total = 0,
state = UserQuotaState.NORMAL
)
val OC_USER_QUOTA_LIMITED = OC_USER_QUOTA.copy(
state = UserQuotaState.NORMAL
)
val OC_USER_AVATAR = UserAvatar(
byteArrayOf(1, 2, 3, 4, 5, 6),
eTag = "edcdc7d39dc218d197c269c8f75ab0f4",
mimeType = "image/png"
)
@@ -0,0 +1,54 @@
/**
* qsfera Android client application
*
* @author José Carlos Montes Martos
* Copyright (C) 2020 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.livedata
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.atomic.AtomicInteger
inline fun <reified T> LiveData<T>.getEmittedValues(
expectedSize: Int,
timeout: Long = TIMEOUT_TEST_SHORT,
crossinline onObserved: () -> Unit = {}
): List<T?> {
val currentValue = AtomicInteger(0)
val data = arrayOfNulls<T>(expectedSize)
val latch = CountDownLatch(expectedSize)
val observer = object : Observer<T> {
override fun onChanged(value: T?) {
data[currentValue.getAndAdd(1)] = value
if (currentValue.get() == expectedSize) {
removeObserver(this)
}
latch.countDown()
}
}
observeForever(observer)
onObserved()
latch.await(timeout, TimeUnit.MILLISECONDS)
return data.toList()
}
inline fun <reified T> LiveData<T>.getLastEmittedValue(
crossinline onObserved: () -> Unit = {}
): T? = getEmittedValues(expectedSize = 1, onObserved = onObserved).firstOrNull()
@@ -0,0 +1,22 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* Copyright (C) 2020 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.livedata
const val TIMEOUT_TEST_SHORT = 2_000L
@@ -0,0 +1,31 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.oauth
import eu.qsfera.android.domain.authentication.oauth.model.ClientRegistrationInfo
import eu.qsfera.android.testutil.OC_CLIENT_ID
import eu.qsfera.android.testutil.OC_CLIENT_SECRET
import eu.qsfera.android.testutil.OC_CLIENT_SECRET_EXPIRATION
val OC_CLIENT_REGISTRATION = ClientRegistrationInfo(
clientId = OC_CLIENT_ID,
clientSecret = OC_CLIENT_SECRET,
clientIdIssuedAt = null,
clientSecretExpiration = OC_CLIENT_SECRET_EXPIRATION
)
@@ -0,0 +1,30 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.oauth
import eu.qsfera.android.domain.authentication.oauth.model.ClientRegistrationRequest
import eu.qsfera.android.testutil.OC_REDIRECT_URI
val OC_CLIENT_REGISTRATION_REQUEST = ClientRegistrationRequest(
registrationEndpoint = OC_OIDC_SERVER_CONFIGURATION.registrationEndpoint!!,
clientName = "Android Client v2.17",
redirectUris = listOf(OC_REDIRECT_URI),
tokenEndpointAuthMethod = "client_secret_basic",
applicationType = "native"
)
@@ -0,0 +1,46 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.oauth
import eu.qsfera.android.domain.authentication.oauth.model.OIDCServerConfiguration
val OC_OIDC_SERVER_CONFIGURATION = OIDCServerConfiguration(
authorizationEndpoint = "https://qsfera.server/authorize",
checkSessionIframe = "https://qsfera.server/check-session.html",
endSessionEndpoint = "https://qsfera.server/endsession",
issuer = "https://qsfera.server/",
registrationEndpoint = "https://qsfera.server/register",
responseTypesSupported = listOf(
"id_token token",
"id_token",
"code id_token",
"code id_token token"
),
scopesSupported = listOf(
"openid",
"offline_access",
"konnect/raw_sub",
"profile",
"email",
"konnect/uuid"
),
tokenEndpoint = "https://qsfera.server/token",
tokenEndpointAuthMethodsSupported = listOf(),
userInfoEndpoint = "https://qsfera.server/userinfo"
)
@@ -0,0 +1,67 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.oauth
import eu.qsfera.android.domain.authentication.oauth.model.TokenRequest
import eu.qsfera.android.testutil.OC_SECURE_BASE_URL
import eu.qsfera.android.testutil.OC_CLIENT_AUTH
import eu.qsfera.android.testutil.OC_REDIRECT_URI
import eu.qsfera.android.testutil.OC_REFRESH_TOKEN
import eu.qsfera.android.testutil.OC_SCOPE
import eu.qsfera.android.testutil.OC_TOKEN_ENDPOINT
val OC_TOKEN_REQUEST_REFRESH = TokenRequest.RefreshToken(
baseUrl = OC_SECURE_BASE_URL,
tokenEndpoint = OC_TOKEN_ENDPOINT,
clientAuth = OC_CLIENT_AUTH,
scope = OC_SCOPE,
refreshToken = OC_REFRESH_TOKEN
)
val OC_TOKEN_REQUEST_ACCESS = TokenRequest.AccessToken(
baseUrl = OC_SECURE_BASE_URL,
tokenEndpoint = OC_TOKEN_ENDPOINT,
clientAuth = OC_CLIENT_AUTH,
scope = OC_SCOPE,
authorizationCode = "4uth0r1z4t10nC0d3",
redirectUri = OC_REDIRECT_URI,
codeVerifier = "A high-entropy cryptographic random STRING using the unreserved characters"
)
/**
* Test fixtures for public PKCE clients (RFC 7636).
* Public clients MUST NOT send Authorization header during token exchange.
*/
val OC_TOKEN_REQUEST_REFRESH_PUBLIC_CLIENT = TokenRequest.RefreshToken(
baseUrl = OC_SECURE_BASE_URL,
tokenEndpoint = OC_TOKEN_ENDPOINT,
clientAuth = "", // Empty for public clients per RFC 7636
scope = OC_SCOPE,
refreshToken = OC_REFRESH_TOKEN
)
val OC_TOKEN_REQUEST_ACCESS_PUBLIC_CLIENT = TokenRequest.AccessToken(
baseUrl = OC_SECURE_BASE_URL,
tokenEndpoint = OC_TOKEN_ENDPOINT,
clientAuth = "", // Empty for public clients per RFC 7636
scope = OC_SCOPE,
authorizationCode = "4uth0r1z4t10nC0d3",
redirectUri = OC_REDIRECT_URI,
codeVerifier = "A high-entropy cryptographic random STRING using the unreserved characters"
)
@@ -0,0 +1,33 @@
/**
* qsfera Android client application
*
* @author Abel García de Prada
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.oauth
import eu.qsfera.android.domain.authentication.oauth.model.TokenResponse
import eu.qsfera.android.testutil.OC_ACCESS_TOKEN
import eu.qsfera.android.testutil.OC_REFRESH_TOKEN
val OC_TOKEN_RESPONSE = TokenResponse(
accessToken = OC_ACCESS_TOKEN,
expiresIn = 3600,
refreshToken = OC_REFRESH_TOKEN,
tokenType = "Bearer",
userId = "demo",
scope = null,
additionalParameters = mapOf()
)
@@ -0,0 +1,24 @@
/**
* qsfera Android client application
*
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.security
const val OC_PASSCODE_4_DIGITS = "1111"
const val OC_PASSCODE_6_DIGITS = "111111"
@@ -0,0 +1,23 @@
/**
* qsfera Android client application
*
* @author Juan Carlos Garrote Gascón
*
* Copyright (C) 2021 ownCloud GmbH.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.qsfera.android.testutil.security
const val OC_PATTERN = "1234"