experimental CustomerRepositoryIntegrationTest with Given/When/Then classes
This commit is contained in:
parent
27c5699c36
commit
f58a68d1cc
@ -1,26 +1,26 @@
|
|||||||
package net.hostsharing.hsadminng.hscustomer;
|
package net.hostsharing.hsadminng.hscustomer;
|
||||||
|
|
||||||
import net.hostsharing.hsadminng.context.Context;
|
import net.hostsharing.hsadminng.context.Context;
|
||||||
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
|
import org.springframework.core.NestedRuntimeException;
|
||||||
import org.springframework.orm.jpa.JpaSystemException;
|
import org.springframework.orm.jpa.JpaSystemException;
|
||||||
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
||||||
|
|
||||||
@DataJpaTest
|
@DataJpaTest
|
||||||
@ComponentScan(basePackageClasses = { Context.class, CustomerRepository.class })
|
@ComponentScan(basePackageClasses = { Context.class, CustomerRepository.class })
|
||||||
class CustomerRepositoryIntegrationTest {
|
class CustomerRepositoryIntegrationTest {
|
||||||
|
|
||||||
final static String adminUser = "mike@hostsharing.net";
|
|
||||||
final static String customerAaa = "admin@aaa.example.com";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
Context context;
|
Context context;
|
||||||
|
|
||||||
@ -29,127 +29,154 @@ class CustomerRepositoryIntegrationTest {
|
|||||||
|
|
||||||
@Autowired EntityManager em;
|
@Autowired EntityManager em;
|
||||||
|
|
||||||
@Test
|
@Nested
|
||||||
@Transactional
|
class FindAll {
|
||||||
void hostsharingAdminWithoutAssumedRoleCanViewAllCustomers() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser(adminUser);
|
|
||||||
|
|
||||||
// when
|
private final Given given = new Given();
|
||||||
final var actual = customerRepository.findAll();
|
private When<List<CustomerEntity>> when;
|
||||||
|
private final Then then = new Then();
|
||||||
|
|
||||||
// then
|
@Test
|
||||||
|
public void hostsharingAdminWithoutAssumedRoleCanViewAllCustomers() {
|
||||||
|
given.currentUser("mike@hostsharing.net");
|
||||||
|
|
||||||
assertThat(actual).hasSize(3)
|
when(() -> customerRepository.findAll());
|
||||||
.extracting(CustomerEntity::getPrefix)
|
|
||||||
.containsExactlyInAnyOrder("aaa", "aab", "aac");
|
then.exactlyTheseCustomersAreReturned("aaa", "aab", "aac");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void hostsharingAdminWithAssumedHostsharingAdminRoleCanViewAllCustomers() {
|
||||||
|
given.currentUser("mike@hostsharing.net").
|
||||||
|
and().assumedRoles("global#hostsharing.admin");
|
||||||
|
|
||||||
|
when(() -> customerRepository.findAll());
|
||||||
|
|
||||||
|
then.exactlyTheseCustomersAreReturned("aaa", "aab", "aac");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customerAdminWithoutAssumedRoleCanViewOnlyItsOwnCustomer() {
|
||||||
|
given.currentUser("admin@aaa.example.com");
|
||||||
|
|
||||||
|
when(() -> customerRepository.findAll());
|
||||||
|
|
||||||
|
then.exactlyTheseCustomersAreReturned("aaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customerAdminWithAssumedOwnedPackageAdminRoleCanViewOnlyItsOwnCustomer() {
|
||||||
|
given.currentUser("admin@aaa.example.com").
|
||||||
|
and().assumedRoles("package#aaa00.admin");
|
||||||
|
|
||||||
|
when(() -> customerRepository.findAll());
|
||||||
|
|
||||||
|
then.exactlyTheseCustomersAreReturned("aaa");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void customerAdmin_withAssumedAlienPackageAdminRole_cannotViewAnyCustomer() {
|
||||||
|
given.currentUser("admin@aaa.example.com").
|
||||||
|
and().assumedRoles("package#aab00.admin");
|
||||||
|
|
||||||
|
when(() -> customerRepository.findAll());
|
||||||
|
|
||||||
|
then.expectJpaSystemExceptionHasBeenThrown().
|
||||||
|
and()
|
||||||
|
.expectRootCauseMessageMatches(
|
||||||
|
".* user admin@aaa.example.com .* has no permission to assume role package#aab00#admin .*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void unknownUser_withoutAssumedRole_cannotViewAnyCustomers() {
|
||||||
|
given.currentUser("unknown@example.org");
|
||||||
|
|
||||||
|
when(() -> customerRepository.findAll());
|
||||||
|
|
||||||
|
then.expectJpaSystemExceptionHasBeenThrown().
|
||||||
|
and().expectRootCauseMessageMatches(".* user unknown@example.org does not exist.*");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Transactional
|
||||||
|
void unknownUserWithAssumedCustomerRoleCannotViewAnyCustomers() {
|
||||||
|
given.currentUser("unknown@example.org").
|
||||||
|
and().assumedRoles("customer#aaa.admin");
|
||||||
|
|
||||||
|
when(() -> customerRepository.findAll());
|
||||||
|
|
||||||
|
then.expectJpaSystemExceptionHasBeenThrown().
|
||||||
|
and().expectRootCauseMessageMatches(".* user unknown@example.org does not exist.*");
|
||||||
|
}
|
||||||
|
|
||||||
|
void when(final Supplier<List<CustomerEntity>> code) {
|
||||||
|
try {
|
||||||
|
when = new When<>(code.get());
|
||||||
|
} catch (final NestedRuntimeException exc) {
|
||||||
|
when = new When<>(exc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Then {
|
||||||
|
|
||||||
|
Then and() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void exactlyTheseCustomersAreReturned(final String... customerPrefixes) {
|
||||||
|
assertThat(when.actualResult)
|
||||||
|
.hasSize(customerPrefixes.length)
|
||||||
|
.extracting(CustomerEntity::getPrefix)
|
||||||
|
.containsExactlyInAnyOrder(customerPrefixes);
|
||||||
|
}
|
||||||
|
|
||||||
|
Then expectJpaSystemExceptionHasBeenThrown() {
|
||||||
|
assertThat(when.actualException).isInstanceOf(JpaSystemException.class);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void expectRootCauseMessageMatches(final String expectedMessage) {
|
||||||
|
assertThat(firstRootCauseMessageLineOf(when.actualException)).matches(expectedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
private String firstRootCauseMessageLineOf(final NestedRuntimeException exception) {
|
||||||
@Transactional
|
return Optional.ofNullable(exception.getRootCause())
|
||||||
void hostsharingAdminWithAssumedHostsharingAdminRoleCanViewAllCustomers() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser(adminUser);
|
|
||||||
context.assumeRoles("global#hostsharing.admin");
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var actual = customerRepository.findAll();
|
|
||||||
|
|
||||||
// then
|
|
||||||
|
|
||||||
assertThat(actual).hasSize(3)
|
|
||||||
.extracting(CustomerEntity::getPrefix)
|
|
||||||
.containsExactlyInAnyOrder("aaa", "aab", "aac");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void customerAdminWithoutAssumedRoleCanViewItsOwnCustomer() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser(customerAaa);
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var actual = customerRepository.findAll();
|
|
||||||
|
|
||||||
// then
|
|
||||||
|
|
||||||
assertThat(actual).hasSize(1)
|
|
||||||
.extracting(CustomerEntity::getPrefix)
|
|
||||||
.containsExactly("aaa");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void customerAdminWithAssumedOwnedPackageAdminRoleCanViewItsOwnCustomer() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser(customerAaa);
|
|
||||||
context.assumeRoles("package#aaa00.admin");
|
|
||||||
|
|
||||||
// when
|
|
||||||
final var actual = customerRepository.findAll();
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(actual).hasSize(1)
|
|
||||||
.extracting(CustomerEntity::getPrefix)
|
|
||||||
.containsExactly("aaa");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void customerAdminWithAssumedAlienPackageAdminRoleCanViewItsOwnCustomer() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser(customerAaa);
|
|
||||||
context.assumeRoles("package#aab00.admin");
|
|
||||||
|
|
||||||
// when
|
|
||||||
final JpaSystemException thrown =
|
|
||||||
assertThrows(JpaSystemException.class, () -> customerRepository.findAll());
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(firstRootCauseMessageLineOf(thrown)).matches(
|
|
||||||
".* user admin@aaa.example.com .* has no permission to assume role package#aab00#admin .*"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void unknownUserWithoutAssumedRoleCannotViewAnyCustomers() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser("unknown@example.org");
|
|
||||||
|
|
||||||
// when
|
|
||||||
final JpaSystemException thrown =
|
|
||||||
assertThrows(JpaSystemException.class, () -> customerRepository.findAll());
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(firstRootCauseMessageLineOf(thrown)).matches(
|
|
||||||
".* user unknown@example.org does not exist.*"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Transactional
|
|
||||||
void unknownUserWithAssumedRoleCannotViewAnyCustomers() {
|
|
||||||
// given
|
|
||||||
context.setCurrentUser("unknown@example.org");
|
|
||||||
assertThat(context.getCurrentUser()).isEqualTo("unknown@example.org");
|
|
||||||
context.assumeRoles("customer#aaa.admin");
|
|
||||||
|
|
||||||
|
|
||||||
// when
|
|
||||||
final JpaSystemException thrown =
|
|
||||||
assertThrows(JpaSystemException.class, () -> customerRepository.findAll());
|
|
||||||
|
|
||||||
// then
|
|
||||||
assertThat(firstRootCauseMessageLineOf(thrown)).matches(
|
|
||||||
".* user unknown@example.org does not exist.*"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String firstRootCauseMessageLineOf(final JpaSystemException throwable) {
|
|
||||||
return Optional.ofNullable(throwable.getRootCause())
|
|
||||||
.map(Throwable::getMessage)
|
.map(Throwable::getMessage)
|
||||||
.map( message -> message.split("\\r|\\n|\\r\\n", 0)[0])
|
.map(message -> message.split("\\r|\\n|\\r\\n", 0)[0])
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Given {
|
||||||
|
|
||||||
|
Given and() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
Given currentUser(final String currentUser) {
|
||||||
|
context.setCurrentUser(currentUser);
|
||||||
|
assertThat(context.getCurrentUser()).as("precondition").isEqualTo(currentUser);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void assumedRoles(final String assumedRoles) {
|
||||||
|
context.assumeRoles(assumedRoles);
|
||||||
|
assertThat(context.getAssumedRoles()).as("precondition").containsExactly(assumedRoles.split(";"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class When<T> {
|
||||||
|
|
||||||
|
T actualResult;
|
||||||
|
NestedRuntimeException actualException;
|
||||||
|
|
||||||
|
When(final T actualResult) {
|
||||||
|
this.actualResult = actualResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
When(final NestedRuntimeException exception) {
|
||||||
|
this.actualException = exception;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user