Skip to content

Commit

Permalink
Fixed link expand (#80)
Browse files Browse the repository at this point in the history
  • Loading branch information
p3t authored Dec 19, 2024
1 parent 7c3b9e4 commit 9be1624
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,10 @@ public <E> LinkBuilder next( final Page<E> page ) {

// actually the Link#expand method should do this, but there seems to be an issue,
// even when setting relaxed-query-chars: "[,],{,},|" in application.yml
private static Link expand( final Link link ) {
static Link expand( final Link link ) {
final var template = link.getHref();
if ( template.indexOf( "&" ) > 0 ) {
final var href = template.replaceAll( "&[^=]+=\\{[^}]+\\}", "" );
final var href = template.replaceAll( "&[^=]+=\\{[^}]+\\}|\\{&[^}]+\\}", "" );
return Link.of( href, link.getRel() )
.withName( link.getName() )
.withTitle( link.getTitle() )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,14 @@ public RequestSerializerBuilder<E> filterRuleFactory( final String name, final R
}
}

public static <E> Function<Consumer<RequestSerializerBuilder<E>>, RequestSerializer<E>> create(
final Class<E> entityClass ) {
public interface RequestSerializerCreator<E> extends
Function<Consumer<RequestSerializerBuilder<E>>, RequestSerializer<E>> {
default RequestSerializer<E> withDefaults() {
return apply( b -> {} );
}
}

public static <E> RequestSerializerCreator<E> create( final Class<E> entityClass ) {
return c -> RequestSerializer.create( entityClass, c );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@

import static java.util.Objects.requireNonNull;

/**
* The {@link RequestSerializerFactory} is a factory for creating {@link RequestSerializer}s for entities. It
* distributes the common parts, i.e. the encrypter and the conversion service, but also does a caching of the
* serializer in order to reuse them when they are requested more than once. Reuse is important as the serializer need
* to know the (java-) types of the properties/attributes when they <b>de</b>serialize a request. This mapping can be
* pre-configured (save in a cluster/multi-node setup) or they learn it when a request is serialized.
*/
@Builder
@RequiredArgsConstructor
public class RequestSerializerFactory {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,14 @@
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.hateoas.Link;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import static org.assertj.core.api.Assertions.assertThat;

@Slf4j
public class PageLinksTest {

Expand Down Expand Up @@ -59,10 +60,17 @@ void shouldGenerateLinksWithoutTemplate() {
log.info( "Self link: {}", selfLink.getHref() );
log.info( "next link: {}", nextLink.getHref() );

Assertions.assertThat( selfLink.getHref() ).contains( "?cursor=" );
Assertions.assertThat( nextLink.getHref() ).contains( "?cursor=" );
Assertions.assertThat( selfLink.getHref() ).doesNotContain( "pageSize", "names[]", "{", "}" );
Assertions.assertThat( nextLink.getHref() ).doesNotContain( "pageSize", "names[]", "{", "}" );
assertThat( selfLink.getHref() ).contains( "?cursor=" );
assertThat( nextLink.getHref() ).contains( "?cursor=" );
assertThat( selfLink.getHref() ).doesNotContain( "pageSize", "names[]", "{", "}" );
assertThat( nextLink.getHref() ).doesNotContain( "pageSize", "names[]", "{", "}" );
}

@Test
void shouldRemoveTemplateVariables() {
final var url = "/api/some/v1/what?cursor=RabarbarBarbar{&tag[],lastModifiedAt[gt],some[],}";
final Link result = PageLinks.expand( Link.of( url, "self" ) );
assertThat( result.getHref() ).doesNotContain( "&tag[]", "lastModifiedAt[gt]", ",", "{", "}" );
}

@Test
Expand All @@ -74,12 +82,12 @@ void shouldGenerateLinksWithoutTemplateButWithVariablesProvided() {
final Link nextLink = links.next( page )
.on( ( cursor, controller ) -> controller.getEntities( cursor, 15, null ) );

Assertions.assertThat( selfLink.getHref() ).contains( "?cursor=" );
Assertions.assertThat( nextLink.getHref() ).contains( "?cursor=" );
Assertions.assertThat( selfLink.getHref() ).contains( "pageSize=10" );
Assertions.assertThat( nextLink.getHref() ).contains( "pageSize=15" );
Assertions.assertThat( selfLink.getHref() ).doesNotContain( "names[]", "{", "}" );
Assertions.assertThat( nextLink.getHref() ).doesNotContain( "names[]", "{", "}" );
assertThat( selfLink.getHref() ).contains( "?cursor=" );
assertThat( nextLink.getHref() ).contains( "?cursor=" );
assertThat( selfLink.getHref() ).contains( "pageSize=10" );
assertThat( nextLink.getHref() ).contains( "pageSize=15" );
assertThat( selfLink.getHref() ).doesNotContain( "names[]", "{", "}" );
assertThat( nextLink.getHref() ).doesNotContain( "names[]", "{", "}" );
}

private static Page<TestEntity> createPage() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.vigier.cursorpaging.jpa.serializer;

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertNotNull;

class RequestSerializerFactoryTest {

static class TestEntity {

}

@Test
void testCreate() {
// Arrange
// Act
final RequestSerializerFactory result = RequestSerializerFactory.create( b -> {
b.serialalizer( RequestSerializer.create( TestEntity.class ).apply( r -> {} ) );
} );
// Assert
assertNotNull( result );
}

@Test
void testForEntity() {
// Arrange
final RequestSerializerFactory requestSerializerFactory = RequestSerializerFactory.builder()
.build();
// Act
final RequestSerializer<TestEntity> result = requestSerializerFactory.forEntity( TestEntity.class );
// Assert
assertNotNull( result );
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ void shouldSerializePageRequestsWithMultipleAttributes() {
void shouldSerializeReversedPageRequests() {
final var request = PageRequest.create( r -> r.position( Position.create(
p -> p.reversed( true ).order( Order.ASC ).attribute( Attribute.of( "some_name", String.class ) ) ) ) );
final RequestSerializer<Object> serializer = RequestSerializer.create( Object.class, b -> {} );
final RequestSerializer<Object> serializer = RequestSerializer.create( Object.class ).withDefaults();
final var serializedRequest = serializer.toBase64( request );
final var deserializedRequest = serializer.toPageRequest( serializedRequest );
assertThat( deserializedRequest.isReversed() ).isTrue();
Expand All @@ -220,7 +220,7 @@ void shouldSerializeReversedPageRequests() {
@Test
void shouldSerializeTotalCountIfPresent() {
final var request = createPageRequest().copy( b -> b.enableTotalCount( true ).totalCount( 42L ) );
final RequestSerializer<TestEntity> serializer = RequestSerializer.create( TestEntity.class, b -> {} );
final RequestSerializer<TestEntity> serializer = RequestSerializer.create( TestEntity.class ).withDefaults();
final var serializedRequest = serializer.toBase64( request );
final var deserializedRequest = serializer.toPageRequest( serializedRequest );
assertThat( deserializedRequest ).isEqualTo( request ).satisfies( r -> {
Expand All @@ -234,7 +234,7 @@ void shouldDeserializeAndFilter() {
final PageRequest<TestEntity> request = PageRequest.create( r -> r.filter(
Filters.and( attribute( TestEntity_.id ).equalTo( 123L ),
attribute( TestEntity_.name ).like( "%bumlux%" ) ) ).asc( TestEntity_.id ) );
final RequestSerializer<TestEntity> serializer = RequestSerializer.create( TestEntity.class, b -> {} );
final RequestSerializer<TestEntity> serializer = RequestSerializer.create( TestEntity.class ).withDefaults();
final var serializedRequest = serializer.toBytes( request );
final var deserializedRequest = serializer.toPageRequest( serializedRequest );

Expand Down

0 comments on commit 9be1624

Please sign in to comment.