package io.katharsis.resource;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import io.katharsis.resource.annotations.JsonApiId;
import io.katharsis.resource.annotations.JsonApiLinksInformation;
import io.katharsis.resource.annotations.JsonApiMetaInformation;
import io.katharsis.resource.annotations.JsonApiResource;
import io.katharsis.resource.annotations.JsonApiToOne;
import io.katharsis.resource.exception.init.MultipleJsonApiLinksInformationException;
import io.katharsis.resource.exception.init.MultipleJsonApiMetaInformationException;
import io.katharsis.resource.exception.init.ResourceDuplicateIdException;
import io.katharsis.resource.exception.init.ResourceIdNotFoundException;
import io.katharsis.resource.field.ResourceFieldNameTransformer;
import io.katharsis.resource.information.ResourceInformation;
import io.katharsis.resource.information.ResourceInformationBuilder;
import io.katharsis.resource.mock.models.Task;
import io.katharsis.resource.mock.models.UnAnnotatedTask;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
public class ResourceInformationBuilderTest {
private static final String NAME_PROPERTY = "underlyingName";
@Rule
public ExpectedException expectedException = ExpectedException.none();
private final ResourceInformationBuilder resourceInformationBuilder = new ResourceInformationBuilder(
new ResourceFieldNameTransformer());
@Test
public void shouldHaveResourceClassInfoForValidResource() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(Task.class);
assertThat(resourceInformation.getResourceClass())
.isNotNull()
.isEqualTo(Task.class);
}
@Test
public void shouldHaveIdFieldInfoForValidResource() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(Task.class);
assertThat(resourceInformation.getIdField().getUnderlyingName())
.isNotNull()
.isEqualTo("id");
}
@Test
public void shouldThrowExceptionWhenResourceWithNoIdAnnotation() {
expectedException.expect(ResourceIdNotFoundException.class);
resourceInformationBuilder.build(UnAnnotatedTask.class);
}
@Test
public void shouldThrowExceptionWhenMoreThan1IdAnnotationFound() throws Exception {
expectedException.expect(ResourceDuplicateIdException.class);
expectedException.expectMessage("Duplicated Id field found in class");
resourceInformationBuilder.build(DuplicatedIdResource.class);
}
@Test
public void shouldHaveProperRelationshipFieldInfoForValidResource() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(Task.class);
assertThat(resourceInformation.getRelationshipFields())
.isNotNull()
.hasSize(4)
.extracting(NAME_PROPERTY)
.contains("project", "projects");
}
@Test
public void shouldThrowExceptionWhenResourceWithIgnoredIdAnnotation() {
expectedException.expect(ResourceIdNotFoundException.class);
resourceInformationBuilder.build(IgnoredIdResource.class);
}
@Test
public void shouldReturnIdFieldBasedOnFieldGetter() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(IdFieldWithAccessorGetterResource.class);
assertThat(resourceInformation.getIdField())
.isNotNull();
}
@Test
public void shouldReturnMergedAnnotationsOnAnnotationsOnFieldAndMethod() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(AnnotationOnFieldAndMethodResource.class);
assertThat(resourceInformation.getRelationshipFields())
.isNotNull()
.hasSize(0);
}
@Test
public void shouldContainMetaInformationField() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(Task.class);
assertThat(resourceInformation.getMetaFieldName())
.isEqualTo("metaInformation");
}
@Test
public void shouldThrowExceptionOnMultipleMetaInformationFields() throws Exception {
ResourceInformation resourceInformation = resourceInformationBuilder.build(Task.class);
assertThat(resourceInformation.getMetaFieldName())
.isEqualTo("metaInformation");
}
@Test
public void shouldContainLinksInformationField() throws Exception {
expectedException.expect(MultipleJsonApiMetaInformationException.class);
resourceInformationBuilder.build(MultipleMetaInformationResource.class);
}
@Test
public void shouldThrowExceptionOnMultipleLinksInformationFields() throws Exception {
expectedException.expect(MultipleJsonApiLinksInformationException.class);
resourceInformationBuilder.build(MultipleLinksInformationResource.class);
}
@JsonApiResource(type = "duplicatedIdAnnotationResources")
private static class DuplicatedIdResource {
@JsonApiId
private Long id;
@JsonApiId
private Long id2;
}
@JsonApiResource(type = "ignoredId")
private static class IgnoredIdResource {
@JsonApiId
@JsonIgnore
private Long id;
}
@JsonApiResource(type = "ignoredAttribute")
private static class IgnoredAttributeResource {
@JsonApiId
private Long id;
@JsonIgnore
private String attribute;
}
@JsonApiResource(type = "accessorGetter")
private static class AccessorGetterResource {
@JsonApiId
private Long id;
private String getAccessorField() {
return null;
}
}
@JsonApiResource(type = "ignoredAccessorGetter")
private static class IgnoredAccessorGetterResource {
@JsonApiId
private Long id;
@JsonIgnore
private String getAccessorField() {
return null;
}
}
@JsonApiResource(type = "fieldWithAccessorGetterResource")
private static class FieldWithAccessorGetterResource {
@JsonApiId
private Long id;
public String getAccessorField() {
return accessorField;
}
private String accessorField;
}
@JsonApiResource(type = "idFieldWithAccessorGetterResource")
private static class IdFieldWithAccessorGetterResource {
@JsonApiId
public Long getId() {
return null;
}
}
@JsonApiResource(type = "annotationOnFieldAndMethod")
private static class AnnotationOnFieldAndMethodResource {
@JsonApiId
private Long id;
@JsonIgnore
private String field;
@JsonApiToOne
private String getField() {
return null;
}
}
@JsonApiResource(type = "ignoredAttribute")
private static class IgnoredStaticAttributeResource {
@JsonApiId
private Long id;
public static String attribute;
}
@JsonApiResource(type = "ignoredAttribute")
private static class IgnoredTransientAttributeResource {
@JsonApiId
private Long id;
public transient int attribute;
public int getAttribute() {
return attribute;
}
}
@JsonApiResource(type = "ignoredAttribute")
private static class IgnoredStaticGetterResource {
@JsonApiId
private Long id;
public static int getAttribute() {
return 0;
}
}
@JsonPropertyOrder({"b", "a", "c"})
@JsonApiResource(type = "orderedResource")
private static class OrderedResource {
@JsonApiId
private Long id;
public String c;
public String b;
public String a;
}
@JsonPropertyOrder(alphabetic = true)
@JsonApiResource(type = "AlphabeticResource")
private static class AlphabeticResource {
@JsonApiId
private Long id;
public String c;
public String b;
public String a;
}
@JsonApiResource(type = "multipleMetaInformationResource")
private static class MultipleMetaInformationResource {
@JsonApiId
private Long id;
@JsonApiMetaInformation
public String c;
@JsonApiMetaInformation
public String b;
}
@JsonApiResource(type = "multipleLinksInformationResource")
private static class MultipleLinksInformationResource {
@JsonApiId
private Long id;
@JsonApiLinksInformation
public String c;
@JsonApiLinksInformation
public String b;
}
}