Skip to content

Commit

Permalink
issue 594: Rework unit-test for ApiUtilsSuite
Browse files Browse the repository at this point in the history
- Add checking for valid time format

Signed-off-by: Oleksandr Mordyk <[email protected]>
  • Loading branch information
omordyk committed Nov 4, 2024
1 parent 02f87d8 commit 4b2ced5
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 80 deletions.
15 changes: 15 additions & 0 deletions src/main/scala/org/openhorizon/exchangeapi/utility/ApiTime.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
package org.openhorizon.exchangeapi.utility
import java.time.format.DateTimeParseException

import java.time.{Instant, ZoneId, ZonedDateTime}

Expand Down Expand Up @@ -48,7 +49,21 @@ object ApiTime {
(nowSeconds - thenTime >= secondsStale)
}

/** Validates time format */
def isValidTimeFormat(time: String): Boolean = {
try {
ZonedDateTime.parse(time)
true
} catch {
case _: DateTimeParseException => false
case _: Exception => false
}
}

def fixFormatting(time: String): String = {
if (time.isEmpty || !isValidTimeFormat(time)) {
return "Invalid format"
}
val timeLength: Int = time.length
/*
This implementation uses length of the string instead of a regex to make it as fast as possible
Expand Down
80 changes: 0 additions & 80 deletions src/test/scala/org/openhorizon/exchangeapi/ApiUtilsSuite.scala

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package org.openhorizon.exchangeapi

import org.openhorizon.exchangeapi.utility.{ApiTime}
import org.scalatest.funsuite.AnyFunSuite

object DateTimeConstants {
val DateTimePattern: String = """\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{1,9}Z\[UTC\]"""
}

class TestApiUtilsTime extends AnyFunSuite {
test("ApiTime fixFormatting no milliseconds") {
val timeNoMilliseconds = "2019-06-17T21:24:55Z[UTC]"
info(ApiTime.fixFormatting(timeNoMilliseconds) + " , " + "2019-06-17T21:24:55.000Z[UTC]")
assert(ApiTime.fixFormatting(timeNoMilliseconds) == "2019-06-17T21:24:55.000Z[UTC]")
}

test("ApiTime fixFormatting no seconds and no milliseconds") {
val timeNoSeconds = "2019-06-17T21:24Z[UTC]"
info(ApiTime.fixFormatting(timeNoSeconds) + " , " + "2019-06-17T21:24:00.000Z[UTC]")
assert(ApiTime.fixFormatting(timeNoSeconds) == "2019-06-17T21:24:00.000Z[UTC]")
}

test("ApiTime fixFormatting handles invalid format") {
val invalidTime = "invalid-time-format"
info(ApiTime.fixFormatting(invalidTime) + " , " + "Invalid format")
assert(ApiTime.fixFormatting(invalidTime) == "Invalid format")

}

test("ApiTime.nowUTC is always right length") {
info(ApiTime.nowUTC)
assert(ApiTime.nowUTC.length >= 29)
}

test("ApiTime.nowUTC returns current time in valid format") {
val currentTime = ApiTime.nowUTC
info(currentTime)

assert(currentTime.matches(DateTimeConstants.DateTimePattern))
}

test("ApiTime.thenUTC is always right time and length") {
info(ApiTime.thenUTC(1615406509) + " , 2021-03-10T20:01:49.000Z[UTC]")
assert(ApiTime.thenUTC(1615406509) == "2021-03-10T20:01:49.000Z[UTC]")
assert(ApiTime.thenUTC(1615406509).length >= 29)
}

test("ApiTime.thenUTC is always right time and length test 2"){
info(ApiTime.thenUTC(1615406355)+ " , 2021-03-10T19:59:15.000Z[UTC]")
assert(ApiTime.thenUTC(1615406355) == "2021-03-10T19:59:15.000Z[UTC]")
assert(ApiTime.thenUTC(1615406355).length >= 29)
}

test("ApiTime.thenUTC handles future timestamps") {
val futureTimestamp = System.currentTimeMillis() / 1000 + 10000
val futureTime = ApiTime.thenUTC(futureTimestamp)
info(futureTime)
assert(futureTime.length >= 29)
}

test("ApiTime.thenUTC handles past timestamps") {
val pastTimestamp = System.currentTimeMillis() / 1000 - 10000
val pastTime = ApiTime.thenUTC(pastTimestamp)
info(pastTime)
assert(pastTime.length >= 29)
}

test("ApiTime.pastUTC is always right length") {
info(ApiTime.pastUTC(10))
assert(ApiTime.pastUTC(10).length >= 29)
}

test("ApiTime.pastUTC returns correct time") {
val tenSecondsAgo = ApiTime.pastUTC(10)
info(tenSecondsAgo)
assert(tenSecondsAgo.matches(DateTimeConstants.DateTimePattern))
}

test("ApiTime.futureUTC is always right length") {
info(ApiTime.futureUTC(10))
assert(ApiTime.futureUTC(10).length >= 29)
}

test("ApiTime.futureUTC returns correct time") {
val tenSecondsLater = ApiTime.futureUTC(10)
info(tenSecondsLater)
assert(tenSecondsLater.matches(DateTimeConstants.DateTimePattern))
}

test("ApiTime.beginningUTC is always correct and right length") {
info(ApiTime.beginningUTC + " , " + "1970-01-01T00:00:00.000Z[UTC]")
assert(ApiTime.beginningUTC == "1970-01-01T00:00:00.000Z[UTC]")
assert(ApiTime.beginningUTC.length >= 29)
}

test("ApiTime.beginningUTC is formatted correctly") {
val beginningTime = ApiTime.beginningUTC
info(beginningTime)
assert(beginningTime.matches("""\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\[UTC\]"""))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package org.openhorizon.exchangeapi

import org.openhorizon.exchangeapi.utility.{NodeAgbotTokenValidation}
import org.scalatest.funsuite.AnyFunSuite


class TestNodeAgbotTokenValidation extends AnyFunSuite {
test("NodeAgbotTokenValidation.isValid correctly identifies if password is too short, <15 chars"){
info("NodeAgbotTokenValidation.isValid(\"1Abbb\")"+ " , " + NodeAgbotTokenValidation.isValid("1Abbb").toString())
assert(NodeAgbotTokenValidation.isValid("1Abbb") == false)
info("NodeAgbotTokenValidation.isValid(\"1Abcdefghijkl\")"+ " , " + NodeAgbotTokenValidation.isValid("1Abcdefghijkl").toString())
assert(NodeAgbotTokenValidation.isValid("1Abcdefghijkl") == false)
}

test("NodeAgbotTokenValidation.isValid correctly identifies if password does not contain digit"){
info("NodeAgbotTokenValidation.isValid(\"aaaaaaaaaaaaaaaB\")"+ " , " + NodeAgbotTokenValidation.isValid("aaaaaaaaaaaaaaaB").toString())
assert(NodeAgbotTokenValidation.isValid("aaaaaaaaaaaaaaaB") == false)
info("NodeAgbotTokenValidation.isValid(\"abcdefghijklmno\")"+ " , " + NodeAgbotTokenValidation.isValid("abcdefghijklmno").toString())
assert(NodeAgbotTokenValidation.isValid("abcdefghijklmno") == false)
}

test("NodeAgbotTokenValidation.isValid correctly identifies if password does not contain uppercase letter"){
info("NodeAgbotTokenValidation.isValid(\"aaaaaaaaaaaaaaa1\")"+ " , " + NodeAgbotTokenValidation.isValid("aaaaaaaaaaaaaaa1").toString())
assert(NodeAgbotTokenValidation.isValid("aaaaaaaaaaaaaaa1") == false)
info("NodeAgbotTokenValidation.isValid(\"abcdefghijklmno1\")"+ " , " + NodeAgbotTokenValidation.isValid("abcdefghijklmno1").toString())
assert(NodeAgbotTokenValidation.isValid("abcdefghijklmno1") == false)
}

test("NodeAgbotTokenValidation.isValid correctly identifies if password does not contain lowercase letter"){
info("NodeAgbotTokenValidation.isValid(\"AAAAAAAAAAAAAB1\")"+ " , " + NodeAgbotTokenValidation.isValid("AAAAAAAAAAAAAB1").toString())
assert(NodeAgbotTokenValidation.isValid("AAAAAAAAAAAAAB1") == false)
info("NodeAgbotTokenValidation.isValid(\"ABCDEFGHIJKLMNO1\")"+ " , " + NodeAgbotTokenValidation.isValid("ABCDEFGHIJKLMNO1").toString())
assert(NodeAgbotTokenValidation.isValid("ABCDEFGHIJKLMNO1") == false)
}

test("NodeAgbotTokenValidation.isValid correctly identifies valid password"){
info("NodeAgbotTokenValidation.isValid(\"AAAAAAAAAAAAaB1\")"+ " , " + NodeAgbotTokenValidation.isValid("AAAAAAAAAAAAaB1").toString())
assert(NodeAgbotTokenValidation.isValid("AAAAAAAAAAAAaB1") == true)
info("NodeAgbotTokenValidation.isValid(\"ValidPassword1!\")"+ " , " + NodeAgbotTokenValidation.isValid("ValidPassword1!").toString())
assert(NodeAgbotTokenValidation.isValid("ValidPassword1!") == true)
}

test("NodeAgbotTokenValidation.isValid correctly identifies valid password with digits only") {
info("NodeAgbotTokenValidation.isValid(\"123456789012345\")"+ " , " + NodeAgbotTokenValidation.isValid("123456789012345").toString())
assert(NodeAgbotTokenValidation.isValid("123456789012345") == false)
}

test("NodeAgbotTokenValidation.isValid correctly identifies password with exactly 15 characters") {
info("NodeAgbotTokenValidation.isValid(\"Aa1aaaaaaaaaaaa\")"+ " , " + NodeAgbotTokenValidation.isValid("Aa1aaaaaaaaaaaa").toString())
assert(NodeAgbotTokenValidation.isValid("Aa1" + "a" * 12) == true) // valid
info("NodeAgbotTokenValidation.isValid(\"Aaaaaaaabbbbbbb\")"+ " , " + NodeAgbotTokenValidation.isValid("Aaaaaaaabbbbbbb").toString())
assert(NodeAgbotTokenValidation.isValid("Aaaaaaaabbbbbbb") == false) // invalid
info("NodeAgbotTokenValidation.isValid(\"A1abbbbbbbbbbbb\")"+ " , " + NodeAgbotTokenValidation.isValid("A1abbbbbbbbbbbb").toString())
assert(NodeAgbotTokenValidation.isValid("A1a" + "b" * 12) == true) // valid
}

test("NodeAgbotTokenValidation.isValid correctly identifies password with special characters") {
info("NodeAgbotTokenValidation.isValid(\"A1!abbbbbbbbbbb\")"+ " , " + NodeAgbotTokenValidation.isValid("A1!abbbbbbbbbbb").toString())
assert(NodeAgbotTokenValidation.isValid("A1!a" + "b" * 11) == true)
info("NodeAgbotTokenValidation.isValid(\"!A1abbbbbbbbbbb\")"+ " , " + NodeAgbotTokenValidation.isValid("!A1abbbbbbbbbbb").toString())
assert(NodeAgbotTokenValidation.isValid("!A1a" + "b" * 11) == true)
}
}

0 comments on commit 4b2ced5

Please sign in to comment.