Skip to content

Commit

Permalink
Feature/base url search criteria v1 (#42)
Browse files Browse the repository at this point in the history
* feat: added baseUrl as criteria to v1

* recommit

* removed comment

* fix: swapped expectation

* feat: added tx annotation

* feat: recursive menuItem deletion + improved constraint

* fix: renamed method and removed unused var
  • Loading branch information
JordenReuter authored Mar 19, 2024
1 parent a0b6173 commit 5afef42
Show file tree
Hide file tree
Showing 15 changed files with 105 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ public class WorkspaceSearchCriteria implements Serializable {

private String themeName;

private String baseUrl;

private Integer pageNumber = 0;

private Integer pageSize = 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,11 @@ public void deleteAllByWorkspaceId(String id) {
}

@Transactional
public void deleteAllByMenuId(String id) {
public void deleteAllByMenuId(List<Object> ids) {
try {
var cb = this.getEntityManager().getCriteriaBuilder();
var cq = this.deleteQuery();
var root = cq.from(Assignment.class);
cq.where(cb.equal(root.get(Assignment_.MENU_ITEM_ID), id));
cq.where(root.get(Assignment_.MENU_ITEM_ID).in(ids));
getEntityManager().createQuery(cq).executeUpdate();
} catch (Exception ex) {
throw new DAOException(ErrorKeys.ERROR_DELETE_ITEMS_BY_MENU_ID, ex);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package org.tkit.onecx.workspace.domain.daos;

import static org.tkit.onecx.workspace.domain.models.Workspace_.NAME;
import static org.tkit.onecx.workspace.domain.models.Workspace_.THEME;
import static org.tkit.onecx.workspace.domain.models.Workspace_.*;
import static org.tkit.quarkus.jpa.models.TraceableEntity_.ID;
import static org.tkit.quarkus.jpa.utils.QueryCriteriaUtil.addSearchStringPredicate;

Expand Down Expand Up @@ -88,6 +87,7 @@ public PageResult<Workspace> findBySearchCriteria(WorkspaceSearchCriteria criter

addSearchStringPredicate(predicates, cb, workspaceTable.get(NAME), criteria.getName());
addSearchStringPredicate(predicates, cb, workspaceTable.get(THEME), criteria.getThemeName());
addSearchStringPredicate(predicates, cb, workspaceTable.get(BASE_URL), criteria.getBaseUrl());
if (criteria.getNames() != null && !criteria.getNames().isEmpty()) {
predicates.add(workspaceTable.get(NAME).in(criteria.getNames()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
@Setter
@Entity
@Table(name = "ASSIGNMENT", uniqueConstraints = {
@UniqueConstraint(name = "ASSIGNMENT_KEY", columnNames = { "TENANT_ID", "ROLE_ID", "MENU_ITEM_ID" })
}, indexes = {
@Index(name = "ASSIGNMENT_TENANT_ID", columnList = "TENANT_ID")
@UniqueConstraint(name = "ASSIGNMENT_UNIQUE_ROLE_MENU_TENANT", columnNames = { "ROLE_ID", "MENU_ITEM_ID", "TENANT_ID" })
})
@SuppressWarnings("java:S2160")
public class Assignment extends TraceableEntity {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,24 @@ public record ImportRequest(String workspaceId, List<Role> roles, List<MenuItem>
}

@Transactional
public void deleteMenuItem(String menuItemId) {
assignmentDAO.deleteAllByMenuId(menuItemId);
dao.deleteQueryById(menuItemId);
public void deleteMenuItem(MenuItem menuItem) {
var childIds = children(menuItem);
if (menuItem != null) {
childIds.add(menuItem.getId());
}
assignmentDAO.deleteAllByMenuId(childIds);
dao.deleteQueryByIds(childIds);
}

private List<Object> children(MenuItem menuItem) {
List<Object> ids = new ArrayList<>();
if (menuItem != null) {
menuItem.getChildren().forEach(item -> {
ids.add(item.getId());
ids.addAll(children(item));
});
}
return ids;
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ public Response getWorkspaceByName(String name) {
}

@Override
@Transactional
public Response searchWorkspaces(WorkspaceSearchCriteriaDTOV1 workspaceSearchCriteriaDTOV1) {
var criteria = mapper.map(workspaceSearchCriteriaDTOV1);
var result = workspaceDAO.findBySearchCriteria(criteria);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@ public interface WorkspaceMapper {
@Mapping(target = "removeStreamItem", ignore = true)
WorkspacePageResultDTOV1 mapAbstractList(PageResult<Workspace> page);

default WorkspaceAbstractDTOV1 mapAbstract(Workspace workspace) {
WorkspaceAbstractDTOV1 abstractDTOV1 = new WorkspaceAbstractDTOV1();
abstractDTOV1.setName(workspace.getName());
abstractDTOV1.setTheme(workspace.getTheme());
abstractDTOV1.setDescription(workspace.getDescription());
abstractDTOV1.setProducts(workspace.getProducts().stream().map(Product::getProductName).toList());
return abstractDTOV1;
}

@Mapping(target = "name", ignore = true)
@Mapping(target = "names", ignore = true)
WorkspaceSearchCriteria map(WorkspaceSearchCriteriaDTOV1 criteria);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,15 @@ public Response createMenuItem(CreateMenuItemDTO menuItemDTO) {
}

@Override
@Transactional
public Response deleteAllMenuItemsForWorkspace(String id) {
menuService.deleteAllMenuItemsForWorkspace(id);
return Response.noContent().build();
}

@Override
@Transactional
public Response deleteMenuItemById(String menuItemId) {
menuService.deleteMenuItem(menuItemId);
var menuItem = dao.loadAllChildren(menuItemId);
menuService.deleteMenuItem(menuItem);
return Response.noContent().build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public interface WorkspaceMapper {
@Mapping(target = "modificationCount", source = "modificationCount")
void update(UpdateWorkspaceRequestDTO dto, @MappingTarget Workspace workspace);

@Mapping(target = "baseUrl", ignore = true)
@Mapping(target = "names", ignore = true)
WorkspaceSearchCriteria map(WorkspaceSearchCriteriaDTO dto);

Expand Down
8 changes: 8 additions & 0 deletions src/main/openapi/onecx-workspace-v1-openapi.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,12 @@ components:
properties:
name:
type: string
theme:
type: string
products:
type: array
items:
type: string
description:
type: string
WorkspaceSearchCriteria:
Expand All @@ -166,6 +172,8 @@ components:
type: string
productName:
type: string
baseUrl:
type: string
pageNumber:
format: int32
description: The number of page.
Expand Down
2 changes: 1 addition & 1 deletion src/main/resources/db/changeLog.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
<include relativeToChangelogFile="true" file="v1/2023-11-09-create-tables.xml"/>
<include relativeToChangelogFile="true" file="v1/2023-11-09-data-import-log.xml"/>
<include relativeToChangelogFile="true" file="v1/2024-02-22-create-table-image.xml"/>

<include relativeToChangelogFile="true" file="v1/2024-03-19-update-assignment-constraints.xml"/>
</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.1" encoding="UTF-8" standalone="no"?>

<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd"
objectQuotingStrategy="QUOTE_ONLY_RESERVED_WORDS">

<changeSet author="dev (generated)" id="1710844180936-1">
<addUniqueConstraint columnNames="role_id, menu_item_id, tenant_id" constraintName="assignment_unique_role_menu_tenant" tableName="assignment"/>
<dropUniqueConstraint constraintName="assignment_key" tableName="assignment"/>
<dropIndex indexName="assignment_tenant_id" tableName="assignment"/>
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,23 @@ void searchWorkspacesByCriteria(WorkspaceSearchCriteriaDTOV1 criteriaDTOV1, int
assertThat(dto.getStream()).hasSize(results);
}

@Test
void searchWorkspacesByBasePathCriteria() {
WorkspaceSearchCriteriaDTOV1 criteriaDTOV1 = new WorkspaceSearchCriteriaDTOV1();
criteriaDTOV1.setBaseUrl("/company1");
var dto = given()
.when()
.contentType(APPLICATION_JSON)
.body(criteriaDTOV1)
.post("/search")
.then()
.statusCode(OK.getStatusCode())
.extract().as(WorkspacePageResultDTOV1.class);

assertThat(dto).isNotNull();
assertThat(dto.getStream().get(0).getName()).isEqualTo("test01");
}

@Test
void getWorkspaceByNameTest() {
var dto = given()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ void createAssignment() {

assertThat(exception.getErrorCode()).isEqualTo("PERSIST_ENTITY_FAILED");
assertThat(exception.getDetail()).isEqualTo(
"could not execute statement [ERROR: duplicate key value violates unique constraint 'assignment_key' Detail: Key (tenant_id, role_id, menu_item_id)=(tenant-100, r13, 33-6) already exists.]");
"could not execute statement [ERROR: duplicate key value violates unique constraint 'assignment_unique_role_menu_tenant' Detail: Key (role_id, menu_item_id, tenant_id)=(r13, 33-6, tenant-100) already exists.]");

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,32 @@ void deleteMenuItemByIdTest() {
assertThat(dto.getStream()).isNotNull().isNotEmpty().hasSize(12);
}

@Test
void deleteMenuItemByIdWhenChildrenExistTest() {
given()
.when()
.contentType(APPLICATION_JSON)
.pathParam("menuItemId", "33-1")
.delete("{menuItemId}")
.then()
.statusCode(NO_CONTENT.getStatusCode());

var criteria = new MenuItemSearchCriteriaDTO()
.workspaceId("11-111");

var dto = given()
.when()
.contentType(APPLICATION_JSON)
.body(criteria)
.post("search")
.then()
.statusCode(OK.getStatusCode())
.extract().as(MenuItemPageResultDTO.class);

assertThat(dto).isNotNull();
assertThat(dto.getStream()).isNotNull().isNotEmpty().hasSize(7);
}

@Test
void deleteAllMenuItemsForWorkspaceTest() {
given()
Expand Down

0 comments on commit 5afef42

Please sign in to comment.