diff --git a/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepository.java b/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepository.java index ad46ab33..a882b304 100644 --- a/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepository.java +++ b/src/main/java/net/hostsharing/hsadminng/test/cust/TestCustomerRepository.java @@ -18,4 +18,6 @@ public interface TestCustomerRepository extends Repository NEW.uuid, permitOps => array ['*']), beneathRole(testCustomerAdmin(parentCustomer)) ); @@ -64,7 +64,6 @@ end; $$; An AFTER INSERT TRIGGER which creates the role structure for a new package. */ -drop trigger if exists createRbacRolesForTestPackage_Trigger on test_package; create trigger createRbacRolesForTestPackage_Trigger after insert on test_package @@ -76,9 +75,7 @@ execute procedure createRbacRolesForTestPackage(); -- ============================================================================ --changeset test-package-rbac-IDENTITY-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- -call generateRbacIdentityView('test_package', $idName$ - target.name - $idName$); +call generateRbacIdentityView('test_package', 'target.name'); --// @@ -90,11 +87,22 @@ call generateRbacIdentityView('test_package', $idName$ Creates a view to the customer main table which maps the identifying name (in this case, the prefix) to the objectUuid. */ -drop view if exists test_package_rv; -create or replace view test_package_rv as -select target.* - from test_package as target - where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids())) - order by target.name; -grant all privileges on test_package_rv to restricted; +-- drop view if exists test_package_rv; +-- create or replace view test_package_rv as +-- select target.* +-- from test_package as target +-- where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'test_package', currentSubjectsUuids())) +-- order by target.name; +-- grant all privileges on test_package_rv to restricted; + +call generateRbacRestrictedView('test_package', 'target.name', + $updates$ + version = new.version, + customerUuid = new.customerUuid, + name = new.name, + description = new.description + $updates$); + --// + + diff --git a/src/main/resources/db/changelog/128-test-package-test-data.sql b/src/main/resources/db/changelog/128-test-package-test-data.sql index 8c8b8d9c..4667b742 100644 --- a/src/main/resources/db/changelog/128-test-package-test-data.sql +++ b/src/main/resources/db/changelog/128-test-package-test-data.sql @@ -31,7 +31,7 @@ begin insert into test_package (customerUuid, name, description) - values (cust.uuid, pacName, 'Here can add your own description of package ' || pacName || '.') + values (cust.uuid, pacName, 'Here you can add your own description of package ' || pacName || '.') returning * into pac; call grantRoleToUser( diff --git a/src/main/resources/db/changelog/133-test-domain-rbac.sql b/src/main/resources/db/changelog/133-test-domain-rbac.sql index 0774ef05..b1c46143 100644 --- a/src/main/resources/db/changelog/133-test-domain-rbac.sql +++ b/src/main/resources/db/changelog/133-test-domain-rbac.sql @@ -100,7 +100,7 @@ call generateRbacIdentityView('test_domain', $idName$ -- ============================================================================ ---changeset test-package-rbac-RESTRICTED-VIEW:1 endDelimiter:--// +--changeset test-domain-rbac-RESTRICTED-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- /* diff --git a/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql b/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql index 0502b2ba..303e11a6 100644 --- a/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql +++ b/src/main/resources/db/changelog/203-hs-office-contact-rbac.sql @@ -86,82 +86,16 @@ call generateRbacIdentityView('hs_office_contact', $idName$ -- ============================================================================ --changeset hs-office-contact-rbac-RESTRICTED-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- -/* - Creates a view to the contact main table with row-level limitation - based on the 'view' permission of the current user or assumed roles. - */ -set session session authorization default; -drop view if exists hs_office_contact_rv; -create or replace view hs_office_contact_rv as -select target.* - from hs_office_contact as target - where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'hs_office_contact', currentSubjectsUuids())); -grant all privileges on hs_office_contact_rv to restricted; ---// - - --- ============================================================================ ---changeset hs-office-contact-rbac-INSTEAD-OF-INSERT-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of insert trigger function for hs_office_contact_rv. - */ -create or replace function insertHsOfficeContact() - returns trigger - language plpgsql as $$ -declare - newUser hs_office_contact; -begin - insert - into hs_office_contact - values (new.*) - returning * into newUser; - return newUser; -end; -$$; - -/* - Creates an instead of insert trigger for the hs_office_contact_rv view. - */ -create trigger insertHsOfficeContact_Trigger - instead of insert - on hs_office_contact_rv - for each row -execute function insertHsOfficeContact(); ---// - --- ============================================================================ ---changeset hs-office-contact-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of delete trigger function for hs_office_contact_rv. - - Checks if the current subject (user / assumed role) has the permission to delete the row. - */ -create or replace function deleteHsOfficeContact() - returns trigger - language plpgsql as $$ -begin - if hasGlobalRoleGranted(currentUserUuid()) or - old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_contact', currentSubjectsUuids())) then - delete from hs_office_contact c where c.uuid = old.uuid; - return old; - end if; - raise exception '[403] User % not allowed to delete contact uuid %', currentUser(), old.uuid; -end; $$; - -/* - Creates an instead of delete trigger for the hs_office_contact_rv view. - */ -create trigger deleteHsOfficeContact_Trigger - instead of delete - on hs_office_contact_rv - for each row -execute function deleteHsOfficeContact(); +call generateRbacRestrictedView('hs_office_contact', 'target.label', + $updates$ + label = new.label, + postalAddress = new.postalAddress, + emailAddresses = new.emailAddresses, + phoneNumbers = new.phoneNumbers + $updates$); --/ + -- ============================================================================ --changeset hs-office-contact-rbac-NEW-CONTACT:1 endDelimiter:--// -- ---------------------------------------------------------------------------- diff --git a/src/main/resources/db/changelog/213-hs-office-person-rbac.sql b/src/main/resources/db/changelog/213-hs-office-person-rbac.sql index a9fbe4a0..63a88d2a 100644 --- a/src/main/resources/db/changelog/213-hs-office-person-rbac.sql +++ b/src/main/resources/db/changelog/213-hs-office-person-rbac.sql @@ -17,11 +17,9 @@ call generateRbacRoleDescriptors('hsOfficePerson', 'hs_office_person'); -- ============================================================================ --changeset hs-office-person-rbac-ROLES-CREATION:1 endDelimiter:--// -- ---------------------------------------------------------------------------- - /* Creates the roles and their assignments for a new person for the AFTER INSERT TRIGGER. */ - create or replace function createRbacRolesForHsOfficePerson() returns trigger language plpgsql @@ -85,82 +83,16 @@ call generateRbacIdentityView('hs_office_person', $idName$ -- ============================================================================ --changeset hs-office-person-rbac-RESTRICTED-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- -/* - Creates a view to the person main table with row-level limitation - based on the 'view' permission of the current user or assumed roles. - */ -set session session authorization default; -drop view if exists hs_office_person_rv; -create or replace view hs_office_person_rv as -select target.* - from hs_office_person as target - where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'hs_office_person', currentSubjectsUuids())); -grant all privileges on hs_office_person_rv to restricted; +call generateRbacRestrictedView('hs_office_person', 'concat(target.tradeName, target.familyName, target.givenName)', + $updates$ + personType = new.personType, + tradeName = new.tradeName, + givenName = new.givenName, + familyName = new.familyName + $updates$); --// --- ============================================================================ ---changeset hs-office-person-rbac-INSTEAD-OF-INSERT-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of insert trigger function for hs_office_person_rv. - */ -create or replace function insertHsOfficePerson() - returns trigger - language plpgsql as $$ -declare - newUser hs_office_person; -begin - insert - into hs_office_person - values (new.*) - returning * into newUser; - return newUser; -end; -$$; - -/* - Creates an instead of insert trigger for the hs_office_person_rv view. - */ -create trigger insertHsOfficePerson_Trigger - instead of insert - on hs_office_person_rv - for each row -execute function insertHsOfficePerson(); ---// - --- ============================================================================ ---changeset hs-office-person-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of delete trigger function for hs_office_person_rv. - - Checks if the current subject (user / assumed role) has the permission to delete the row. - */ -create or replace function deleteHsOfficePerson() - returns trigger - language plpgsql as $$ -begin - if hasGlobalRoleGranted(currentUserUuid()) or - old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_person', currentSubjectsUuids())) then - delete from hs_office_person c where c.uuid = old.uuid; - return old; - end if; - raise exception '[403] User % not allowed to delete person uuid %', currentUser(), old.uuid; -end; $$; - -/* - Creates an instead of delete trigger for the hs_office_person_rv view. - */ -create trigger deleteHsOfficePerson_Trigger - instead of delete - on hs_office_person_rv - for each row -execute function deleteHsOfficePerson(); ---/ - -- ============================================================================ --changeset hs-office-person-rbac-NEW-PERSON:1 endDelimiter:--// -- ---------------------------------------------------------------------------- diff --git a/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql b/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql index cc108f7a..b004e965 100644 --- a/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql +++ b/src/main/resources/db/changelog/223-hs-office-partner-rbac.sql @@ -127,122 +127,20 @@ call generateRbacIdentityView('hs_office_partner', $idName$ -- ============================================================================ --changeset hs-office-partner-rbac-RESTRICTED-VIEW:1 endDelimiter:--// -- ---------------------------------------------------------------------------- -/* - Creates a view to the partner main table with row-level limitation - based on the 'view' permission of the current user or assumed roles. - */ -set session session authorization default; -drop view if exists hs_office_partner_rv; -create or replace view hs_office_partner_rv as -select target.* - from hs_office_partner as target - where target.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('view', 'hs_office_partner', currentSubjectsUuids())); -grant all privileges on hs_office_partner_rv to restricted; +call generateRbacRestrictedView('hs_office_partner', + '(select idName from hs_office_person_iv p where p.uuid = target.personUuid)', + $updates$ + personUuid = new.personUuid, + contactUuid = new.contactUuid, + registrationOffice = new.registrationOffice, + registrationNumber = new.registrationNumber, + birthday = new.birthday, + birthName = new.birthName, + dateOfDeath = new.dateOfDeath + $updates$); --// --- ============================================================================ ---changeset hs-office-partner-rbac-INSTEAD-OF-INSERT-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of insert trigger function for hs_office_partner_rv. - */ -create or replace function insertHsOfficePartner() - returns trigger - language plpgsql as $$ -declare - newUser hs_office_partner; -begin - insert - into hs_office_partner - values (new.*) - returning * into newUser; - return newUser; -end; -$$; - -/* - Creates an instead of insert trigger for the hs_office_partner_rv view. - */ -create trigger insertHsOfficePartner_Trigger - instead of insert - on hs_office_partner_rv - for each row -execute function insertHsOfficePartner(); ---// - - --- ============================================================================ ---changeset hs-office-partner-rbac-INSTEAD-OF-DELETE-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of delete trigger function for hs_office_partner_rv. - - Checks if the current subject (user / assumed role) has the permission to delete the row. - */ -create or replace function deleteHsOfficePartner() - returns trigger - language plpgsql as $$ -begin - if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('delete', 'hs_office_partner', currentSubjectsUuids())) then - delete from hs_office_partner p where p.uuid = old.uuid; - return old; - end if; - raise exception '[403] Subject % is not allowed to delete partner uuid %', currentSubjectsUuids(), old.uuid; -end; $$; - -/* - Creates an instead of delete trigger for the hs_office_partner_rv view. - */ -create trigger deleteHsOfficePartner_Trigger - instead of delete - on hs_office_partner_rv - for each row -execute function deleteHsOfficePartner(); ---/ - - --- ============================================================================ ---changeset hs-office-partner-rbac-INSTEAD-OF-UPDATE-TRIGGER:1 endDelimiter:--// --- ---------------------------------------------------------------------------- - -/** - Instead of update trigger function for hs_office_partner_rv. - - Checks if the current subject (user / assumed role) has the permission to update the row. - */ -create or replace function updateHsOfficePartner() - returns trigger - language plpgsql as $$ -begin - if old.uuid in (select queryAccessibleObjectUuidsOfSubjectIds('edit', 'hs_office_partner', currentSubjectsUuids())) then - update hs_office_partner - set personUuid = new.personUuid, - contactUuid = new.contactUuid, - registrationOffice = new.registrationOffice, - registrationNumber = new.registrationNumber, - birthday = new.birthday, - birthName = new.birthName, - dateOfDeath = new.dateOfDeath - where uuid = old.uuid; - return old; - end if; - raise exception '[403] Subject % is not allowed to update partner uuid %', currentSubjectsUuids(), old.uuid; -end; $$; - -/* - Creates an instead of delete trigger for the hs_office_partner_rv view. - */ -create trigger updateHsOfficePartner_Trigger - instead of update - on hs_office_partner_rv - for each row -execute function updateHsOfficePartner(); ---/ - - -- ============================================================================ --changeset hs-office-partner-rbac-NEW-CONTACT:1 endDelimiter:--// -- ---------------------------------------------------------------------------- diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java index 92177242..f600dfe9 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerControllerAcceptanceTest.java @@ -422,11 +422,6 @@ class HsOfficePartnerControllerAcceptanceTest { } } - private UUID toCleanup(final UUID tempPartnerUuid) { - tempPartnerUuids.add(tempPartnerUuid); - return tempPartnerUuid; - } - private HsOfficePartnerEntity givenSomeTemporaryPartnerBessler() { return jpaAttempt.transacted(() -> { context.define("superuser-alex@hostsharing.net"); @@ -444,6 +439,11 @@ class HsOfficePartnerControllerAcceptanceTest { }).assertSuccessful().returnedValue(); } + private UUID toCleanup(final UUID tempPartnerUuid) { + tempPartnerUuids.add(tempPartnerUuid); + return tempPartnerUuid; + } + @AfterEach void cleanup() { tempPartnerUuids.forEach(uuid -> { diff --git a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java index b1d42ef2..ba63488a 100644 --- a/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/hs/office/partner/HsOfficePartnerRepositoryIntegrationTest.java @@ -243,7 +243,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { // then result.assertExceptionWithRootCauseMessage(JpaSystemException.class, - "[403] Subject ", " is not allowed to update partner uuid"); + "[403] Subject ", " is not allowed to update hs_office_partner uuid"); } @Test @@ -265,7 +265,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { // then result.assertExceptionWithRootCauseMessage(JpaSystemException.class, - "[403] Subject ", " is not allowed to update partner uuid"); + "[403] Subject ", " is not allowed to update hs_office_partner uuid"); } private void assertThatPartnerActuallyInDatabase(final HsOfficePartnerEntity saved) { @@ -333,7 +333,7 @@ class HsOfficePartnerRepositoryIntegrationTest extends ContextBasedTest { // then result.assertExceptionWithRootCauseMessage( JpaSystemException.class, - "[403] Subject ", " not allowed to delete partner"); + "[403] Subject ", " not allowed to delete hs_office_partner"); assertThat(jpaAttempt.transacted(() -> { context("superuser-alex@hostsharing.net"); return partnerRepo.findByUuid(givenPartner.getUuid()); diff --git a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java index 69c50e75..401046b8 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/test/cust/TestCustomerControllerAcceptanceTest.java @@ -4,6 +4,8 @@ import io.restassured.RestAssured; import io.restassured.http.ContentType; import net.hostsharing.hsadminng.HsadminNgApplication; import net.hostsharing.hsadminng.context.Context; +import net.hostsharing.test.JpaAttempt; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; @@ -11,6 +13,8 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.transaction.annotation.Transactional; +import java.util.HashSet; +import java.util.Set; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; @@ -19,7 +23,7 @@ import static org.hamcrest.Matchers.*; @SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, - classes = HsadminNgApplication.class + classes = { HsadminNgApplication.class, JpaAttempt.class } ) @Transactional class TestCustomerControllerAcceptanceTest { @@ -32,9 +36,15 @@ class TestCustomerControllerAcceptanceTest { @Autowired Context contextMock; + @Autowired TestCustomerRepository testCustomerRepository; + @Autowired + JpaAttempt jpaAttempt; + + Set tempPartnerUuids = new HashSet<>(); + @Nested class ListCustomers { @@ -46,7 +56,7 @@ class TestCustomerControllerAcceptanceTest { .port(port) .when() .get("http://localhost/api/test/customers") - .then().assertThat() + .then().log().all().assertThat() .statusCode(200) .contentType("application/json") .body("[0].prefix", is("xxx")) @@ -119,8 +129,8 @@ class TestCustomerControllerAcceptanceTest { .body(""" { "reference": 90020, - "prefix": "ttt", - "adminUserName": "customer-admin@ttt.example.com" + "prefix": "uuu", + "adminUserName": "customer-admin@uuu.example.com" } """) .port(port) @@ -129,22 +139,22 @@ class TestCustomerControllerAcceptanceTest { .then().assertThat() .statusCode(201) .contentType(ContentType.JSON) - .body("prefix", is("ttt")) + .body("prefix", is("uuu")) .header("Location", startsWith("http://localhost")) .extract().header("Location"); // @formatter:on // finally, the new customer can be viewed by its own admin - final var newUserUuid = UUID.fromString( - location.substring(location.lastIndexOf('/') + 1)); - context.define("customer-admin@ttt.example.com"); + final var newUserUuid = toCleanup(UUID.fromString( + location.substring(location.lastIndexOf('/') + 1))); + context.define("customer-admin@uuu.example.com"); assertThat(testCustomerRepository.findByUuid(newUserUuid)) - .hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("ttt")); + .hasValueSatisfying(c -> assertThat(c.getPrefix()).isEqualTo("uuu")); } @Test void globalAdmin_withoutAssumedRole_canAddCustomerWithGivenUuid() { - final var givenUuid = UUID.randomUUID(); + final var givenUuid = toCleanup(UUID.randomUUID()); final var location = RestAssured // @formatter:off .given() @@ -238,4 +248,22 @@ class TestCustomerControllerAcceptanceTest { assertThat(testCustomerRepository.findCustomerByOptionalPrefixLike("uuu")).hasSize(0); } } + + private UUID toCleanup(final UUID tempPartnerUuid) { + tempPartnerUuids.add(tempPartnerUuid); + return tempPartnerUuid; + } + + @AfterEach + void cleanup() { + tempPartnerUuids.forEach(uuid -> { + jpaAttempt.transacted(() -> { + context.define("superuser-alex@hostsharing.net", null); + System.out.println("DELETING temporary partner: " + uuid); + final var entity = testCustomerRepository.findByUuid(uuid); + final var count = testCustomerRepository.deleteByUuid(uuid); + System.out.println("DELETED temporary partner: " + uuid + (count > 0 ? " successful" : " failed") + " (" + entity.map(TestCustomerEntity::getPrefix).orElse("???") + ")"); + }).assertSuccessful(); + }); + } } diff --git a/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageControllerAcceptanceTest.java b/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageControllerAcceptanceTest.java index adbf3db9..e8cfc5bb 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageControllerAcceptanceTest.java +++ b/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageControllerAcceptanceTest.java @@ -86,7 +86,7 @@ class TestPackageControllerAcceptanceTest { void withDescriptionUpdatesDescription() { assumeThat(getDescriptionOfPackage("xxx00")) - .isEqualTo("Here can add your own description of package xxx00."); + .isEqualTo("Here you can add your own description of package xxx00."); final var randomDescription = RandomStringUtils.randomAlphanumeric(80); @@ -104,7 +104,7 @@ class TestPackageControllerAcceptanceTest { .port(port) .when() .patch("http://localhost/api/test/packages/{uuidOfPackage}", getUuidOfPackage("xxx00")) - .then() + .then().log().all() .assertThat() .statusCode(200) .contentType("application/json") @@ -118,7 +118,7 @@ class TestPackageControllerAcceptanceTest { void withNullDescriptionUpdatesDescriptionToNull() { assumeThat(getDescriptionOfPackage("xxx01")) - .isEqualTo("Here can add your own description of package xxx01."); + .isEqualTo("Here you can add your own description of package xxx01."); // @formatter:off RestAssured @@ -147,7 +147,7 @@ class TestPackageControllerAcceptanceTest { void withoutDescriptionDoesNothing() { assumeThat(getDescriptionOfPackage("xxx02")) - .isEqualTo("Here can add your own description of package xxx02."); + .isEqualTo("Here you can add your own description of package xxx02."); // @formatter:off RestAssured @@ -163,7 +163,7 @@ class TestPackageControllerAcceptanceTest { .statusCode(200) .contentType("application/json") .body("name", is("xxx02")) - .body("description", is("Here can add your own description of package xxx02.")); // unchanged + .body("description", is("Here you can add your own description of package xxx02.")); // unchanged // @formatter:on } } diff --git a/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageRepositoryIntegrationTest.java b/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageRepositoryIntegrationTest.java index fd7fda0e..99172d8d 100644 --- a/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageRepositoryIntegrationTest.java +++ b/src/test/java/net/hostsharing/hsadminng/test/pac/TestPackageRepositoryIntegrationTest.java @@ -98,22 +98,22 @@ class TestPackageRepositoryIntegrationTest { // when final var result1 = jpaAttempt.transacted(() -> { - globalAdminWithAssumedRole("test_package#xxx00.admin"); + globalAdminWithAssumedRole("test_package#xxx00.owner"); pac.setDescription("description set by thread 1"); testPackageRepository.save(pac); }); final var result2 = jpaAttempt.transacted(() -> { - globalAdminWithAssumedRole("test_package#xxx00.admin"); + globalAdminWithAssumedRole("test_package#xxx00.owner"); pac.setDescription("description set by thread 2"); testPackageRepository.save(pac); sleep(1500); }); // then - em.refresh(pac); - assertThat(pac.getDescription()).isEqualTo("description set by thread 1"); assertThat(result1.caughtException()).isNull(); assertThat(result2.caughtException()).isInstanceOf(ObjectOptimisticLockingFailureException.class); + em.refresh(pac); + assertThat(pac.getDescription()).isEqualTo("description set by thread 1"); } private void sleep(final int millis) {