Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • api-redesign
  • main
  • 0.10.0
  • 0.10.1
  • 0.10.2
  • 0.7.0
  • 0.8.0
  • 0.8.1
  • 0.9.0
  • 0.9.1
  • 0.9.2
11 results

Target

Select target project
  • justJanne/libquassel
1 result
Select Git revision
  • api-redesign
  • main
  • 0.10.0
  • 0.10.1
  • 0.10.2
  • 0.7.0
  • 0.8.0
  • 0.8.1
  • 0.9.0
  • 0.9.1
  • 0.9.2
11 results
Show changes
Showing
with 988 additions and 976 deletions
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
* Copyright (c) 2024 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
......
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
* Copyright (c) 2024 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
......
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.util.collections
fun <T> List<T>.remove(value: T): List<T> = this.filter { it != value }
fun <T> List<T>.removeAt(index: Int): List<T> {
if (index < 0 || index >= size) return this
val before = subList(0, index)
val after = subList(index + 1, size)
if (before.isEmpty()) return after
if (after.isEmpty()) return before
return before + after
}
......@@ -22,7 +22,7 @@ sealed class Expansion {
/**
* Text to insert
*/
override val source: String
override val source: String,
) : Expansion()
/**
......@@ -41,7 +41,7 @@ sealed class Expansion {
/**
* Original value that was parsed and replaced
*/
override val source: String
override val source: String,
) : Expansion()
/**
......@@ -66,7 +66,7 @@ sealed class Expansion {
/**
* Original value that was parsed and replaced
*/
override val source: String
override val source: String,
) : Expansion()
/**
......@@ -80,7 +80,7 @@ sealed class Expansion {
/**
* Original value that was parsed and replaced
*/
override val source: String
override val source: String,
) : Expansion()
/**
......@@ -115,7 +115,7 @@ sealed class Expansion {
* given context, or "*" if the user is not found or the hostname could not
* be determined.
*/
ACCOUNT
ACCOUNT,
}
/**
......@@ -136,14 +136,13 @@ sealed class Expansion {
/**
* Name of the network this alias is invoked on
*/
NETWORK
NETWORK,
}
companion object {
/**
* Parse a list of expansions from a given expansion string
*/
fun parse(text: String): List<Expansion> =
ExpansionParsingContext(text).parse()
fun parse(text: String): List<Expansion> = ExpansionParsingContext(text).parse()
}
}
......@@ -13,9 +13,10 @@ import de.justjanne.libquassel.protocol.util.ParsingContext
import java.util.function.Supplier
internal class ExpansionParsingContext(
text: String
text: String,
) : ParsingContext<Expansion>(text) {
override val matchers: List<Supplier<Expansion?>> = listOf(
override val matchers: List<Supplier<Expansion?>> =
listOf(
match("\$channelname", "\$channel") { source ->
Expansion.Constant(Expansion.ConstantField.CHANNEL, source)
},
......@@ -50,9 +51,13 @@ internal class ExpansionParsingContext(
Expansion.Parameter(value.toInt(), null, source)
},
Supplier {
val end = text.indexOf('$', startIndex = position).let {
if (it >= 0) it
else text.length
val end =
text.indexOf('$', startIndex = position).let {
if (it >= 0) {
it
} else {
text.length
}
}
if (position < end) {
val start = position
......@@ -61,6 +66,6 @@ internal class ExpansionParsingContext(
return@Supplier Expansion.Text(value)
}
return@Supplier null
}
},
)
}
......@@ -19,21 +19,22 @@ package de.justjanne.libquassel.protocol.util.expression
data class ExpressionMatch(
val expression: String,
val mode: MatchMode,
val caseSensitive: Boolean
val caseSensitive: Boolean,
) {
enum class MatchMode {
MatchPhrase,
MatchMultiPhrase,
MatchWildcard,
MatchMultiWildcard,
MatchRegEx
MatchRegEx,
}
internal val positiveRegex: Regex?
internal val negativeRegex: Regex?
init {
val (positive, negative) = when (mode) {
val (positive, negative) =
when (mode) {
MatchMode.MatchPhrase -> parsePhrase(expression)
MatchMode.MatchMultiPhrase -> parseMultiPhrase(expression)
MatchMode.MatchWildcard -> parseWildcard(expression)
......@@ -47,7 +48,10 @@ data class ExpressionMatch(
fun isEmpty() = positiveRegex == null && negativeRegex == null
fun match(content: String, matchEmpty: Boolean = false): Boolean {
fun match(
content: String,
matchEmpty: Boolean = false,
): Boolean {
if (isEmpty()) {
return matchEmpty
}
......@@ -64,7 +68,11 @@ data class ExpressionMatch(
}
companion object {
private fun regex(expression: String, caseSensitive: Boolean): Regex? = try {
private fun regex(
expression: String,
caseSensitive: Boolean,
): Regex? =
try {
when {
expression.isBlank() -> null
caseSensitive -> expression.toRegex()
......@@ -154,7 +162,8 @@ data class ExpressionMatch(
}
private fun parseMultiPhrase(expression: String): Pair<String, String> {
val components = expression.split('\n')
val components =
expression.split('\n')
.filter(String::isNotEmpty)
.map(::escape)
......@@ -170,14 +179,16 @@ data class ExpressionMatch(
var escaped = false
for (char in expression) {
when (char) {
'\\' -> if (escaped) {
'\\' ->
if (escaped) {
result.append('\\')
result.append(char)
escaped = false
} else {
escaped = true
}
'?' -> if (escaped) {
'?' ->
if (escaped) {
result.append('\\')
result.append(char)
escaped = false
......@@ -185,7 +196,8 @@ data class ExpressionMatch(
result.append('.')
escaped = false
}
'*' -> if (escaped) {
'*' ->
if (escaped) {
result.append('\\')
result.append(char)
escaped = false
......@@ -211,14 +223,18 @@ data class ExpressionMatch(
val (inverted, phrase) = parseInverted(expression)
val result = "^${parseWildcardInternal(phrase)}$"
return if (inverted) Pair("", result)
else Pair(result, "")
return if (inverted) {
Pair("", result)
} else {
Pair(result, "")
}
}
private fun parseMultiWildcard(expression: String): Pair<String, String> {
val components = splitWithEscaping(expression)
val positive = components
val positive =
components
.asSequence()
.map(::parseInverted)
.filterNot(Pair<Boolean, String>::first)
......@@ -228,7 +244,8 @@ data class ExpressionMatch(
.filter(String::isNotEmpty)
.toList()
val negative = components
val negative =
components
.asSequence()
.map(::parseInverted)
.filter(Pair<Boolean, String>::first)
......@@ -239,10 +256,16 @@ data class ExpressionMatch(
.toList()
return Pair(
if (positive.isEmpty()) ""
else positive.joinToString("|", prefix = "^(?:", postfix = ")$"),
if (negative.isEmpty()) ""
else negative.joinToString("|", prefix = "^(?:", postfix = ")$")
if (positive.isEmpty()) {
""
} else {
positive.joinToString("|", prefix = "^(?:", postfix = ")$")
},
if (negative.isEmpty()) {
""
} else {
negative.joinToString("|", prefix = "^(?:", postfix = ")$")
},
)
}
......
......@@ -9,5 +9,4 @@
package de.justjanne.libquassel.protocol.util.reflect
internal infix fun <T> Any?.instanceof(other: Class<T>?): Boolean =
other?.isInstance(this) != false
internal infix fun <T> Any?.instanceof(other: Class<T>?): Boolean = other?.isInstance(this) != false
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.util.reflect
inline fun <reified T> objectByName(name: String): T {
val clazz = try {
Class.forName(name)
} catch (t: Throwable) {
throw IllegalArgumentException("Could not load class $name", t)
}
val element = clazz.getDeclaredField("INSTANCE").get(null)
require(element != null) {
"No object found for $name"
}
require(element is T) {
"Object of wrong type found for $name:" +
"expected ${T::class.java.canonicalName}, " +
"got ${element::class.java.canonicalName}"
}
return element
}
......@@ -35,7 +35,6 @@ data class TlsInfo(
*/
val certificateChain: List<X509Certificate>,
) {
override fun toString(): String {
return "TlsInfo(protocol='$protocol', cipherSuite='$cipherSuite', keyExchangeMechanism=$keyExchangeMechanism)"
}
......@@ -45,11 +44,18 @@ data class TlsInfo(
private val cipherSuiteRegex12 = "TLS_(.*)_WITH_(.*)".toRegex()
private fun cipherSuiteRegex(protocol: String): Regex =
if (protocol == "TLSv1.3") cipherSuiteRegex13
else cipherSuiteRegex12
if (protocol == "TLSv1.3") {
cipherSuiteRegex13
} else {
cipherSuiteRegex12
}
private fun parseCipherSuite(protocol: String, cipherSuite: String): Pair<String, String?>? {
val match = cipherSuiteRegex(protocol)
private fun parseCipherSuite(
protocol: String,
cipherSuite: String,
): Pair<String, String?>? {
val match =
cipherSuiteRegex(protocol)
.matchEntire(cipherSuite)
?: return null
......@@ -64,7 +70,8 @@ data class TlsInfo(
* Obtain the TLS metadata of an existing [SSLSession]
*/
fun ofSession(session: SSLSession): TlsInfo? {
val (cipherSuite, keyExchangeMechanism) = parseCipherSuite(
val (cipherSuite, keyExchangeMechanism) =
parseCipherSuite(
session.protocol,
session.cipherSuite,
) ?: return null
......@@ -73,7 +80,7 @@ data class TlsInfo(
session.protocol,
cipherSuite,
keyExchangeMechanism,
session.peerCertificates.map(Certificate::toX509)
session.peerCertificates.map(Certificate::toX509),
)
}
}
......
......@@ -35,17 +35,20 @@ sealed class QVariant<T> {
* Serializer for the contained data
*/
abstract val serializer: PrimitiveSerializer<T>
@PublishedApi
internal abstract fun <U> withType(type: Class<U>): QVariant<U>?
/**
* QVariant of a predefined qt type
*/
data class Typed<T> @PublishedApi internal constructor(
data class Typed<T>
@PublishedApi
internal constructor(
override val data: T,
@PublishedApi
internal val type: QtType,
override val serializer: PrimitiveSerializer<T>
override val serializer: PrimitiveSerializer<T>,
) : QVariant<T>() {
override fun <U> withType(type: Class<U>): QVariant<U>? {
return if (
......@@ -58,7 +61,9 @@ sealed class QVariant<T> {
null
}
}
override fun toString() = data.let {
override fun toString() =
data.let {
when (it) {
is ByteBuffer ->
"QVariant(${type.name}, ${it.contentToString()})"
......@@ -73,11 +78,13 @@ sealed class QVariant<T> {
*
* Serialized as [QtType.UserType] with the custom type name serialized as ASCII string
*/
data class Custom<T> @PublishedApi internal constructor(
data class Custom<T>
@PublishedApi
internal constructor(
override val data: T,
@PublishedApi
internal val type: QuasselType,
override val serializer: PrimitiveSerializer<T>
override val serializer: PrimitiveSerializer<T>,
) : QVariant<T>() {
override fun <U> withType(type: Class<U>): QVariant<U>? {
return if (
......@@ -91,7 +98,8 @@ sealed class QVariant<T> {
}
}
override fun toString() = data.let {
override fun toString() =
data.let {
when (it) {
is ByteBuffer ->
"QVariant(${type.name}, ${it.contentToString()})"
......@@ -103,33 +111,37 @@ sealed class QVariant<T> {
@PublishedApi
@Suppress("UNCHECKED_CAST")
internal inline fun <reified U> withType(): QVariant<U>? =
withType(U::class.java)
internal inline fun <reified U> withType(): QVariant<U>? = withType(U::class.java)
fun type(): Class<*>? = data?.let { it::class.java }
internal fun serialize(buffer: ChainedByteBuffer, featureSet: FeatureSet) =
serializer.serialize(buffer, data, featureSet)
internal fun serialize(
buffer: ChainedByteBuffer,
featureSet: FeatureSet,
) = serializer.serialize(buffer, data, featureSet)
}
/**
* Construct a QVariant from data and type
*/
inline fun <reified T> qVariant(data: T, type: QtType): QVariant<T> =
QVariant.Typed(data, type, type.serializer())
inline fun <reified T> qVariant(
data: T,
type: QtType,
): QVariant<T> = QVariant.Typed(data, type, type.serializer())
/**
* Construct a QVariant from data and type
*/
inline fun <reified T> qVariant(data: T, type: QuasselType): QVariant<T> =
QVariant.Custom(data, type, type.serializer())
inline fun <reified T> qVariant(
data: T,
type: QuasselType,
): QVariant<T> = QVariant.Custom(data, type, type.serializer())
/**
* Extract the content of a QVariant in a type-safe manner
* @return value of the QVariant or null
*/
inline fun <reified T> QVariant_?.into(): T? =
this?.withType<T>()?.data
inline fun <reified T> QVariant_?.into(): T? = this?.withType<T>()?.data
/**
* Extract the content of a QVariant in a type-safe manner
......@@ -139,7 +151,7 @@ inline fun <reified T> QVariant_?.into(): T? =
inline fun <reified T> QVariant_?.intoOrThrow(): T =
this?.withType<T>()?.data ?: throw WrongVariantTypeException(
T::class.java.canonicalName,
this?.type()?.canonicalName ?: "null"
this?.type()?.canonicalName ?: "null",
)
/**
......@@ -147,5 +159,4 @@ inline fun <reified T> QVariant_?.intoOrThrow(): T =
* @param defValue default value if the type does not match or no value is found
* @return value of the QVariant or defValue
*/
inline fun <reified T> QVariant_?.into(defValue: T): T =
this?.withType<T>()?.data ?: defValue
inline fun <reified T> QVariant_?.into(defValue: T): T = this?.withType<T>()?.data ?: defValue
......@@ -11,5 +11,5 @@ package de.justjanne.libquassel.protocol.variant
data class WrongVariantTypeException(
val expected: String,
val actual: String?
val actual: String?,
) : Exception("Could not coerce QVariant of type $actual into $expected")
/*
* libquassel
* Copyright (c) 2021 Janne Mareike Koschinski
*
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at https://mozilla.org/MPL/2.0/.
*/
package de.justjanne.libquassel.protocol.variant
@Suppress("NOTHING_TO_INLINE")
internal inline fun QVariant_?.indexed(index: Int?) = this?.let {
index?.let { i ->
it.into<QVariantList>()?.get(i)
} ?: it
}
......@@ -16,35 +16,47 @@ import org.junit.jupiter.api.Test
class ClientHeaderSerializerTest {
@Test
fun testQuasseldroid() = serializerTest(
fun testQuasseldroid() =
serializerTest(
ClientHeaderSerializer,
ClientHeader(
features = ProtocolFeature.of(
features =
ProtocolFeature.of(
ProtocolFeature.TLS,
ProtocolFeature.Compression,
),
versions = listOf(
versions =
listOf(
ProtocolMeta(
version = ProtocolVersion.Datastream,
data = 0x0000u,
)
)
),
),
),
byteBufferOf(
0x42u, 0xb3u, 0x3fu, 0x03u,
0x80u, 0x00u, 0x00u, 0x02u
)
0x42u,
0xb3u,
0x3fu,
0x03u,
0x80u,
0x00u,
0x00u,
0x02u,
),
)
@Test
fun testQuasselClient() = serializerTest(
fun testQuasselClient() =
serializerTest(
ClientHeaderSerializer,
ClientHeader(
features = ProtocolFeature.of(
features =
ProtocolFeature.of(
ProtocolFeature.TLS,
ProtocolFeature.Compression,
),
versions = listOf(
versions =
listOf(
ProtocolMeta(
version = ProtocolVersion.Legacy,
data = 0x0000u,
......@@ -52,22 +64,24 @@ class ClientHeaderSerializerTest {
ProtocolMeta(
version = ProtocolVersion.Datastream,
data = 0x0000u,
)
)
),
),
),
byteBufferOf(
0x42u, 0xb3u, 0x3fu, 0x03u,
0x00u, 0x00u, 0x00u, 0x01u,
0x80u, 0x00u, 0x00u, 0x02u
)
0x80u, 0x00u, 0x00u, 0x02u,
),
)
@Test
fun testDebugClient() = serializerTest(
fun testDebugClient() =
serializerTest(
ClientHeaderSerializer,
ClientHeader(
features = ProtocolFeature.of(),
versions = listOf(
versions =
listOf(
ProtocolMeta(
version = ProtocolVersion.Legacy,
data = 0x0000u,
......@@ -75,13 +89,13 @@ class ClientHeaderSerializerTest {
ProtocolMeta(
version = ProtocolVersion.Datastream,
data = 0x0000u,
)
)
),
),
),
byteBufferOf(
0x42u, 0xb3u, 0x3fu, 0x00u,
0x00u, 0x00u, 0x00u, 0x01u,
0x80u, 0x00u, 0x00u, 0x02u
)
0x80u, 0x00u, 0x00u, 0x02u,
),
)
}
......@@ -21,25 +21,25 @@ class FeatureSetTest {
emptyList<QuasselFeatureName>(),
FeatureSet.build(
LegacyFeature.none(),
emptyList()
).featureList()
emptyList(),
).featureList(),
)
assertEquals(
listOf(
QuasselFeature.SynchronizedMarkerLine.feature,
QuasselFeature.ExtendedFeatures.feature,
QuasselFeatureName("_unknownFeature")
QuasselFeatureName("_unknownFeature"),
),
FeatureSet.build(
LegacyFeature.of(
LegacyFeature.SynchronizedMarkerLine
LegacyFeature.SynchronizedMarkerLine,
),
listOf(
QuasselFeature.ExtendedFeatures.feature,
QuasselFeatureName("_unknownFeature")
)
).featureList()
QuasselFeatureName("_unknownFeature"),
),
).featureList(),
)
}
......@@ -47,20 +47,20 @@ class FeatureSetTest {
fun testBuild() {
assertEquals(
emptyList<QuasselFeatureName>(),
FeatureSet.build(emptySet()).featureList()
FeatureSet.build(emptySet()).featureList(),
)
assertEquals(
listOf(
QuasselFeature.SynchronizedMarkerLine.feature,
QuasselFeature.ExtendedFeatures.feature
QuasselFeature.ExtendedFeatures.feature,
),
FeatureSet.build(
setOf(
QuasselFeature.SynchronizedMarkerLine,
QuasselFeature.ExtendedFeatures
)
).featureList()
QuasselFeature.ExtendedFeatures,
),
).featureList(),
)
}
}
......@@ -17,8 +17,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import java.nio.ByteBuffer
class ChainedByteBufferTest {
class ChainedByteBufferModelTest {
@Test
fun testPutArray() {
validateArray(byteArrayOf())
......@@ -35,7 +34,7 @@ class ChainedByteBufferTest {
0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
0x00, 0x01, -0x01, 0x00, 0x00, 0x01, -0x01, 0x00,
)
),
)
validateArray(ByteArray(3000, Int::toByte))
}
......@@ -43,7 +42,7 @@ class ChainedByteBufferTest {
@Test
fun testLimit() {
assertThrows<IllegalArgumentException>(
"Can not allocate 10 bytes, currently at 50, limit is 50"
"Can not allocate 10 bytes, currently at 50, limit is 50",
) {
ChainedByteBuffer(chunkSize = 10, limit = 50)
.put(ByteArray(70, Int::toByte))
......@@ -81,7 +80,10 @@ class ChainedByteBufferTest {
}
private fun validateArray(array: ByteArray) {
fun validateArrayInternal(array: ByteArray, direct: Boolean) {
fun validateArrayInternal(
array: ByteArray,
direct: Boolean,
) {
val bufferSize = 1024
val chained = ChainedByteBuffer(chunkSize = bufferSize, direct = direct, limit = 16384)
chained.put(array)
......
......@@ -25,15 +25,15 @@ class StringEncoderTest {
fun testNullString() {
assertThat(
ascii.encode(null),
ByteBufferMatcher(ByteBuffer.allocate(0))
ByteBufferMatcher(ByteBuffer.allocate(0)),
)
assertThat(
utf8.encode(null),
ByteBufferMatcher(ByteBuffer.allocate(0))
ByteBufferMatcher(ByteBuffer.allocate(0)),
)
assertThat(
utf16.encode(null),
ByteBufferMatcher(ByteBuffer.allocate(0))
ByteBufferMatcher(ByteBuffer.allocate(0)),
)
}
......@@ -41,11 +41,11 @@ class StringEncoderTest {
fun testUnencodableString() {
assertEquals(
0,
ascii.encode("\uFFFF").remaining()
ascii.encode("\uFFFF").remaining(),
)
assertThat(
ascii.encode("\uFFFF"),
ByteBufferMatcher(byteBufferOf())
ByteBufferMatcher(byteBufferOf()),
)
}
......@@ -53,21 +53,21 @@ class StringEncoderTest {
fun testNullChar() {
assertEquals(
1,
ascii.encodeChar(null).remaining()
ascii.encodeChar(null).remaining(),
)
assertThat(
ascii.encodeChar(null),
ByteBufferMatcher(byteBufferOf(0))
ByteBufferMatcher(byteBufferOf(0)),
)
assertThat(
utf8.encodeChar(null),
ByteBufferMatcher(byteBufferOf(0xEFu, 0xBFu, 0xBDu))
ByteBufferMatcher(byteBufferOf(0xEFu, 0xBFu, 0xBDu)),
)
assertEquals(
2,
utf16.encodeChar(null).remaining()
utf16.encodeChar(null).remaining(),
)
assertThat(
utf16.encodeChar(null),
......@@ -79,11 +79,11 @@ class StringEncoderTest {
fun testUnencodableChar() {
assertEquals(
1,
ascii.encodeChar('\uFFFF').remaining()
ascii.encodeChar('\uFFFF').remaining(),
)
assertThat(
ascii.encodeChar('\uFFFF'),
ByteBufferMatcher(byteBufferOf(0))
ByteBufferMatcher(byteBufferOf(0)),
)
}
}
......@@ -22,12 +22,13 @@ import org.junit.jupiter.api.Test
@Tag("HandshakeSerializerTest")
class ClientInitAckSerializerTest {
@Test
fun testEmptyMap() = handshakeSerializerTest(
fun testEmptyMap() =
handshakeSerializerTest(
HandshakeMessage.ClientInitAck(
coreConfigured = null,
backendInfo = emptyList(),
authenticatorInfo = emptyList(),
featureSet = FeatureSet.none()
featureSet = FeatureSet.none(),
),
byteBufferOf(
// 4 elements
......@@ -49,16 +50,17 @@ class ClientInitAckSerializerTest {
0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x41u, 0x00u, 0x63u, 0x00u, 0x6Bu,
),
featureSets = emptyList(),
serializeFeatureSet = null
serializeFeatureSet = null,
)
@Test
fun testSimple() = handshakeSerializerTest(
fun testSimple() =
handshakeSerializerTest(
HandshakeMessage.ClientInitAck(
coreConfigured = false,
backendInfo = emptyList(),
authenticatorInfo = emptyList(),
featureSet = FeatureSet.none()
featureSet = FeatureSet.none(),
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
......@@ -74,71 +76,78 @@ class ClientInitAckSerializerTest {
0x6Eu, 0x66u, 0x69u, 0x67u, 0x75u, 0x72u, 0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u,
0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u,
0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
)
),
)
@Test
fun testRealistic() = handshakeSerializerTest(
fun testRealistic() =
handshakeSerializerTest(
HandshakeMessage.ClientInitAck(
coreConfigured = false,
backendInfo = listOf(
backendInfo =
listOf(
BackendInfo(
entries = emptyList(),
isDefault = true,
displayName = "SQLite",
description = "SQLite is a file-based database engine that does not " +
description =
"SQLite is a file-based database engine that does not " +
"require any setup. It is suitable for small and medium-sized " +
"databases that do not require access via network. Use SQLite if " +
"your Quassel Core should store its data on the same machine it is " +
"running on, and if you only expect a few users to use your core.",
backendId = "SQLite"
backendId = "SQLite",
),
BackendInfo(
entries = listOf(
entries =
listOf(
SetupEntry(
"Username",
"Username",
qVariant("quassel", QtType.QString)
qVariant("quassel", QtType.QString),
),
SetupEntry(
"Password",
"Password",
qVariant<String?>(null, QtType.QString)
qVariant<String?>(null, QtType.QString),
),
SetupEntry(
"Hostname",
"Hostname",
qVariant("localhost", QtType.QString)
qVariant("localhost", QtType.QString),
),
SetupEntry(
"Port",
"Port",
qVariant(5432, QtType.Int)
qVariant(5432, QtType.Int),
),
SetupEntry(
"Database",
"Database",
qVariant("quassel", QtType.QString)
)
qVariant("quassel", QtType.QString),
),
),
isDefault = false,
displayName = "PostgreSQL",
description = "PostgreSQL Turbo Bomber HD!",
backendId = "PostgreSQL"
)
backendId = "PostgreSQL",
),
),
authenticatorInfo = listOf(
authenticatorInfo =
listOf(
BackendInfo(
entries = emptyList(),
isDefault = true,
displayName = "Database",
description = "Do not authenticate against any remote service, but " +
description =
"Do not authenticate against any remote service, but " +
"instead save a hashed and salted password in the database " +
"selected in the next step.",
backendId = "Database"
backendId = "Database",
),
BackendInfo(
entries = listOf(
entries =
listOf(
SetupEntry(
"Hostname",
"Hostname",
......@@ -173,15 +182,15 @@ class ClientInitAckSerializerTest {
"UidAttribute",
"UID Attribute",
qVariant("uid", QtType.QString),
)
),
),
isDefault = false,
displayName = "LDAP",
description = "Authenticate users using an LDAP server.",
backendId = "LDAP"
)
backendId = "LDAP",
),
featureSet = FeatureSet.none()
),
featureSet = FeatureSet.none(),
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
......@@ -417,6 +426,6 @@ class ClientInitAckSerializerTest {
0x65u, 0x64u, 0x00u, 0x00u, 0x00u, 0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u,
0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u, 0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u, 0x00u, 0x0Bu,
0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
)
),
)
}
......@@ -17,9 +17,10 @@ import org.junit.jupiter.api.Test
@Tag("HandshakeSerializerTest")
class ClientInitRejectSerializerTest {
@Test
fun testEmptyMap() = handshakeSerializerTest(
fun testEmptyMap() =
handshakeSerializerTest(
HandshakeMessage.ClientInitReject(
errorString = null
errorString = null,
),
byteBufferOf(
// 4 elements
......@@ -41,13 +42,14 @@ class ClientInitRejectSerializerTest {
0x00u, 0x69u, 0x00u, 0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u,
),
featureSets = emptyList(),
serializeFeatureSet = null
serializeFeatureSet = null,
)
@Test
fun testEmpty() = handshakeSerializerTest(
fun testEmpty() =
handshakeSerializerTest(
HandshakeMessage.ClientInitReject(
errorString = null
errorString = null,
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
......@@ -56,14 +58,16 @@ class ClientInitRejectSerializerTest {
0x74u, 0x00u, 0x52u, 0x00u, 0x65u, 0x00u, 0x6Au, 0x00u, 0x65u, 0x00u, 0x63u, 0x00u, 0x74u, 0x00u, 0x00u, 0x00u,
0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x05u, 0x45u, 0x72u, 0x72u, 0x6Fu, 0x72u, 0x00u, 0x00u, 0x00u, 0x0Au, 0x00u,
0xFFu, 0xFFu, 0xFFu, 0xFFu,
)
),
)
@Test
fun testSimple() = handshakeSerializerTest(
fun testSimple() =
handshakeSerializerTest(
HandshakeMessage.ClientInitReject(
errorString = "hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
"can't figure out where in my apartment it is."
errorString =
"hm. I've lost a machine.. literally _lost_. it responds to ping, it works completely, I just " +
"can't figure out where in my apartment it is.",
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x04u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
......@@ -89,6 +93,6 @@ class ClientInitRejectSerializerTest {
0x00u, 0x20u, 0x00u, 0x6Du, 0x00u, 0x79u, 0x00u, 0x20u, 0x00u, 0x61u, 0x00u, 0x70u, 0x00u, 0x61u, 0x00u, 0x72u,
0x00u, 0x74u, 0x00u, 0x6Du, 0x00u, 0x65u, 0x00u, 0x6Eu, 0x00u, 0x74u, 0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x74u,
0x00u, 0x20u, 0x00u, 0x69u, 0x00u, 0x73u, 0x00u, 0x2Eu,
)
),
)
}
......@@ -19,11 +19,12 @@ import org.junit.jupiter.api.Test
@Tag("HandshakeSerializerTest")
class ClientInitSerializerTest {
@Test
fun testEmptyMap() = handshakeSerializerTest(
fun testEmptyMap() =
handshakeSerializerTest(
HandshakeMessage.ClientInit(
clientVersion = null,
buildDate = null,
featureSet = FeatureSet.none()
featureSet = FeatureSet.none(),
),
byteBufferOf(
// 4 elements
......@@ -44,15 +45,16 @@ class ClientInitSerializerTest {
0x00u, 0x69u, 0x00u, 0x74u,
),
featureSets = emptyList(),
serializeFeatureSet = null
serializeFeatureSet = null,
)
@Test
fun testSimple() = handshakeSerializerTest(
fun testSimple() =
handshakeSerializerTest(
HandshakeMessage.ClientInit(
clientVersion = "Quasseldroid test",
buildDate = "Never",
featureSet = FeatureSet.none()
featureSet = FeatureSet.none(),
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu,
......@@ -80,17 +82,20 @@ class ClientInitSerializerTest {
0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u,
0x00u, 0x00u, 0x0Bu, 0x46u, 0x65u, 0x61u, 0x74u, 0x75u,
0x72u, 0x65u, 0x4Cu, 0x69u, 0x73u, 0x74u, 0x00u, 0x00u,
0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u
)
0x00u, 0x0Bu, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,
),
)
@Test
fun testRealistic() = handshakeSerializerTest(
fun testRealistic() =
handshakeSerializerTest(
HandshakeMessage.ClientInit(
clientVersion = "Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" +
clientVersion =
"Quasseldroid <a href=\"https://git.kuschku.de/justJanne/QuasselDroid-ng/commit/" +
"b622ad63056b6054b06e09f8e1f1ef2b0c3aaf9a\">v1.3.3</a>",
buildDate = "2020-04-27T22:21:17Z",
featureSet = FeatureSet.build(
featureSet =
FeatureSet.build(
QuasselFeature.SynchronizedMarkerLine,
QuasselFeature.SaslAuthentication,
QuasselFeature.SaslExternal,
......@@ -113,7 +118,7 @@ class ClientInitSerializerTest {
QuasselFeature.EcdsaCertfpKeys,
QuasselFeature.LongMessageId,
QuasselFeature.SyncedCoreInfo,
)
),
),
byteBufferOf(
0x00u, 0x00u, 0x00u, 0x0Au, 0x00u, 0x00u, 0x00u, 0x0Cu, 0x00u, 0x00u, 0x00u, 0x00u, 0x07u, 0x4Du, 0x73u, 0x67u,
......@@ -192,7 +197,7 @@ class ClientInitSerializerTest {
0x73u, 0x00u, 0x00u, 0x00u, 0x1Au, 0x00u, 0x4Cu, 0x00u, 0x6Fu, 0x00u, 0x6Eu, 0x00u, 0x67u, 0x00u, 0x4Du, 0x00u,
0x65u, 0x00u, 0x73u, 0x00u, 0x73u, 0x00u, 0x61u, 0x00u, 0x67u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x64u, 0x00u,
0x00u, 0x00u, 0x1Cu, 0x00u, 0x53u, 0x00u, 0x79u, 0x00u, 0x6Eu, 0x00u, 0x63u, 0x00u, 0x65u, 0x00u, 0x64u, 0x00u,
0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu
)
0x43u, 0x00u, 0x6Fu, 0x00u, 0x72u, 0x00u, 0x65u, 0x00u, 0x49u, 0x00u, 0x6Eu, 0x00u, 0x66u, 0x00u, 0x6Fu,
),
)
}