add IBAN+BIC validation
This commit is contained in:
@@ -2,6 +2,8 @@ package net.hostsharing.hsadminng.errors;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.dao.DataIntegrityViolationException;
|
||||
import org.springframework.orm.jpa.JpaObjectRetrievalFailureException;
|
||||
@@ -9,7 +11,6 @@ import org.springframework.orm.jpa.JpaSystemException;
|
||||
import org.springframework.web.context.request.WebRequest;
|
||||
|
||||
import javax.persistence.EntityNotFoundException;
|
||||
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -147,6 +148,25 @@ class RestResponseEntityExceptionHandlerUnitTest {
|
||||
assertThat(errorResponse.getBody().getMessage()).isEqualTo("some error message");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(classes = {
|
||||
org.iban4j.InvalidCheckDigitException.class,
|
||||
org.iban4j.IbanFormatException.class,
|
||||
org.iban4j.BicFormatException.class })
|
||||
void handlesIbanAndBicExceptions(final Class<? extends RuntimeException> givenExceptionClass)
|
||||
throws Exception {
|
||||
// given
|
||||
final var givenException = givenExceptionClass.getConstructor(String.class).newInstance("given error message");
|
||||
final var givenWebRequest = mock(WebRequest.class);
|
||||
|
||||
// when
|
||||
final var errorResponse = exceptionHandler.handleIbanAndBicExceptions(givenException, givenWebRequest);
|
||||
|
||||
// then
|
||||
assertThat(errorResponse.getStatusCodeValue()).isEqualTo(400);
|
||||
assertThat(errorResponse.getBody().getMessage()).isEqualTo("given error message");
|
||||
}
|
||||
|
||||
@Test
|
||||
void handleOtherExceptionsWithoutErrorCode() {
|
||||
// given
|
||||
|
@@ -115,7 +115,7 @@ class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
|
||||
@Nested
|
||||
@Accepts({ "bankaccount:C(Create)" })
|
||||
class AddBankAccount {
|
||||
class CreateBankAccount {
|
||||
|
||||
@Test
|
||||
void globalAdmin_withoutAssumedRole_canAddBankAccount() {
|
||||
@@ -127,11 +127,11 @@ class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.contentType(ContentType.JSON)
|
||||
.body("""
|
||||
{
|
||||
"holder": "new test holder",
|
||||
"iban": "DE88100900001234567892",
|
||||
"bic": "BEVODEBB"
|
||||
}
|
||||
{
|
||||
"holder": "new test holder",
|
||||
"iban": "DE88100900001234567892",
|
||||
"bic": "BEVODEBB"
|
||||
}
|
||||
""")
|
||||
.port(port)
|
||||
.when()
|
||||
@@ -195,8 +195,7 @@ class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Accepts({ "bankaccount:X(Access Control)" })
|
||||
@Disabled("TODO: not implemented yet")
|
||||
@Disabled("TODO: not implemented yet - also add Accepts annotation when done")
|
||||
void bankaccountAdminUser_canGetRelatedBankAccount() {
|
||||
context.define("superuser-alex@hostsharing.net");
|
||||
final var givenBankAccountUuid = bankAccountRepo.findByOptionalHolderLike("first").get(0).getUuid();
|
||||
@@ -212,9 +211,9 @@ class HsOfficeBankAccountControllerAcceptanceTest {
|
||||
.contentType("application/json")
|
||||
.body("", lenientlyEquals("""
|
||||
{
|
||||
"label": "first bankaccount",
|
||||
"emailAddresses": "bankaccount-admin@firstbankaccount.example.com",
|
||||
"phoneNumbers": "+49 123 1234567"
|
||||
"holder": "...",
|
||||
"iban": "...",
|
||||
"bic": "..."
|
||||
}
|
||||
""")); // @formatter:on
|
||||
}
|
||||
|
@@ -0,0 +1,125 @@
|
||||
package net.hostsharing.hsadminng.hs.office.bankaccount;
|
||||
|
||||
import net.hostsharing.hsadminng.context.Context;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.EnumSource;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
@WebMvcTest(HsOfficeBankAccountController.class)
|
||||
class HsOfficeBankAccountControllerRestTest {
|
||||
|
||||
@Autowired
|
||||
MockMvc mockMvc;
|
||||
|
||||
@MockBean
|
||||
Context contextMock;
|
||||
|
||||
@MockBean
|
||||
HsOfficeBankAccountRepository bankAccountRepo;
|
||||
|
||||
enum InvalidIbanTestCase {
|
||||
TOO_SHORT("DE8810090000123456789", "[10090000123456789] length is 17, expected BBAN length is: 18"),
|
||||
TOO_LONG("DE8810090000123456789123445", "[10090000123456789123445] length is 23, expected BBAN length is: 18"),
|
||||
INVALID_CHARACTER("DE 8810090000123456789123445", "Iban's check digit should contain only digits."),
|
||||
INVALID_CHECKSUM(
|
||||
"DE88100900001234567893",
|
||||
"[DE88100900001234567893] has invalid check digit: 88, expected check digit is: 61");
|
||||
|
||||
private final String givenIban;
|
||||
private final String expectedIbanMessage;
|
||||
|
||||
InvalidIbanTestCase(final String givenIban, final String expectedErrorMessage) {
|
||||
this.givenIban = givenIban;
|
||||
this.expectedIbanMessage = expectedErrorMessage;
|
||||
}
|
||||
|
||||
String givenIban() {
|
||||
return givenIban;
|
||||
}
|
||||
|
||||
String expectedErrorMessage() {
|
||||
return expectedIbanMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(InvalidIbanTestCase.class)
|
||||
void invalidIbanBeRejected(final InvalidIbanTestCase testCase) throws Exception {
|
||||
|
||||
// when
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.post("/api/hs/office/bankaccounts")
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"holder": "new test holder",
|
||||
"iban": "%s",
|
||||
"bic": "BEVODEBB"
|
||||
}
|
||||
""".formatted(testCase.givenIban()))
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
|
||||
// then
|
||||
.andExpect(status().is4xxClientError())
|
||||
.andExpect(jsonPath("status", is(400)))
|
||||
.andExpect(jsonPath("error", is("Bad Request")))
|
||||
.andExpect(jsonPath("message", is(testCase.expectedErrorMessage())));
|
||||
}
|
||||
|
||||
enum InvalidBicTestCase {
|
||||
TOO_SHORT("BEVODEB", "Bic length must be 8 or 11"),
|
||||
TOO_LONG("BEVODEBBX", "Bic length must be 8 or 11"),
|
||||
INVALID_CHARACTER("BEV-ODEB", "Bank code must contain only letters.");
|
||||
|
||||
private final String givenBic;
|
||||
private final String expectedErrorMessage;
|
||||
|
||||
InvalidBicTestCase(final String givenBic, final String expectedErrorMessage) {
|
||||
this.givenBic = givenBic;
|
||||
this.expectedErrorMessage = expectedErrorMessage;
|
||||
}
|
||||
|
||||
String givenIban() {
|
||||
return givenBic;
|
||||
}
|
||||
|
||||
String expectedErrorMessage() {
|
||||
return expectedErrorMessage;
|
||||
}
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@EnumSource(InvalidBicTestCase.class)
|
||||
void invalidBicBeRejected(final InvalidBicTestCase testCase) throws Exception {
|
||||
|
||||
// when
|
||||
mockMvc.perform(MockMvcRequestBuilders
|
||||
.post("/api/hs/office/bankaccounts")
|
||||
.header("current-user", "superuser-alex@hostsharing.net")
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"holder": "new test holder",
|
||||
"iban": "DE88100900001234567892",
|
||||
"bic": "%s"
|
||||
}
|
||||
""".formatted(testCase.givenIban()))
|
||||
.accept(MediaType.APPLICATION_JSON))
|
||||
|
||||
// then
|
||||
.andExpect(status().is4xxClientError())
|
||||
.andExpect(jsonPath("status", is(400)))
|
||||
.andExpect(jsonPath("error", is("Bad Request")))
|
||||
.andExpect(jsonPath("message", is(testCase.expectedErrorMessage())));
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user