protected Mono<ContentVo> extendPageContent(SinglePage singlePage,
        ContentWrapper wrapper) {
        Assert.notNull(singlePage, "SinglePage must not be null");
        Assert.notNull(wrapper, "SinglePage content must not be null");
        return extensionGetter.getEnabledExtensions(
                ReactiveSinglePageContentHandler.class)
            .reduce(Mono.fromSupplier(() -> SinglePageContentContext.builder()
                    .singlePage(singlePage)
                    .content(wrapper.getContent())
                    .raw(wrapper.getRaw())
                    .rawType(wrapper.getRawType())
                    .build()
                ),
                (contentMono, handler) -> contentMono.flatMap(handler::handle)
            )
            .flatMap(Function.identity())
            .map(pageContent -> ContentVo.builder()
                .content(pageContent.getContent())
                .raw(pageContent.getRaw())
                .build()
            );
    }
@Test
    void extendPageContent() {
        when(extensionGetter.getEnabledExtensions(
            eq(ReactiveSinglePageContentHandler.class)))
            .thenReturn(
                Flux.just(new PageContentHandlerB(),
                    new PageContentHandlerA(),
                    new PageContentHandlerC())
            );
        ContentWrapper contentWrapper = ContentWrapper.builder()
            .content("fake-content")
            .raw("fake-raw")
            .rawType("markdown")
            .build();
        SinglePage singlePage = new SinglePage();
        singlePage.setMetadata(new Metadata());
        singlePage.getMetadata().setName("fake-page");
        pageConversionService.extendPageContent(singlePage, contentWrapper)
            .as(StepVerifier::create)
            .consumeNextWith(contentVo -> {
                assertThat(contentVo.getContent()).isEqualTo("fake-content-B-A-C");
            })
            .verifyComplete();
    }