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

Add unit tests for Bean validation #22

Merged
merged 4 commits into from Nov 30, 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 11 additions & 1 deletion common/build.gradle
Expand Up @@ -17,6 +17,9 @@ repositories {
mavenCentral()
}

test {
useJUnitPlatform()
}

dependencies {
compile('com.fasterxml.jackson.core:jackson-databind:2.9.6')
Expand All @@ -26,5 +29,12 @@ dependencies {
compile('org.hibernate.validator:hibernate-validator:6.2.0.Final')
compileOnly 'org.projectlombok:lombok:1.18.18'
annotationProcessor 'org.projectlombok:lombok:1.18.18'
testCompile group: 'junit', name: 'junit', version: '4.12'

testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
testImplementation 'org.assertj:assertj-core:3.21.0'

// For Bean validation test
compile('javax.el:javax.el-api:3.0.0')
compile('org.glassfish:javax.el:3.0.0')
}
@@ -0,0 +1,47 @@
package com.linecorp.line.auth.fido.fido2.common.server.bean.validation;

import com.linecorp.line.auth.fido.fido2.common.server.AuthOptionRequest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

class AuthOptionRequestBeanValidationTest extends BeanValidationTestSupport {

private static AuthOptionRequest origin;
private AuthOptionRequest authOptionRequest;

@BeforeAll
static void initGlobal() throws IOException {
origin = objectMapper.readValue(AuthOptionRequest.class.getResourceAsStream("/json/auth/auth-challenge-req.json"), AuthOptionRequest.class);
}

@BeforeEach
void setUp() throws IOException {
//Deep copy
authOptionRequest = objectMapper.readValue(objectMapper.writeValueAsString(origin), AuthOptionRequest.class);
}

@Test
void validateSuccessfulRequest() {
final Set<ConstraintViolation<AuthOptionRequest>> constraintViolations = validator.validate(authOptionRequest);
assertThat(constraintViolations).isEmpty();
}

@Test
void validateIncompleteRequestWithBlank() {

authOptionRequest.setRpId("");

final Set<ConstraintViolation<AuthOptionRequest>> constraintViolations = validator.validate(authOptionRequest);

assertThat(constraintViolations).hasSize(1);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_BLANK);
}
}
@@ -0,0 +1,26 @@
package com.linecorp.line.auth.fido.fido2.common.server.bean.validation;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeAll;

import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Locale;

public class BeanValidationTestSupport {

protected static final String MUST_NOT_BE_NULL = "must not be null";
protected static final String MUST_NOT_BE_BLANK = "must not be blank";
protected static final String MUST_BE_A_WELL_FORMED_BASE_64 = "must be a well-formed base64";
protected static final String LENGTH_MUST_BE_BETWEEN_1_AND_64 = "length must be between 1 and 64";
protected static final String NOT_VALID_BASE64_URL_STRING = "!@=/+";

protected static final ObjectMapper objectMapper = new ObjectMapper();
protected static Validator validator;

@BeforeAll
static void init() {
Locale.setDefault(Locale.ENGLISH);
validator = Validation.buildDefaultValidatorFactory().getValidator();
}
}
@@ -0,0 +1,48 @@
package com.linecorp.line.auth.fido.fido2.common.server.bean.validation;

import com.linecorp.line.auth.fido.fido2.common.server.RegOptionRequest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

class RegOptionRequestBeanValidationTest extends BeanValidationTestSupport {

private static RegOptionRequest origin;
private RegOptionRequest regOptionRequest;

@BeforeAll
static void initGlobal() throws IOException {
origin = objectMapper.readValue(RegOptionRequest.class.getResourceAsStream("/json/reg/reg-challenge-req.json"), RegOptionRequest.class);
}

@BeforeEach
void setUp() throws IOException {
//Deep copy
regOptionRequest = objectMapper.readValue(objectMapper.writeValueAsString(origin), RegOptionRequest.class);
}

@Test
void validateSuccessfulRequest() {
final Set<ConstraintViolation<RegOptionRequest>> constraintViolations = validator.validate(regOptionRequest);
assertThat(constraintViolations).isEmpty();
}

@Test
void validateIncompleteRequestWithNull() {

regOptionRequest.setRp(null);
regOptionRequest.setUser(null);

final Set<ConstraintViolation<RegOptionRequest>> constraintViolations = validator.validate(regOptionRequest);

assertThat(constraintViolations).hasSize(2);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_NULL);
}
}
@@ -0,0 +1,61 @@
package com.linecorp.line.auth.fido.fido2.common.server.bean.validation;

import com.linecorp.line.auth.fido.fido2.common.server.RegisterCredential;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

class RegisterCredentialBeanValidationTest extends BeanValidationTestSupport {

private static RegisterCredential origin;
private RegisterCredential registerCredential;

@BeforeAll
static void initGlobal() throws IOException {
origin = objectMapper.readValue(RegisterCredential.class.getResourceAsStream("/json/reg/reg-response-req.json"), RegisterCredential.class);
}

@BeforeEach
void setUp() throws IOException {
//Deep copy
registerCredential = objectMapper.readValue(objectMapper.writeValueAsString(origin), RegisterCredential.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice idea to load the base request first!

}

@Test
void validateSuccessfulRequest() {
final Set<ConstraintViolation<RegisterCredential>> constraintViolations = validator.validate(registerCredential);
assertThat(constraintViolations).isEmpty();
}

@Test
void validateIncompleteRequestWithNull() {

registerCredential.setServerPublicKeyCredential(null);

final Set<ConstraintViolation<RegisterCredential>> constraintViolations = validator.validate(registerCredential);

assertThat(constraintViolations).hasSize(1);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_NULL);
}

@Test
void validateIncompleteRequestWithBlank() {

registerCredential.setOrigin("");
registerCredential.setRpId("");
registerCredential.setSessionId("");

final Set<ConstraintViolation<RegisterCredential>> constraintViolations = validator.validate(registerCredential);

assertThat(constraintViolations).hasSize(3);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_BLANK);
}
}
@@ -0,0 +1,74 @@
package com.linecorp.line.auth.fido.fido2.common.server.bean.validation;

import com.linecorp.line.auth.fido.fido2.common.server.ServerAuthPublicKeyCredential;
import com.linecorp.line.auth.fido.fido2.common.server.VerifyCredential;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

class ServerAuthPublicKeyCredentialBeanValidationTest extends BeanValidationTestSupport {

private static ServerAuthPublicKeyCredential origin;
private ServerAuthPublicKeyCredential serverAuthPublicKeyCredential;

@BeforeAll
static void initGlobal() throws IOException {
origin = objectMapper.readValue(VerifyCredential.class.getResourceAsStream("/json/auth/auth-response-req.json"), VerifyCredential.class).getServerPublicKeyCredential();
}

@BeforeEach
void setUp() throws IOException {
//Deep copy
serverAuthPublicKeyCredential = objectMapper.readValue(objectMapper.writeValueAsString(origin), ServerAuthPublicKeyCredential.class);
}

@Test
void validateSuccessfulRequest() {
final Set<ConstraintViolation<ServerAuthPublicKeyCredential>> constraintViolations = validator.validate(serverAuthPublicKeyCredential);
assertThat(constraintViolations).isEmpty();
}

@Test
void validateIncompleteRequestWithNull() {

serverAuthPublicKeyCredential.setResponse(null);
serverAuthPublicKeyCredential.setType(null);

final Set<ConstraintViolation<ServerAuthPublicKeyCredential>> constraintViolations = validator.validate(serverAuthPublicKeyCredential);

assertThat(constraintViolations).hasSize(2);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_NULL);
}

@Test
void validateIncompleteRequestWithBlank() {

serverAuthPublicKeyCredential.setId("");

final Set<ConstraintViolation<ServerAuthPublicKeyCredential>> constraintViolations = validator.validate(serverAuthPublicKeyCredential);

assertThat(constraintViolations).hasSize(1);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_BLANK);
}

@Test
void validateIncompleteRequestWithInvalidBase64Url() {

final String id = serverAuthPublicKeyCredential.getId() + NOT_VALID_BASE64_URL_STRING;
serverAuthPublicKeyCredential.setId(id);

final Set<ConstraintViolation<ServerAuthPublicKeyCredential>> constraintViolations = validator.validate(serverAuthPublicKeyCredential);

assertThat(constraintViolations).hasSize(1);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_BE_A_WELL_FORMED_BASE_64);
}
}
@@ -0,0 +1,68 @@
package com.linecorp.line.auth.fido.fido2.common.server.bean.validation;

import com.linecorp.line.auth.fido.fido2.common.server.ServerAuthenticatorAssertionResponse;
import com.linecorp.line.auth.fido.fido2.common.server.VerifyCredential;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;

class ServerAuthenticatorAssertionResponseBeanValidationTest extends BeanValidationTestSupport {
private static ServerAuthenticatorAssertionResponse origin;
private ServerAuthenticatorAssertionResponse serverAuthenticatorAssertionResponse;

@BeforeAll
static void initGlobal() throws IOException {
origin = objectMapper.readValue(VerifyCredential.class.getResourceAsStream("/json/auth/auth-response-req.json"), VerifyCredential.class).getServerPublicKeyCredential().getResponse();
}

@BeforeEach
void setUp() throws IOException {
//Deep copy
serverAuthenticatorAssertionResponse = objectMapper.readValue(objectMapper.writeValueAsString(origin), ServerAuthenticatorAssertionResponse.class);
}

@Test
void validateSuccessfulRequest() {
final Set<ConstraintViolation<ServerAuthenticatorAssertionResponse>> constraintViolations = validator.validate(serverAuthenticatorAssertionResponse);
assertThat(constraintViolations).isEmpty();
}

@Test
void validateIncompleteRequestWithBlank() {

serverAuthenticatorAssertionResponse.setAuthenticatorData("");
serverAuthenticatorAssertionResponse.setClientDataJSON("");
serverAuthenticatorAssertionResponse.setSignature("");

final Set<ConstraintViolation<ServerAuthenticatorAssertionResponse>> constraintViolations = validator.validate(serverAuthenticatorAssertionResponse);

assertThat(constraintViolations).hasSize(3);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_NOT_BE_BLANK);
}

@Test
void validateIncompleteRequestWithInvalidBase64Url() {

final String authenticatorData = serverAuthenticatorAssertionResponse.getAuthenticatorData() + NOT_VALID_BASE64_URL_STRING;
serverAuthenticatorAssertionResponse.setAuthenticatorData(authenticatorData);

final String clientDataJSON = serverAuthenticatorAssertionResponse.getClientDataJSON() + NOT_VALID_BASE64_URL_STRING;
serverAuthenticatorAssertionResponse.setClientDataJSON(clientDataJSON);

final String signature = serverAuthenticatorAssertionResponse.getSignature() + NOT_VALID_BASE64_URL_STRING;
serverAuthenticatorAssertionResponse.setSignature(signature);

final Set<ConstraintViolation<ServerAuthenticatorAssertionResponse>> constraintViolations = validator.validate(serverAuthenticatorAssertionResponse);

assertThat(constraintViolations).hasSize(3);
assertThat(constraintViolations).extracting(ConstraintViolation::getMessage)
.containsOnly(MUST_BE_A_WELL_FORMED_BASE_64);
}
}