Skip to content

Commit

Permalink
PI-2536 Fix NumberFormatException attempting to parse invalid PNCs (#754
Browse files Browse the repository at this point in the history
)

* PI-2536 Fix NumberFormatException attempting to parse invalid PNCs

PNC IDs can only have up to 7 digits after the slash, but the existing regular expression allows an unlimited number.

Example invalid PNC ID: 1999/9999999999a. Previously the code would try to parse 9,999,999,999 as an int, and fail.

* Switch to parameterized test
  • Loading branch information
marcus-bcl committed Sep 27, 2024
1 parent 5a1cc32 commit ca8c3d3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ internal fun String.canonicalPNCNumberOrNull(): String? =
}

private fun String.isPNCNumber(): Boolean {
return this.matches("^([0-9]{2}|[0-9]{4})/[0-9]+[a-zA-Z]".toRegex())
return this.matches("^([0-9]{2}|[0-9]{4})/[0-9]{1,7}[a-zA-Z]".toRegex())
}

private fun String.toPNCNumber(): String {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,59 @@
package uk.gov.justice.hmpps.probationsearch.services

import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.Arguments.arguments
import org.junit.jupiter.params.provider.MethodSource

internal class CanonicalPncKtTest {
companion object {
@JvmStatic
fun validPNCs() = listOf(
arguments("2003/1234567A", "2003/1234567a"),
arguments("2003/0234567A", "2003/234567a"),
arguments("2003/0034567A", "2003/34567a"),
arguments("2003/0004567A", "2003/4567a"),
arguments("2003/0000567A", "2003/567a"),
arguments("2003/0000067A", "2003/67a"),
arguments("2003/0000007A", "2003/7a"),
arguments("2003/0000000A", "2003/0a"),
arguments("03/1234567A", "03/1234567a"),
arguments("03/0234567A", "03/234567a"),
arguments("03/0034567A", "03/34567a"),
arguments("03/0004567A", "03/4567a"),
arguments("03/0000567A", "03/567a"),
arguments("03/0000067A", "03/67a"),
arguments("03/0000007A", "03/7a"),
arguments("03/0000000A", "03/0a"),
)

@Test
internal fun `will convert to canonical form of PNC when it is valid`() {
assertThat("2003/1234567A".canonicalPNCNumber()).isEqualTo("2003/1234567a")
assertThat("2003/0234567A".canonicalPNCNumber()).isEqualTo("2003/234567a")
assertThat("2003/0034567A".canonicalPNCNumber()).isEqualTo("2003/34567a")
assertThat("2003/0004567A".canonicalPNCNumber()).isEqualTo("2003/4567a")
assertThat("2003/0000567A".canonicalPNCNumber()).isEqualTo("2003/567a")
assertThat("2003/0000067A".canonicalPNCNumber()).isEqualTo("2003/67a")
assertThat("2003/0000007A".canonicalPNCNumber()).isEqualTo("2003/7a")
assertThat("2003/0000000A".canonicalPNCNumber()).isEqualTo("2003/0a")
assertThat("03/1234567A".canonicalPNCNumber()).isEqualTo("03/1234567a")
assertThat("03/0234567A".canonicalPNCNumber()).isEqualTo("03/234567a")
assertThat("03/0034567A".canonicalPNCNumber()).isEqualTo("03/34567a")
assertThat("03/0004567A".canonicalPNCNumber()).isEqualTo("03/4567a")
assertThat("03/0000567A".canonicalPNCNumber()).isEqualTo("03/567a")
assertThat("03/0000067A".canonicalPNCNumber()).isEqualTo("03/67a")
assertThat("03/0000007A".canonicalPNCNumber()).isEqualTo("03/7a")
assertThat("03/0000000A".canonicalPNCNumber()).isEqualTo("03/0a")
@JvmStatic
fun invalidPNCs() = listOf(
arguments("203/1234567A"),
arguments("203/1234567"),
arguments("1234567A"),
arguments("2013"),
arguments("john smith"),
arguments("john/smith"),
arguments("16/11/2018"),
arguments("16-11-2018"),
arguments("111111/11A"),
arguments("SF68/945674U"),
arguments(""),
arguments("2010/BBBBBBBA"),
arguments("2003/012345678A"),
)
}

@Test
internal fun `will not convert to canonical form of PNC when it is not valid`() {
assertThat("2003/A".canonicalPNCNumber()).isEqualTo("2003/A")
assertThat("203/1234567A".canonicalPNCNumber()).isEqualTo("203/1234567A")
assertThat("203/1234567".canonicalPNCNumber()).isEqualTo("203/1234567")
assertThat("1234567A".canonicalPNCNumber()).isEqualTo("1234567A")
assertThat("2013".canonicalPNCNumber()).isEqualTo("2013")
assertThat("john smith".canonicalPNCNumber()).isEqualTo("john smith")
assertThat("john/smith".canonicalPNCNumber()).isEqualTo("john/smith")
assertThat("16/11/2018".canonicalPNCNumber()).isEqualTo("16/11/2018")
assertThat("16-11-2018".canonicalPNCNumber()).isEqualTo("16-11-2018")
assertThat("111111/11A".canonicalPNCNumber()).isEqualTo("111111/11A")
assertThat("SF68/945674U".canonicalPNCNumber()).isEqualTo("SF68/945674U")
assertThat("".canonicalPNCNumber()).isEqualTo("")
assertThat("2010/BBBBBBBA".canonicalPNCNumber()).isEqualTo("2010/BBBBBBBA")
@ParameterizedTest
@MethodSource("validPNCs")
internal fun `will convert to canonical form of PNC when it is valid`(actual: String, expected: String) {
assertThat(actual.canonicalPNCNumber()).isEqualTo(expected)
}

@ParameterizedTest
@MethodSource("invalidPNCs")
internal fun `will not convert to canonical form of PNC when it is not valid`(actual: String) {
assertThat(actual.canonicalPNCNumber()).isEqualTo(actual)
}
}

0 comments on commit ca8c3d3

Please sign in to comment.