Skip to content

Commit

Permalink
Merge pull request #199 from aivanovski/feature/add-fake-file-for-aut…
Browse files Browse the repository at this point in the history
…otests

Add fake file handling for autotests
  • Loading branch information
aivanovski authored Oct 15, 2023
2 parents 90ec375 + 959c43b commit 852fb81
Show file tree
Hide file tree
Showing 25 changed files with 840 additions and 253 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,9 @@
project.properties
/.project
/tmp

# Clojure
.lsp/
.clj-kondo/
.cpcache/
.nrepl-port
Binary file removed app/src/debug/assets/fake-fs-database.kdbx
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.ivanovsky.passnotes.data.repository.file

import java.text.SimpleDateFormat
import java.util.Locale

private val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.US)

fun parseDate(str: String): Long {
return DATE_FORMAT.parse(str)?.time ?: throw IllegalArgumentException()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package com.ivanovsky.passnotes.data.repository.file

import app.keemobile.kotpass.database.KeePassDatabase
import app.keemobile.kotpass.database.encode
import com.ivanovsky.passnotes.data.repository.file.databaseDsl.EntryEntity
import com.ivanovsky.passnotes.data.repository.file.databaseDsl.GroupEntity
import com.ivanovsky.passnotes.data.repository.file.databaseDsl.KotpassTreeDsl
import java.io.ByteArrayOutputStream

class FakeFileContentFactory {

fun createDefaultLocalDatabase(): ByteArray {
return KotpassTreeDsl.tree(ROOT) {
group(GROUP_EMAIL)
group(GROUP_INTERNET) {
group(GROUP_CODING) {
entry(ENTRY_LEETCODE)
entry(ENTRY_NEETCODE)
entry(ENTRY_GITHUB)
}
group(GROUP_GAMING) {
entry(ENTRY_STADIA)
}
group(GROUP_SHOPPING)
group(GROUP_SOCIAL)

entry(ENTRY_GOOGLE)
entry(ENTRY_APPLE)
entry(ENTRY_MICROSOFT)
}
entry(ENTRY_NAS_LOGIN)
entry(ENTRY_LAPTOP_LOGIN)
entry(ENTRY_LOCAL)
}
.toByteArray()
}

fun createDefaultRemoteDatabase(): ByteArray {
return KotpassTreeDsl.tree(ROOT) {
group(GROUP_EMAIL)
group(GROUP_INTERNET) {
group(GROUP_CODING) {
entry(ENTRY_LEETCODE)
entry(ENTRY_NEETCODE)
entry(ENTRY_GITLAB)
}
group(GROUP_GAMING) {
entry(ENTRY_STADIA)
}
group(GROUP_SHOPPING)
group(GROUP_SOCIAL)

entry(ENTRY_GOOGLE)
entry(ENTRY_APPLE)
entry(ENTRY_MICROSOFT)
}
entry(ENTRY_NAS_LOGIN)
entry(ENTRY_LAPTOP_LOGIN)
entry(ENTRY_MAC_BOOK_LOGIN)
entry(ENTRY_REMOTE)
}
.toByteArray()
}

private fun KeePassDatabase.toByteArray(): ByteArray {
return ByteArrayOutputStream().use { out ->
this.encode(out)
out.toByteArray()
}
}

companion object {
private val ROOT = GroupEntity(title = "Database")
private val GROUP_INTERNET = GroupEntity(title = "Internet")
private val GROUP_EMAIL = GroupEntity(title = "Email")

private val GROUP_CODING = GroupEntity(title = "Coding")
private val GROUP_GAMING = GroupEntity(title = "Gaming")
private val GROUP_SHOPPING = GroupEntity(title = "Shopping")
private val GROUP_SOCIAL = GroupEntity(title = "Social")

private val ENTRY_LOCAL = EntryEntity(
title = "Local",
username = "john.doe",
password = "abc123",
created = parseDate("2020-01-01"),
modified = parseDate("2020-01-01")
)

private val ENTRY_REMOTE = EntryEntity(
title = "Remote",
username = "john.doe",
password = "abc123",
created = parseDate("2020-01-01"),
modified = parseDate("2020-01-01")
)

private val ENTRY_NAS_LOGIN = EntryEntity(
title = "My NAS Login",
username = "john.doe",
password = "abc123",
created = parseDate("2020-01-01"),
modified = parseDate("2020-01-01")
)

private val ENTRY_LAPTOP_LOGIN = EntryEntity(
title = "My Laptop Login",
username = "john.doe",
password = "abc123",
created = parseDate("2020-01-02"),
modified = parseDate("2020-01-02")
)

private val ENTRY_MAC_BOOK_LOGIN = EntryEntity(
title = "My Mac Book Login",
username = "john.doe",
password = "abc123",
created = parseDate("2020-02-01"),
modified = parseDate("2020-02-01")
)

private val ENTRY_GOOGLE = EntryEntity(
title = "My Google Login",
username = "[email protected]",
password = "abc123",
url = "https://google.com",
created = parseDate("2020-01-03"),
modified = parseDate("2020-01-03")
)

private val ENTRY_APPLE = EntryEntity(
title = "My Apple Login",
username = "[email protected]",
password = "abc123",
url = "https://apple.com",
created = parseDate("2020-01-04"),
modified = parseDate("2020-01-04")
)

private val ENTRY_MICROSOFT = EntryEntity(
title = "My Microsoft Login",
username = "[email protected]",
password = "abc123",
url = "https://microsoft.com",
created = parseDate("2020-01-05"),
modified = parseDate("2020-01-05")
)

private val ENTRY_LEETCODE = EntryEntity(
title = "My LeetCode Login",
username = "[email protected]",
password = "abc123",
url = "https://leetcode.com",
created = parseDate("2020-01-06"),
modified = parseDate("2020-01-06")
)

private val ENTRY_NEETCODE = EntryEntity(
title = "My NeetCode Login",
username = "[email protected]",
url = "https://neetcode.io/practice",
created = parseDate("2020-01-07"),
modified = parseDate("2020-01-07")
)

private val ENTRY_GITHUB = EntryEntity(
title = "My GitHub Login",
username = "[email protected]",
password = "abc123",
url = "https://github.com",
created = parseDate("2020-01-08"),
modified = parseDate("2020-01-08")
)

private val ENTRY_GITLAB = EntryEntity(
title = "My GitLab Login",
username = "[email protected]",
password = "abc123",
url = "https://gitlab.com",
created = parseDate("2020-01-08"),
modified = parseDate("2020-01-08")
)

private val ENTRY_STADIA = EntryEntity(
title = "My Stadia Login",
username = "[email protected]",
password = "abc123",
created = parseDate("2020-01-09"),
modified = parseDate("2020-01-09")
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package com.ivanovsky.passnotes.data.repository.file
import com.ivanovsky.passnotes.data.entity.FSAuthority
import com.ivanovsky.passnotes.data.entity.FileDescriptor
import com.ivanovsky.passnotes.util.FileUtils
import java.text.SimpleDateFormat
import java.util.Locale

class FakeFileFactory(
private val fsAuthority: FSAuthority
Expand Down Expand Up @@ -50,10 +48,18 @@ class FakeFileFactory(
return create(fsAuthority, FileUid.NOT_FOUND, Time.LOCAL)
}

fun createAutoTestsFile(): FileDescriptor {
return create(fsAuthority, FileUid.AUTO_TESTS, Time.NO_CHANGES)
}

fun createNewFromUid(uid: String): FileDescriptor {
return create(fsAuthority, uid, System.currentTimeMillis())
}

private fun create(
fsAuthority: FSAuthority,
uid: String,
modified: Long = System.currentTimeMillis()
modified: Long
): FileDescriptor {
val path = pathFromUid(uid)

Expand All @@ -69,9 +75,11 @@ class FakeFileFactory(
}

private fun pathFromUid(uid: String): String {
return when (uid) {
FileUid.ROOT -> "/"
else -> "/test-$uid.kdbx"
return when {
uid == FileUid.ROOT -> "/"
uid == FileUid.AUTO_TESTS -> "/automation.kdbx"
uid in FileUid.DEFAULT_UIDS -> "/test-$uid.kdbx"
else -> uid
}
}

Expand All @@ -85,19 +93,26 @@ class FakeFileFactory(
const val AUTH_ERROR = "auth-error"
const val NOT_FOUND = "not-found"
const val ERROR = "error"
const val AUTO_TESTS = "auto-tests"

val DEFAULT_UIDS = listOf(
NO_CHANGES,
ROOT,
REMOTE_CHANGES,
LOCAL_CHANGES,
LOCAL_CHANGES_TIMEOUT,
CONFLICT,
AUTH_ERROR,
NOT_FOUND,
ERROR,
AUTO_TESTS
)
}

private object Time {

private val DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd", Locale.US)

val ROOT = parseDate("2020-01-01")
val NO_CHANGES = parseDate("2020-02-01")
val LOCAL = parseDate("2020-03-01")
val REMOTE = parseDate("2020-03-02")

private fun parseDate(str: String): Long {
return DATE_FORMAT.parse(str)?.time ?: throw IllegalArgumentException()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.ivanovsky.passnotes.data.repository.file

import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.OutputStream
import timber.log.Timber

class FakeFileOutputStream(
private val onFinished: (bytes: ByteArray) -> Unit
) : OutputStream() {

private val out = ByteArrayOutputStream()
private var isFailed = false
private var isClosed = false

override fun write(b: Int) {
throwIfInvalidState()

try {
out.write(b)
} catch (exception: IOException) {
Timber.d(exception)
isFailed = true
throw IOException(exception)
}
}

override fun flush() {
throwIfInvalidState()
}

override fun close() {
if (isClosed || isFailed) {
return
}

val bytes = try {
out.toByteArray()
} catch (exception: IOException) {
Timber.d(exception)
isFailed = true
throw IOException(exception)
}

onFinished.invoke(bytes)
}

private fun throwIfInvalidState() {
when {
isFailed -> throw IOException("Invalid state: failed")
isClosed -> throw IOException("Invalid state: closed")
}
}
}
Loading

0 comments on commit 852fb81

Please sign in to comment.