Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/bca/spaces dnd #3502

Merged
merged 5 commits into from
Jun 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
/*
* Copyright 2021 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.matrix.android.sdk

import org.amshove.kluent.internal.assertEquals
import org.junit.Assert
import org.junit.Test
import org.matrix.android.sdk.api.session.space.SpaceOrderUtils

class SpaceOrderTest {

@Test
fun testOrderBetweenNodesWithOrder() {
val orderedSpaces = listOf(
"roomId1" to "a",
"roomId2" to "m",
"roomId3" to "z"
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 1)

Assert.assertTrue("Only one order should be changed", orderCommand.size == 1)
Assert.assertTrue("Moved space order should change", orderCommand.first().spaceId == "roomId1")

Assert.assertTrue("m" < orderCommand[0].order)
Assert.assertTrue(orderCommand[0].order < "z")
}

@Test
fun testMoveLastBetweenNodesWithOrder() {
val orderedSpaces = listOf(
"roomId1" to "a",
"roomId2" to "m",
"roomId3" to "z"
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 2)

Assert.assertTrue("Only one order should be changed", orderCommand.size == 1)
Assert.assertTrue("Moved space order should change", orderCommand.first().spaceId == "roomId1")

Assert.assertTrue("z" < orderCommand[0].order)
}

@Test
fun testMoveUpNoOrder() {
val orderedSpaces = listOf(
"roomId1" to null,
"roomId2" to null,
"roomId3" to null
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 1)

Assert.assertTrue("2 orders change should be needed", orderCommand.size == 2)

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId2", reOrdered[0].first)
Assert.assertEquals("roomId1", reOrdered[1].first)
Assert.assertEquals("roomId3", reOrdered[2].first)
}

@Test
fun testMoveUpNotEnoughSpace() {
val orderedSpaces = listOf(
"roomId1" to "a",
"roomId2" to "j",
"roomId3" to "k"
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 1)

Assert.assertTrue("more orders change should be needed", orderCommand.size > 1)

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId2", reOrdered[0].first)
Assert.assertEquals("roomId1", reOrdered[1].first)
Assert.assertEquals("roomId3", reOrdered[2].first)
}

@Test
fun testMoveEndNoOrder() {
val orderedSpaces = listOf(
"roomId1" to null,
"roomId2" to null,
"roomId3" to null
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId1", 2)

// Actually 2 could be enough... as it's last it can stays with null
Assert.assertEquals("3 orders change should be needed", 3, orderCommand.size)

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId2", reOrdered[0].first)
Assert.assertEquals("roomId3", reOrdered[1].first)
Assert.assertEquals("roomId1", reOrdered[2].first)
}

@Test
fun testMoveUpBiggerOrder() {
val orderedSpaces = listOf(
"roomId1" to "aaaa",
"roomId2" to "ffff",
"roomId3" to "pppp",
"roomId4" to null,
"roomId5" to null,
"roomId6" to null
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId2", 3)

// Actually 2 could be enough... as it's last it can stays with null
Assert.assertEquals("3 orders change should be needed", 3, orderCommand.size)

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId1", reOrdered[0].first)
Assert.assertEquals("roomId3", reOrdered[1].first)
Assert.assertEquals("roomId4", reOrdered[2].first)
Assert.assertEquals("roomId5", reOrdered[3].first)
Assert.assertEquals("roomId2", reOrdered[4].first)
Assert.assertEquals("roomId6", reOrdered[5].first)
}

@Test
fun testMoveDownBetweenNodesWithOrder() {
val orderedSpaces = listOf(
"roomId1" to "a",
"roomId2" to "m",
"roomId3" to "z"
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId3", -1)

Assert.assertTrue("Only one order should be changed", orderCommand.size == 1)
Assert.assertTrue("Moved space order should change", orderCommand.first().spaceId == "roomId3")

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId1", reOrdered[0].first)
Assert.assertEquals("roomId3", reOrdered[1].first)
Assert.assertEquals("roomId2", reOrdered[2].first)
}

@Test
fun testMoveDownNoOrder() {
val orderedSpaces = listOf(
"roomId1" to null,
"roomId2" to null,
"roomId3" to null
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId3", -1)

Assert.assertTrue("2 orders change should be needed", orderCommand.size == 2)

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId1", reOrdered[0].first)
Assert.assertEquals("roomId3", reOrdered[1].first)
Assert.assertEquals("roomId2", reOrdered[2].first)
}

@Test
fun testMoveDownBiggerOrder() {
val orderedSpaces = listOf(
"roomId1" to "aaaa",
"roomId2" to "ffff",
"roomId3" to "pppp",
"roomId4" to null,
"roomId5" to null,
"roomId6" to null
).assertSpaceOrdered()

val orderCommand = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId5", -4)

Assert.assertEquals("1 order change should be needed", 1, orderCommand.size)

val reOrdered = reOrderWithCommands(orderedSpaces, orderCommand)

Assert.assertEquals("roomId5", reOrdered[0].first)
Assert.assertEquals("roomId1", reOrdered[1].first)
Assert.assertEquals("roomId2", reOrdered[2].first)
Assert.assertEquals("roomId3", reOrdered[3].first)
Assert.assertEquals("roomId4", reOrdered[4].first)
Assert.assertEquals("roomId6", reOrdered[5].first)
}

@Test
fun testMultipleMoveOrder() {
val orderedSpaces = listOf(
"roomId1" to null,
"roomId2" to null,
"roomId3" to null,
"roomId4" to null,
"roomId5" to null,
"roomId6" to null
).assertSpaceOrdered()

// move 5 to Top
val fiveToTop = SpaceOrderUtils.orderCommandsForMove(orderedSpaces, "roomId5", -4)

val fiveTopReOrder = reOrderWithCommands(orderedSpaces, fiveToTop)

// now move 4 to second
val orderCommand = SpaceOrderUtils.orderCommandsForMove(fiveTopReOrder, "roomId4", -3)

val reOrdered = reOrderWithCommands(fiveTopReOrder, orderCommand)
// second order should cost 1 re-order
Assert.assertEquals(1, orderCommand.size)

Assert.assertEquals("roomId5", reOrdered[0].first)
Assert.assertEquals("roomId4", reOrdered[1].first)
Assert.assertEquals("roomId1", reOrdered[2].first)
Assert.assertEquals("roomId2", reOrdered[3].first)
Assert.assertEquals("roomId3", reOrdered[4].first)
Assert.assertEquals("roomId6", reOrdered[5].first)
}

@Test
fun testComparator() {
listOf(
"roomId2" to "a",
"roomId1" to "b",
"roomId3" to null,
"roomId4" to null
).assertSpaceOrdered()
}

private fun reOrderWithCommands(orderedSpaces: List<Pair<String, String?>>, orderCommand: List<SpaceOrderUtils.SpaceReOrderCommand>) =
orderedSpaces.map { orderInfo ->
orderInfo.first to (orderCommand.find { it.spaceId == orderInfo.first }?.order ?: orderInfo.second)
}
.sortedWith(testSpaceComparator)

private fun List<Pair<String, String?>>.assertSpaceOrdered(): List<Pair<String, String?>> {
assertEquals(this, this.sortedWith(testSpaceComparator))
return this
}

private val testSpaceComparator = compareBy<Pair<String, String?>, String?>(nullsLast()) { it.second }.thenBy { it.first }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright 2021 The Matrix.org Foundation C.I.C.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.matrix.android.sdk

import org.amshove.kluent.internal.assertEquals
import org.junit.Assert
import org.junit.Test
import org.matrix.android.sdk.api.MatrixPatterns
import org.matrix.android.sdk.api.util.StringOrderUtils

class StringOrderTest {

@Test
fun testbasing() {
assertEquals("a", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("a", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
assertEquals("element", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("element", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
assertEquals("matrix", StringOrderUtils.baseToString(StringOrderUtils.stringToBase("matrix", StringOrderUtils.DEFAULT_ALPHABET), StringOrderUtils.DEFAULT_ALPHABET))
}

@Test
fun testValid() {
println(StringOrderUtils.DEFAULT_ALPHABET.joinToString(","))

assert(MatrixPatterns.isValidOrderString("a"))
assert(MatrixPatterns.isValidOrderString(" "))
assert(MatrixPatterns.isValidOrderString("abc"))
assert(!MatrixPatterns.isValidOrderString("abcê"))
assert(!MatrixPatterns.isValidOrderString(""))
assert(MatrixPatterns.isValidOrderString("!"))
assert(MatrixPatterns.isValidOrderString("!\"#\$%&'()*+,012"))
assert(!MatrixPatterns.isValidOrderString(Char(' '.code - 1).toString()))

assert(!MatrixPatterns.isValidOrderString(
buildString {
for (i in 0..49) {
append(StringOrderUtils.DEFAULT_ALPHABET.random())
}
}
))

assert(MatrixPatterns.isValidOrderString(
buildString {
for (i in 0..48) {
append(StringOrderUtils.DEFAULT_ALPHABET.random())
}
}
))
}

@Test
fun testAverage() {
assertAverage("${StringOrderUtils.DEFAULT_ALPHABET.first()}", "m")
assertAverage("aa", "aab")
assertAverage("matrix", "element")
assertAverage("mmm", "mmmmm")
assertAverage("aab", "aa")
assertAverage("", "aa")
assertAverage("a", "z")
assertAverage("ground", "sky")
}

@Test
fun testMidPoints() {
val orders = StringOrderUtils.midPoints("element", "matrix", 4)
assertEquals(4, orders!!.size)
assert("element" < orders[0])
assert(orders[0] < orders[1])
assert(orders[1] < orders[2])
assert(orders[2] < orders[3])
assert(orders[3] < "matrix")

println("element < ${orders.joinToString(" < ") { "[$it]" }} < matrix")

val orders2 = StringOrderUtils.midPoints("a", "d", 4)
assertEquals(null, orders2)
}

@Test
fun testRenumberNeeded() {
assertEquals(null, StringOrderUtils.average("a", "a"))
assertEquals(null, StringOrderUtils.average("", ""))
assertEquals(null, StringOrderUtils.average("a", "b"))
assertEquals(null, StringOrderUtils.average("b", "a"))
assertEquals(null, StringOrderUtils.average("mmmm", "mmmm"))
assertEquals(null, StringOrderUtils.average("a${Char(0)}", "a"))
}

private fun assertAverage(first: String, second: String) {
val left = first.takeIf { first < second } ?: second
val right = first.takeIf { first > second } ?: second
val av1 = StringOrderUtils.average(left, right)!!
println("[$left] < [$av1] < [$right]")
Assert.assertTrue(left < av1)
Assert.assertTrue(av1 < right)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ object MatrixPatterns {
private const val LINK_TO_APP_ROOM_ALIAS_REGEXP = APP_BASE_REGEX + MATRIX_ROOM_ALIAS_REGEX + SEP_REGEX + MATRIX_EVENT_IDENTIFIER_REGEX
private val PATTERN_CONTAIN_APP_LINK_PERMALINK_ROOM_ALIAS = LINK_TO_APP_ROOM_ALIAS_REGEXP.toRegex(RegexOption.IGNORE_CASE)

// ascii characters in the range \x20 (space) to \x7E (~)
val ORDER_STRING_REGEX = "[ -~]+".toRegex()

// list of patterns to find some matrix item.
val MATRIX_PATTERNS = listOf(
PATTERN_CONTAIN_MATRIX_TO_PERMALINK_ROOM_ID,
Expand Down Expand Up @@ -146,4 +149,12 @@ object MatrixPatterns {
fun extractServerNameFromId(matrixId: String?): String? {
return matrixId?.substringAfter(":", missingDelimiterValue = "")?.takeIf { it.isNotEmpty() }
}

/**
* Orders which are not strings, or do not consist solely of ascii characters in the range \x20 (space) to \x7E (~),
* or consist of more than 50 characters, are forbidden and the field should be ignored if received.
*/
fun isValidOrderString(order: String?) : Boolean {
return order != null && order.length < 50 && order matches ORDER_STRING_REGEX
}
}
Loading