Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

T2D-319 spring rest docs #16

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@
<artifactId>springfox-bean-validators</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

<build>
Expand Down Expand Up @@ -136,6 +142,26 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<executions>
<execution>
<id>generate-docs</id>
<phase>prepare-package</phase>
<goals>
<goal>process-asciidoc</goal>
</goals>
<configuration>
<sourceDocumentName>index.adoc</sourceDocumentName>
<backend>html</backend>
<attributes>
<snippets>${project.build.directory}/generated-snippets/</snippets>
</attributes>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

Expand Down
170 changes: 170 additions & 0 deletions src/main/asciidoc/index.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
= Getting Started With Spring REST Docs

This is an example output for the registry service

:snippets: ../../../target/generated-snippets

=== Create Entity using POST Requests

==== Phenotype

.requestFields

include::{snippets}/should-create-phenotype/1/request-fields.adoc[]

.request

include::{snippets}/should-create-phenotype/1/http-request.adoc[]

.response

include::{snippets}/should-create-phenotype/1/http-response.adoc[]


==== Property

.requestFields

include::{snippets}/should-create-property/1/request-fields.adoc[]

.request

include::{snippets}/should-create-property/1/http-request.adoc[]

.response

include::{snippets}/should-create-property/1/http-response.adoc[]


== Query Entity using GET Requests

==== Phenotype
.request

include::{snippets}/should-query-phenotype/1/http-request.adoc[]

.response

include::{snippets}/should-query-phenotype/1/http-response.adoc[]

==== Property
.request

include::{snippets}/should-query-properties/1/http-request.adoc[]

.response

include::{snippets}/should-query-properties/1/http-response.adoc[]

== Update Entity using PATCH/PUT Requests

==== Phenotype
.request

include::{snippets}/should-update-phenotype/2/http-request.adoc[]

.response

include::{snippets}/should-update-phenotype/2/http-response.adoc[]

==== Property
.request

include::{snippets}/should-update-property/2/http-request.adoc[]

.response
include::{snippets}/should-update-property/2/http-response.adoc[]

== Partial update Entity using PATCH/PUT Requests

==== Phenotype
.request

include::{snippets}/should-partially-update-phenotype/2/http-request.adoc[]

.response

include::{snippets}/should-partially-update-phenotype/2/http-response.adoc[]

==== Property
.request

include::{snippets}/should-partially-update-property/2/http-request.adoc[]

.response
include::{snippets}/should-partially-update-property/2/http-response.adoc[]

== Delete Entity using DELETE Requests

==== Phenotype
.request

include::{snippets}/should-delete-phenotype/2/http-request.adoc[]

.response

include::{snippets}/should-delete-phenotype/2/http-response.adoc[]

==== Property
.request

include::{snippets}/should-delete-property/2/http-request.adoc[]

.response
include::{snippets}/should-delete-property/2/http-response.adoc[]

== Test Authorization

==== Accessing secured endpoints without authentication
.request

include::{snippets}/test-authorization/1/http-request.adoc[]

.response

include::{snippets}/test-authorization/1/http-response.adoc[]

==== Accessing secured endpoints with authentication token
===== User with ROLE_READ
.request

include::{snippets}/test-authorization/11/http-request.adoc[]

.response

include::{snippets}/test-authorization/11/http-response.adoc[]

.request

include::{snippets}/test-authorization/14/http-request.adoc[]

.response

include::{snippets}/test-authorization/14/http-response.adoc[]

===== User with ROLE_EDITOR

.request

include::{snippets}/test-authorization/15/http-request.adoc[]

.response

include::{snippets}/test-authorization/15/http-response.adoc[]

.request

include::{snippets}/test-authorization/19/http-request.adoc[]

.response

include::{snippets}/test-authorization/19/http-response.adoc[]

===== User with ROLE_ADMIN
.request

include::{snippets}/test-authorization/20/http-request.adoc[]

.response

include::{snippets}/test-authorization/20/http-response.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,39 @@
package uk.ac.ebi.ampt2d.registry;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.json.JacksonTester;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.restdocs.JUnitRestDocumentation;
import org.springframework.security.web.FilterChainProxy;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import uk.ac.ebi.ampt2d.registry.entities.Phenotype;
import uk.ac.ebi.ampt2d.registry.entities.Property;
import uk.ac.ebi.ampt2d.registry.repositories.PhenotypeRepository;
import uk.ac.ebi.ampt2d.registry.repositories.PropertyRepository;
import uk.ac.ebi.ampt2d.registry.service.mail.MailService;

import javax.annotation.Resource;

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessRequest;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.prettyPrint;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.test.annotation.DirtiesContext.ClassMode.AFTER_CLASS;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand All @@ -49,12 +62,13 @@

@RunWith(SpringRunner.class)
@SpringBootTest(properties = {"security.enabled=true", "spring.jpa.hibernate.ddl-auto=none"})
@AutoConfigureMockMvc
@AutoConfigureJsonTesters
@DirtiesContext(classMode = AFTER_CLASS)
public class PropertyRegistryServiceApplicationTests {

@Autowired
@Rule
public JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation("target/generated-snippets");

private MockMvc mockMvc;

@Autowired
Expand All @@ -75,11 +89,24 @@ public class PropertyRegistryServiceApplicationTests {
@MockBean
private MailService mailService;

@Autowired
private WebApplicationContext webApplicationContext;

@Resource
private FilterChainProxy springSecurityFilterChain;

@Before
public void setUp() throws Exception {
doNothing().when(mailService).send(anyString());
phenotypeRepository.deleteAll();
propertyRepository.deleteAll();
mockMvc = MockMvcBuilders.webAppContextSetup(this.webApplicationContext).apply
(documentationConfiguration(restDocumentation))
.alwaysDo(document("{method-name}/{step}"
, preprocessRequest(prettyPrint())
, preprocessResponse(prettyPrint())))
.addFilters(springSecurityFilterChain)
.build();
}

@Test
Expand All @@ -90,10 +117,32 @@ public void shouldReturnRepositoryIndex() throws Exception {
jsonPath("$._links.phenotypes").exists());
}

private String postTestEntity(String uri, String content) throws Exception {
private String postTestPhenotypeEntity(String uri, String content) throws Exception {
MvcResult mvcResult = mockMvc.perform(post(uri).with(oAuthHelper.bearerToken("[email protected]")).content
(content))
.andExpect(status().isCreated())
.andDo(document("{method-name}/{step}", requestFields(
fieldWithPath("id").description("Unique identifier of a Phenotype"),
fieldWithPath("description").description("Description of a Phenotype"),
fieldWithPath("type").description("CONTINUOUS/DICHOTOMOUS/TRICHOTOMOUS"),
fieldWithPath("phenotypeGroup").description("Example values: ANTHROPOMETRIC,RENAL.."),
fieldWithPath("allowedValues").description("Format of values eg : nn.nn / 0 or 1")
)))
.andReturn();

return mvcResult.getResponse().getHeader("Location");
}

private String postTestPropertyEntity(String uri, String content) throws Exception {
MvcResult mvcResult = mockMvc.perform(post(uri).with(oAuthHelper.bearerToken("[email protected]")).content
(content))
.andExpect(status().isCreated())
.andDo(document("{method-name}/{step}", requestFields(
fieldWithPath("id").description("Unique identifier of a Property"),
fieldWithPath("description").description("Description of a Property"),
fieldWithPath("type").description("Example values: DOUBLE,INTEGER.."),
fieldWithPath("meaning").description("meaning related to portal")
)))
.andReturn();

return mvcResult.getResponse().getHeader("Location");
Expand All @@ -102,7 +151,7 @@ private String postTestEntity(String uri, String content) throws Exception {
private String postTestPhenotype() throws Exception {
Phenotype phenotype = new Phenotype("BMI", Phenotype.Group.ANTHROPOMETRIC, "Body Mass Index",
Phenotype.Type.CONTINUOUS, "nn.nn");
return postTestEntity("/phenotypes", phenotypeJacksonTester.write(phenotype).getJson());
return postTestPhenotypeEntity("/phenotypes", phenotypeJacksonTester.write(phenotype).getJson());
}

@Test
Expand Down Expand Up @@ -174,7 +223,7 @@ public void shouldDeletePhenotype() throws Exception {
private String postTestProperty() throws Exception {
Property property = new Property("CALL_RATE", Property.Type.FLOAT, Property.Meaning.CALL_RATE, "calling rate");

return postTestEntity("/properties", propertyJacksonTester.write(property).getJson());
return postTestPropertyEntity("/properties", propertyJacksonTester.write(property).getJson());
}

@Test
Expand Down Expand Up @@ -256,9 +305,9 @@ public void testPaging() throws Exception {
Property property1 = new Property("CALL_RATE", Property.Type.DOUBLE, Property.Meaning.CALL_RATE, "calling rate");
Property property2 = new Property("MAF", Property.Type.FLOAT, Property.Meaning.MAF, "MAF");

postTestEntity("/properties", propertyJacksonTester.write(property1).getJson());
postTestPropertyEntity("/properties", propertyJacksonTester.write(property1).getJson());

postTestEntity("/properties", propertyJacksonTester.write(property2).getJson());
postTestPropertyEntity("/properties", propertyJacksonTester.write(property2).getJson());

mockMvc.perform(get("/properties?size=1").with(oAuthHelper.bearerToken("[email protected]")))
.andExpect(status().isOk())
Expand Down