Skip to content

Commit

Permalink
feat(service): add page reorder during update
Browse files Browse the repository at this point in the history
  • Loading branch information
jourdiw committed Nov 6, 2023
1 parent 9df74bc commit 48f472d
Show file tree
Hide file tree
Showing 3 changed files with 229 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.gravitee.apim.core.documentation.domain_service.HomepageDomainService;
import io.gravitee.apim.core.documentation.domain_service.UpdateApiDocumentationDomainService;
import io.gravitee.apim.core.documentation.model.Page;
import io.gravitee.apim.core.documentation.query_service.PageQueryService;
import java.util.Date;
import java.util.Objects;
import lombok.Builder;
Expand All @@ -33,19 +34,22 @@ public class ApiUpdateDocumentationPageUsecase {
private final HomepageDomainService homepageDomainService;
private final ApiCrudService apiCrudService;
private final PageCrudService pageCrudService;
private final PageQueryService pageQueryService;

public ApiUpdateDocumentationPageUsecase(
UpdateApiDocumentationDomainService updateApiDocumentationDomainService,
ApiDocumentationDomainService apiDocumentationDomainService,
HomepageDomainService homepageDomainService,
ApiCrudService apiCrudService,
PageCrudService pageCrudService
PageCrudService pageCrudService,
PageQueryService pageQueryService
) {
this.updateApiDocumentationDomainService = updateApiDocumentationDomainService;
this.apiDocumentationDomainService = apiDocumentationDomainService;
this.homepageDomainService = homepageDomainService;
this.apiCrudService = apiCrudService;
this.pageCrudService = pageCrudService;
this.pageQueryService = pageQueryService;
}

public Output execute(Input input) {
Expand All @@ -69,7 +73,6 @@ public Output execute(Input input) {
newPage.updatedAt(new Date());
newPage.visibility(input.visibility);
newPage.homepage(input.homepage);
// TODO: Implement order logic -- APIM-3077
newPage.order(input.order);

var updatedPage = this.updateApiDocumentationDomainService.updatePage(newPage.build(), oldPage, input.auditInfo);
Expand All @@ -78,6 +81,10 @@ public Output execute(Input input) {
this.homepageDomainService.setPreviousHomepageToFalse(input.apiId, updatedPage.getId());
}

if (updatedPage.getOrder() != oldPage.getOrder()) {
this.updatePageOrders(oldPage.getOrder(), updatedPage, input.auditInfo);
}

return new Output(updatedPage);
}

Expand All @@ -94,4 +101,31 @@ public record Input(
) {}

public record Output(Page page) {}

private void updatePageOrders(int oldOrder, Page updatedPage, AuditInfo auditInfo) {
var newOrder = updatedPage.getOrder();
var shouldMoveDown = newOrder < oldOrder;
var orderIncrement = shouldMoveDown ? 1 : -1;

this.pageQueryService.searchByApiIdAndParentId(updatedPage.getReferenceId(), updatedPage.getParentId())
.stream()
.filter(page -> !Objects.equals(page.getId(), updatedPage.getId()))
.filter(page ->
shouldMoveDown
? this.toBeMovedDown(oldOrder, newOrder, page.getOrder())
: this.toBeMovedUp(oldOrder, newOrder, page.getOrder())
)
.forEach(page -> {
var updatedOrder = page.getOrder() + orderIncrement;
this.updateApiDocumentationDomainService.updatePage(page.toBuilder().order(updatedOrder).build(), page, auditInfo);
});
}

private boolean toBeMovedUp(int oldOrder, int newOrder, int pageOrder) {
return oldOrder < pageOrder && pageOrder <= newOrder;
}

private boolean toBeMovedDown(int oldOrder, int newOrder, int pageOrder) {
return newOrder <= pageOrder && pageOrder < oldOrder;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,16 @@ public ApiUpdateDocumentationPageUsecase apiUpdateDocumentationPageUsecase(
ApiDocumentationDomainService apiDocumentationDomainService,
HomepageDomainService homepageDomainService,
ApiCrudService apiCrudService,
PageCrudService pageCrudService
PageCrudService pageCrudService,
PageQueryService pageQueryService
) {
return new ApiUpdateDocumentationPageUsecase(
updateApiDocumentationDomainService,
apiDocumentationDomainService,
homepageDomainService,
apiCrudService,
pageCrudService
pageCrudService,
pageQueryService
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,8 @@ void setUp() {
new ApiDocumentationDomainService(pageQueryService, new HtmlSanitizerImpl()),
new HomepageDomainService(pageQueryService, pageCrudService),
apiCrudService,
pageCrudService
pageCrudService,
pageQueryService
);
}

Expand Down Expand Up @@ -490,6 +491,193 @@ void should_throw_error_if_duplicate_name() {
}
}

@Nested
class UpdateOrderTests {

Page page_0 = Page
.builder()
.id("page_0")
.name("0")
.type(Page.Type.MARKDOWN)
.referenceType(Page.ReferenceType.API)
.referenceId(API_ID)
.parentId(OLD_FOLDER_PAGE.getId())
.updatedAt(DATE)
.order(0)
.build();
Page page_1 = Page
.builder()
.id("page_1")
.name("1")
.type(Page.Type.MARKDOWN)
.referenceType(Page.ReferenceType.API)
.referenceId(API_ID)
.parentId(OLD_FOLDER_PAGE.getId())
.updatedAt(DATE)
.order(1)
.build();
Page page_2 = Page
.builder()
.id("page_2")
.name("2")
.type(Page.Type.FOLDER)
.referenceType(Page.ReferenceType.API)
.referenceId(API_ID)
.parentId(OLD_FOLDER_PAGE.getId())
.updatedAt(DATE)
.order(2)
.build();
Page page_3 = Page
.builder()
.id("page_3")
.name("3")
.type(Page.Type.MARKDOWN)
.referenceType(Page.ReferenceType.API)
.referenceId(API_ID)
.parentId(OLD_FOLDER_PAGE.getId())
.updatedAt(DATE)
.order(3)
.build();
Page page_4 = Page
.builder()
.id("page_4")
.name("4")
.type(Page.Type.MARKDOWN)
.referenceType(Page.ReferenceType.API)
.referenceId(API_ID)
.parentId(OLD_FOLDER_PAGE.getId())
.updatedAt(DATE)
.order(4)
.build();

@BeforeEach
void setup() {
initApiServices(List.of(Api.builder().id(API_ID).build()));
initPageServices(List.of(OLD_FOLDER_PAGE, page_0, page_1, page_2, page_3, page_4));
}

@Test
void should_insert_new_page_with_lower_order() {
// Change page_3 order to 1
var res = apiUpdateDocumentationPageUsecase.execute(
ApiUpdateDocumentationPageUsecase.Input
.builder()
.apiId(API_ID)
.pageId(page_3.getId())
.order(1)
.visibility(page_3.getVisibility())
.content(page_3.getContent())
.name(page_3.getName())
.homepage(false)
.auditInfo(AUDIT_INFO)
.build()
);

assertThat(res.page()).isNotNull().hasFieldOrPropertyWithValue("order", 1);
assertThat(pageCrudService.get(page_0.getId()).getOrder()).isEqualTo(0);
assertThat(pageCrudService.get(page_1.getId()).getOrder()).isEqualTo(2);
assertThat(pageCrudService.get(page_2.getId()).getOrder()).isEqualTo(3);
assertThat(pageCrudService.get(page_4.getId()).getOrder()).isEqualTo(4);
}

@Test
void should_insert_new_page_with_higher_order() {
// Change page_1 order to 3
var res = apiUpdateDocumentationPageUsecase.execute(
ApiUpdateDocumentationPageUsecase.Input
.builder()
.apiId(API_ID)
.pageId(page_1.getId())
.order(3)
.visibility(page_1.getVisibility())
.content(page_1.getContent())
.name(page_1.getName())
.homepage(false)
.auditInfo(AUDIT_INFO)
.build()
);

assertThat(res.page()).isNotNull().hasFieldOrPropertyWithValue("order", 3);
assertThat(pageCrudService.get(page_0.getId()).getOrder()).isEqualTo(0);
assertThat(pageCrudService.get(page_2.getId()).getOrder()).isEqualTo(1);
assertThat(pageCrudService.get(page_3.getId()).getOrder()).isEqualTo(2);
assertThat(pageCrudService.get(page_4.getId()).getOrder()).isEqualTo(4);
}

@Test
void should_not_change_order_if_the_same() {
var res = apiUpdateDocumentationPageUsecase.execute(
ApiUpdateDocumentationPageUsecase.Input
.builder()
.apiId(API_ID)
.pageId(page_1.getId())
.order(1)
.visibility(page_1.getVisibility())
.content(page_1.getContent())
.name(page_1.getName())
.homepage(false)
.auditInfo(AUDIT_INFO)
.build()
);

assertThat(res.page()).isNotNull().hasFieldOrPropertyWithValue("order", 1);
assertThat(pageCrudService.get(page_0.getId()).getOrder()).isEqualTo(0);
assertThat(pageCrudService.get(page_2.getId()).getOrder()).isEqualTo(2);
assertThat(pageCrudService.get(page_3.getId()).getOrder()).isEqualTo(3);
assertThat(pageCrudService.get(page_4.getId()).getOrder()).isEqualTo(4);
}

@Test
void should_update_with_very_high_order() {
// Change page_1 order to 9999
var res = apiUpdateDocumentationPageUsecase.execute(
ApiUpdateDocumentationPageUsecase.Input
.builder()
.apiId(API_ID)
.pageId(page_1.getId())
.order(9999)
.visibility(page_1.getVisibility())
.content(page_1.getContent())
.name(page_1.getName())
.homepage(false)
.auditInfo(AUDIT_INFO)
.build()
);

assertThat(res.page()).isNotNull().hasFieldOrPropertyWithValue("order", 9999);
assertThat(pageCrudService.get(page_0.getId()).getOrder()).isEqualTo(0);
assertThat(pageCrudService.get(page_2.getId()).getOrder()).isEqualTo(1);
assertThat(pageCrudService.get(page_3.getId()).getOrder()).isEqualTo(2);
assertThat(pageCrudService.get(page_4.getId()).getOrder()).isEqualTo(3);
}

@Test
void should_only_change_order_of_pages_with_same_parent() {
var pageWithDifferentParent = page_0.toBuilder().id("other-page").parentId(null).build();
initPageServices(List.of(page_0, page_1, page_2, page_3, page_4, pageWithDifferentParent));
var res = apiUpdateDocumentationPageUsecase.execute(
ApiUpdateDocumentationPageUsecase.Input
.builder()
.apiId(API_ID)
.pageId(pageWithDifferentParent.getId())
.order(1)
.visibility(pageWithDifferentParent.getVisibility())
.content(pageWithDifferentParent.getContent())
.name(pageWithDifferentParent.getName())
.homepage(false)
.auditInfo(AUDIT_INFO)
.build()
);

assertThat(res.page()).isNotNull().hasFieldOrPropertyWithValue("order", 1);
assertThat(pageCrudService.get(page_0.getId()).getOrder()).isEqualTo(0);
assertThat(pageCrudService.get(page_1.getId()).getOrder()).isEqualTo(1);
assertThat(pageCrudService.get(page_2.getId()).getOrder()).isEqualTo(2);
assertThat(pageCrudService.get(page_3.getId()).getOrder()).isEqualTo(3);
assertThat(pageCrudService.get(page_4.getId()).getOrder()).isEqualTo(4);
}
}

private void initPageServices(List<Page> pages) {
pageQueryService.initWith(pages);
pageCrudService.initWith(pages);
Expand Down

0 comments on commit 48f472d

Please sign in to comment.