implement query for relation mark
This commit is contained in:
parent
599e165d00
commit
5bd635a4cd
@ -17,6 +17,7 @@ import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.function.BiConsumer;
|
||||
|
||||
import static net.hostsharing.hsadminng.errors.Validate.validate;
|
||||
import static net.hostsharing.hsadminng.mapper.KeyValueMap.from;
|
||||
|
||||
@RestController
|
||||
@ -38,10 +39,14 @@ public class HsOfficeContactController implements HsOfficeContactsApi {
|
||||
public ResponseEntity<List<HsOfficeContactResource>> getListOfContacts(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String caption) {
|
||||
final String caption,
|
||||
final String emailAddress) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = contactRepo.findContactByOptionalCaptionLike(caption);
|
||||
validate("caption, emailAddress").atMaxOne(caption, emailAddress);
|
||||
final var entities = caption != null
|
||||
? contactRepo.findContactByOptionalCaptionLike(caption)
|
||||
: contactRepo.findContactByEmailAddress(emailAddress);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeContactResource.class);
|
||||
return ResponseEntity.ok(resources);
|
||||
|
@ -21,6 +21,17 @@ public interface HsOfficeContactRbacRepository extends Repository<HsOfficeContac
|
||||
@Timed("app.office.contacts.repo.findContactByOptionalCaptionLike.rbac")
|
||||
List<HsOfficeContactRbacEntity> findContactByOptionalCaptionLike(String caption);
|
||||
|
||||
@Query(value = """
|
||||
SELECT c.* FROM hs_office.contact_rv c
|
||||
WHERE jsonb_path_exists(c.emailaddresses, cast(:emailAddressExpression as jsonpath))
|
||||
""", nativeQuery = true)
|
||||
@Timed("app.office.contacts.repo.findContactByEmailAddressImpl.rbac")
|
||||
List<HsOfficeContactRbacEntity> findContactByEmailAddressImpl(final String emailAddressExpression);
|
||||
|
||||
default List<HsOfficeContactRbacEntity> findContactByEmailAddress(final String emailAddress) {
|
||||
return findContactByEmailAddressImpl("$.** ? (@ == \"" + emailAddress + "\")");
|
||||
}
|
||||
|
||||
@Timed("app.office.contacts.repo.save.rbac")
|
||||
HsOfficeContactRbacEntity save(final HsOfficeContactRbacEntity entity);
|
||||
|
||||
|
@ -35,10 +35,10 @@ public class HsOfficePersonController implements HsOfficePersonsApi {
|
||||
public ResponseEntity<List<HsOfficePersonResource>> getListOfPersons(
|
||||
final String currentSubject,
|
||||
final String assumedRoles,
|
||||
final String caption) {
|
||||
final String name) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final var entities = personRepo.findPersonByOptionalNameLike(caption);
|
||||
final var entities = personRepo.findPersonByOptionalNameLike(name);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficePersonResource.class);
|
||||
return ResponseEntity.ok(resources);
|
||||
|
@ -54,15 +54,16 @@ public class HsOfficeRelationController implements HsOfficeRelationsApi {
|
||||
final String assumedRoles,
|
||||
final UUID personUuid,
|
||||
final HsOfficeRelationTypeResource relationType,
|
||||
final String mark,
|
||||
final String personData,
|
||||
final String contactData) {
|
||||
context.define(currentSubject, assumedRoles);
|
||||
|
||||
final List<HsOfficeRelationRbacEntity> entities =
|
||||
rbacRelationRepo.findRelationRelatedToPersonUuidRelationTypePersonAndContactData(
|
||||
rbacRelationRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
|
||||
personUuid,
|
||||
relationType == null ? null : HsOfficeRelationType.valueOf(relationType.name()),
|
||||
personData, contactData);
|
||||
mark, personData, contactData);
|
||||
|
||||
final var resources = mapper.mapList(entities, HsOfficeRelationResource.class,
|
||||
RELATION_ENTITY_TO_RESOURCE_POSTMAPPER);
|
||||
|
@ -26,17 +26,20 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
||||
* *
|
||||
* @param personUuid the optional UUID of the anchorPerson or holderPerson
|
||||
* @param relationType the type of the relation
|
||||
* @param mark the mark (use '%' for wildcard), case ignored
|
||||
* @param personData a string to match the persons tradeName, familyName or givenName (use '%' for wildcard), case ignored
|
||||
* @param contactData a string to match the contacts caption, postalAddress, emailAddresses or phoneNumbers (use '%' for wildcard), case ignored
|
||||
* @return a list of (accessible) relations which match all given criteria
|
||||
*/
|
||||
default List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidRelationTypePersonAndContactData(
|
||||
default List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(
|
||||
final UUID personUuid,
|
||||
final HsOfficeRelationType relationType,
|
||||
final String mark,
|
||||
final String personData,
|
||||
final String contactData) {
|
||||
return findRelationRelatedToPersonUuidRelationTypePersonAndContactDataImpl(
|
||||
personUuid, toStringOrNull(relationType), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
|
||||
return findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
|
||||
personUuid, toStringOrNull(relationType),
|
||||
toSqlLikeOperand(mark), toSqlLikeOperand(personData), toSqlLikeOperand(contactData));
|
||||
}
|
||||
|
||||
@Query(value = """
|
||||
@ -44,6 +47,7 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
||||
WHERE (:relationType IS NULL OR CAST(rel.type AS String) = :relationType)
|
||||
AND ( :personUuid IS NULL
|
||||
OR rel.anchor.uuid = :personUuid OR rel.holder.uuid = :personUuid )
|
||||
AND ( :mark IS NULL OR lower(rel.mark) LIKE :mark )
|
||||
AND ( :personData IS NULL
|
||||
OR lower(rel.anchor.tradeName) LIKE :personData OR lower(rel.holder.tradeName) LIKE :personData
|
||||
OR lower(rel.anchor.familyName) LIKE :personData OR lower(rel.holder.familyName) LIKE :personData
|
||||
@ -54,10 +58,11 @@ public interface HsOfficeRelationRbacRepository extends Repository<HsOfficeRelat
|
||||
OR lower(CAST(rel.contact.emailAddresses AS String)) LIKE :contactData
|
||||
OR lower(CAST(rel.contact.phoneNumbers AS String)) LIKE :contactData )
|
||||
""")
|
||||
@Timed("app.office.relations.repo.findRelationRelatedToPersonUuidRelationTypePersonAndContactDataImpl.rbac")
|
||||
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidRelationTypePersonAndContactDataImpl(
|
||||
@Timed("app.office.relations.repo.findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl.rbac")
|
||||
List<HsOfficeRelationRbacEntity> findRelationRelatedToPersonUuidRelationByTypeMarkPersonAndContactDataImpl(
|
||||
final UUID personUuid,
|
||||
final String relationType,
|
||||
final String mark,
|
||||
final String personData,
|
||||
final String contactData);
|
||||
|
||||
|
@ -7,12 +7,18 @@ get:
|
||||
parameters:
|
||||
- $ref: 'auth.yaml#/components/parameters/currentSubject'
|
||||
- $ref: 'auth.yaml#/components/parameters/assumedRoles'
|
||||
- name: name
|
||||
- name: caption
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description: Prefix of caption to filter the results.
|
||||
description: Beginning of caption to filter the results.
|
||||
- name: emailAddress
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description: Beginning of email-address to filter the results.
|
||||
responses:
|
||||
"200":
|
||||
description: OK
|
||||
|
@ -22,6 +22,12 @@ get:
|
||||
schema:
|
||||
$ref: 'hs-office-relation-schemas.yaml#/components/schemas/HsOfficeRelationType'
|
||||
description: Prefix of name properties from holder or contact to filter the results.
|
||||
- name: mark
|
||||
in: query
|
||||
required: false
|
||||
schema:
|
||||
type: string
|
||||
description:
|
||||
- name: personData
|
||||
in: query
|
||||
required: false
|
||||
|
@ -127,7 +127,7 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FindAllContacts {
|
||||
class FindContacts {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllContacts() {
|
||||
@ -184,6 +184,22 @@ class HsOfficeContactRbacRepositoryIntegrationTest extends ContextBasedTestWithC
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class FindByEmailAddress {
|
||||
|
||||
@Test
|
||||
public void globalAdmin_withoutAssumedRole_canViewAllContacts() {
|
||||
// given
|
||||
context("superuser-alex@hostsharing.net", null);
|
||||
|
||||
// when
|
||||
final var result = contactRepo.findContactByEmailAddress("contact-admin@secondcontact.example.com");
|
||||
|
||||
// then
|
||||
exactlyTheseContactsAreReturned(result, "second contact");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class DeleteByUuid {
|
||||
|
||||
|
@ -193,7 +193,7 @@ class HsOfficeRelationRepositoryIntegrationTest extends ContextBasedTestWithClea
|
||||
.findFirst().orElseThrow();
|
||||
|
||||
// when:
|
||||
final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypePersonAndContactData(person.getUuid(), null, null, null);
|
||||
final var result = relationRbacRepo.findRelationRelatedToPersonUuidRelationTypeMarkPersonAndContactData(person.getUuid(), null, null, null, null);
|
||||
|
||||
// then:
|
||||
exactlyTheseRelationsAreReturned(
|
||||
|
@ -31,6 +31,7 @@ import net.hostsharing.hsadminng.hs.office.scenarios.partner.CreatePartner;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.partner.DeletePartner;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.person.ShouldUpdatePersonData;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.subscription.RemoveOperationsContactFromPartner;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.subscription.SubscribeExistingPersonAndContactToMailinglist;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.subscription.SubscribeNewPersonAndContactToMailinglist;
|
||||
import net.hostsharing.hsadminng.hs.office.scenarios.subscription.UnsubscribeFromMailinglist;
|
||||
import net.hostsharing.hsadminng.hs.scenarios.Produces;
|
||||
@ -578,7 +579,22 @@ class HsOfficeScenarioTests extends ScenarioTest {
|
||||
@Test
|
||||
@Order(5001)
|
||||
@Requires("Subscription: Michael Miller to operations-announce")
|
||||
void shouldUnsubscribeNewPersonAndContactToMailinglist() {
|
||||
@Produces("Subscription: Michael Miller to operations-discussion")
|
||||
void shouldSubscribeExistingPersonAndContactToMailinglist() {
|
||||
new SubscribeExistingPersonAndContactToMailinglist(scenarioTest)
|
||||
.given("partnerPersonTradeName", "Test AG")
|
||||
.given("subscriberFamilyName", "Miller")
|
||||
.given("subscriberGivenName", "Michael")
|
||||
.given("subscriberEMailAddress", "michael.miller@example.org")
|
||||
.given("mailingList", "operations-discussion")
|
||||
.doRun()
|
||||
.keep();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5002)
|
||||
@Requires("Subscription: Michael Miller to operations-announce")
|
||||
void shouldUnsubscribePersonAndContactFromMailinglist() {
|
||||
new UnsubscribeFromMailinglist(scenarioTest)
|
||||
.given("mailingList", "operations-announce")
|
||||
.given("subscriberEMailAddress", "michael.miller@example.org")
|
||||
|
@ -0,0 +1,54 @@
|
||||
package net.hostsharing.hsadminng.hs.office.scenarios.subscription;
|
||||
|
||||
import io.restassured.http.ContentType;
|
||||
import net.hostsharing.hsadminng.hs.scenarios.ScenarioTest;
|
||||
import net.hostsharing.hsadminng.hs.scenarios.UseCase;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import static io.restassured.http.ContentType.JSON;
|
||||
import static org.springframework.http.HttpStatus.CREATED;
|
||||
import static org.springframework.http.HttpStatus.OK;
|
||||
|
||||
public class SubscribeExistingPersonAndContactToMailinglist extends UseCase<SubscribeExistingPersonAndContactToMailinglist> {
|
||||
|
||||
public SubscribeExistingPersonAndContactToMailinglist(final ScenarioTest testSuite) {
|
||||
super(testSuite);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HttpResponse run() {
|
||||
|
||||
obtain("Person: %{partnerPersonTradeName}", () ->
|
||||
httpGet("/api/hs/office/persons?name=" + uriEncoded("%{partnerPersonTradeName}"))
|
||||
.expecting(OK).expecting(JSON),
|
||||
response -> response.expectArrayElements(1).getFromBody("[0].uuid"),
|
||||
"In production, data this query could result in multiple outputs. In that case, you have to find out which is the right one."
|
||||
);
|
||||
|
||||
obtain(
|
||||
"Person: %{subscriberGivenName} %{subscriberFamilyName}", () ->
|
||||
httpGet("/api/hs/office/persons?name=%{subscriberFamilyName}")
|
||||
.expecting(HttpStatus.OK).expecting(ContentType.JSON),
|
||||
response -> response.expectArrayElements(1).getFromBody("[0].uuid"),
|
||||
"In real scenarios there are most likely multiple results and you have to choose the right one."
|
||||
);
|
||||
|
||||
obtain("Contact: %{subscriberEMailAddress}", () ->
|
||||
httpGet("/api/hs/office/contacts?emailAddress=%{subscriberEMailAddress}")
|
||||
.expecting(HttpStatus.OK).expecting(ContentType.JSON),
|
||||
response -> response.expectArrayElements(1).getFromBody("[0].uuid"),
|
||||
"In real scenarios there are most likely multiple results and you have to choose the right one."
|
||||
);
|
||||
|
||||
return httpPost("/api/hs/office/relations", usingJsonBody("""
|
||||
{
|
||||
"type": "SUBSCRIBER",
|
||||
"mark": ${mailingList},
|
||||
"anchor.uuid": ${Person: %{partnerPersonTradeName}},
|
||||
"holder.uuid": ${Person: %{subscriberGivenName} %{subscriberFamilyName}},
|
||||
"contact.uuid": ${Contact: %{subscriberEMailAddress}}
|
||||
}
|
||||
"""))
|
||||
.expecting(CREATED).expecting(JSON);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user