diff --git a/.gitattributes b/.gitattributes
index 0f44a614..9f35bfa4 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -5,6 +5,7 @@
# to native line endings on checkout.
LICENSE text
*.MF text
+*.adoc text
*.csv text
*.html text
*.java text
@@ -13,6 +14,7 @@ LICENSE text
*.properties text
*.sql text
*.script text
+*.snippet text
*.txt text
*.xml text
*.xsd text
diff --git a/fhir/pom.xml b/fhir/pom.xml
index acfccd37..8647bfee 100644
--- a/fhir/pom.xml
+++ b/fhir/pom.xml
@@ -111,6 +111,54 @@
${db.flyway.locations}
+
+ org.asciidoctor
+ asciidoctor-maven-plugin
+
+
+ generate-docs
+ prepare-package
+
+ process-asciidoc
+
+
+ html
+ book
+
+
+
+
+
+ org.springframework.restdocs
+ spring-restdocs-asciidoctor
+ ${spring-restdocs.version}
+
+
+
+
+ maven-resources-plugin
+
+
+ copy-resources
+ prepare-package
+
+ copy-resources
+
+
+
+ ${project.build.outputDirectory}/static/docs
+
+
+
+
+ ${project.build.directory}/generated-docs
+
+
+
+
+
+
+
diff --git a/fhir/src/asciidoc/api-guide.adoc b/fhir/src/asciidoc/api-guide.adoc
new file mode 100644
index 00000000..ded5a211
--- /dev/null
+++ b/fhir/src/asciidoc/api-guide.adoc
@@ -0,0 +1,67 @@
+= RESTful Notes API Guide
+Andy Wilkinson;
+:doctype: book
+:icons: font
+:source-highlighter: highlightjs
+:toc: left
+:toclevels: 4
+:sectlinks:
+:operation-curl-request-title: Example request
+:operation-http-response-title: Example response
+
+[[overview]]
+= Overview
+
+[[overview-http-verbs]]
+== HTTP verbs
+
+RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
+use of HTTP verbs.
+
+|===
+| Verb | Usage
+
+| `GET`
+| Used to retrieve a resource
+
+| `POST`
+| Used to create a new resource
+
+| `PATCH`
+| Used to update an existing resource, including partial updates
+
+| `DELETE`
+| Used to delete an existing resource
+|===
+
+[[overview-http-status-codes]]
+== HTTP status codes
+
+RESTful notes tries to adhere as closely as possible to standard HTTP and REST conventions in its
+use of HTTP status codes.
+
+|===
+| Status code | Usage
+
+| `200 OK`
+| The request completed successfully
+
+| `201 Created`
+| A new resource has been created successfully. The resource's URI is available from the response's
+`Location` header
+
+| `204 No Content`
+| An update to an existing resource has been applied successfully
+
+| `400 Bad Request`
+| The request was malformed. The response body will include an error providing further information
+
+| `404 Not Found`
+| The requested resource did not exist
+|===
+
+[[overview-headers]]
+== Headers
+
+Every response has the following header(s):
+
diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/Code.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/Code.java
index cf84df6e..9740ece5 100644
--- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/Code.java
+++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/Code.java
@@ -38,6 +38,9 @@
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+import javax.validation.constraints.Size;
import java.io.Serializable;
import java.util.List;
import java.util.Objects;
@@ -64,11 +67,22 @@ public class Code extends VersionedBaseMetadata implements Serializable
public static final int MAX_MAPPED_CODE_LENGTH = 50;
+ @NotBlank
+ @Size( max = MAX_NAME_LENGTH )
private String name;
+
+ @NotBlank
+ @Size( max = MAX_CODE_LENGTH )
private String code;
+
+ @Size( max = MAX_MAPPED_CODE_LENGTH )
private String mappedCode;
+
private String description;
+
+ @NotNull
private CodeCategory codeCategory;
+
private List systemCodes;
@Basic
diff --git a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/CodeCategory.java b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/CodeCategory.java
index d8208190..33e11a63 100644
--- a/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/CodeCategory.java
+++ b/fhir/src/main/java/org/dhis2/fhir/adapter/fhir/metadata/model/CodeCategory.java
@@ -32,6 +32,8 @@
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Size;
import java.io.Serializable;
/**
@@ -49,8 +51,14 @@ public class CodeCategory extends VersionedBaseMetadata implements Serializable
public static final int MAX_CODE_LENGTH = 50;
+ @NotBlank
+ @Size( max = MAX_NAME_LENGTH )
private String name;
+
+ @NotBlank
+ @Size( max = MAX_CODE_LENGTH )
private String code;
+
private String description;
@Basic
diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryRestDocsTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryRestDocsTest.java
new file mode 100644
index 00000000..b1e960fa
--- /dev/null
+++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryRestDocsTest.java
@@ -0,0 +1,72 @@
+package org.dhis2.fhir.adapter.fhir;
+
+/*
+ * Copyright (c) 2004-2018, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.springframework.restdocs.JUnitRestDocumentation;
+import org.springframework.restdocs.mockmvc.RestDocumentationResultHandler;
+import org.springframework.test.annotation.Rollback;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
+import static org.springframework.restdocs.operation.preprocess.Preprocessors.*;
+
+/**
+ * Abstract test class that generate REST documentation for JPA repositories.
+ *
+ * @author volsch
+ */
+@Transactional
+@Rollback
+public abstract class AbstractJpaRepositoryRestDocsTest extends AbstractJpaRepositoryTest
+{
+ @Rule
+ public final JUnitRestDocumentation restDocumentation = new JUnitRestDocumentation();
+
+ protected RestDocumentationResultHandler documentationHandler;
+
+ protected MockMvc docMockMvc;
+
+ @Before
+ public void beforeAbstractJpaRepositoryRestDocsTest()
+ {
+ documentationHandler = document( "{method-name}",
+ preprocessRequest( prettyPrint() ),
+ preprocessResponse( removeHeaders( "X-Content-Type-Options", "X-XSS-Protection", "X-Frame-Options" ), prettyPrint() ) );
+
+ docMockMvc = MockMvcBuilders.webAppContextSetup( context )
+ .apply( documentationConfiguration( restDocumentation ).uris().withPort( 8081 ) )
+ .alwaysDo( documentationHandler )
+ .build();
+ }
+}
diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryTest.java
index 047b6171..d2094c72 100644
--- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryTest.java
+++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/AbstractJpaRepositoryTest.java
@@ -31,6 +31,7 @@
import org.dhis2.fhir.adapter.fhir.data.DataBasePackage;
import org.dhis2.fhir.adapter.fhir.metadata.MetadataBasePackage;
import org.dhis2.fhir.adapter.jackson.JacksonConfig;
+import org.junit.Before;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
@@ -39,8 +40,6 @@
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.boot.test.autoconfigure.restdocs.AutoConfigureRestDocs;
-import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.rest.webmvc.config.RepositoryRestMvcConfiguration;
@@ -48,9 +47,8 @@
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
-import org.springframework.test.web.servlet.request.RequestPostProcessor;
-
-import javax.annotation.Nonnull;
+import org.springframework.test.web.servlet.setup.MockMvcBuilders;
+import org.springframework.web.context.WebApplicationContext;
/**
* Abstract base class for JPA Repository dependent tests.
@@ -64,20 +62,17 @@
@EntityScan( basePackageClasses = { DataBasePackage.class, MetadataBasePackage.class } )
@SpringBootTest( webEnvironment = SpringBootTest.WebEnvironment.MOCK )
@TestPropertySource( "classpath:test.properties" )
-@AutoConfigureMockMvc
-@AutoConfigureRestDocs( outputDir = "target/snippets/{class-name}/{method-name}" )
@DataJpaTest
public abstract class AbstractJpaRepositoryTest
{
@Autowired
+ protected WebApplicationContext context;
+
protected MockMvc mockMvc;
- @Nonnull
- protected RequestPostProcessor createRequestPostProcessor()
+ @Before
+ public void beforeAbstractJpaRepositoryTest()
{
- return request -> {
- request.setRemotePort( 8081 );
- return request;
- };
+ mockMvc = MockMvcBuilders.webAppContextSetup( context ).build();
}
}
diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/ConstrainedFields.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/ConstrainedFields.java
new file mode 100644
index 00000000..52ac6f1c
--- /dev/null
+++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/ConstrainedFields.java
@@ -0,0 +1,58 @@
+package org.dhis2.fhir.adapter.fhir;
+
+/*
+ * Copyright (c) 2004-2018, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.springframework.restdocs.constraints.ConstraintDescriptions;
+import org.springframework.restdocs.payload.FieldDescriptor;
+import org.springframework.util.StringUtils;
+
+import javax.annotation.Nonnull;
+
+import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
+import static org.springframework.restdocs.snippet.Attributes.key;
+
+/**
+ * Contains constrained fields of a class for REST documentation.
+ *
+ * @author volsch
+ */
+public class ConstrainedFields
+{
+ private final ConstraintDescriptions constraintDescriptions;
+
+ public ConstrainedFields( @Nonnull Class> input )
+ {
+ this.constraintDescriptions = new ConstraintDescriptions( input );
+ }
+
+ public FieldDescriptor withPath( @Nonnull String path )
+ {
+ return fieldWithPath( path ).attributes( key( "constraints" ).value( StringUtils.collectionToDelimitedString( constraintDescriptions.descriptionsForProperty( path ), ". " ) ) );
+ }
+}
diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestConfig.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestConfig.java
index a3f22251..4ff2ab2a 100644
--- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestConfig.java
+++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestConfig.java
@@ -31,6 +31,7 @@
import org.dhis2.fhir.adapter.converter.ZonedDateTimeToDateConverter;
import org.dhis2.fhir.adapter.script.ScriptCompiler;
import org.dhis2.fhir.adapter.script.impl.ScriptCompilerImpl;
+import org.springframework.boot.test.autoconfigure.restdocs.RestDocsAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
@@ -39,6 +40,7 @@
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurerAdapter;
import org.springframework.format.FormatterRegistry;
+import org.springframework.test.context.ContextConfiguration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Nonnull;
@@ -48,9 +50,10 @@
/**
* Test configuration.
*
- * @author volsch4
+ * @author volsch
*/
@Configuration
+@ContextConfiguration( classes = { RestDocsAutoConfiguration.class } )
public class TestConfig
{
@Nonnull
diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestWebSecurityConfig.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestWebSecurityConfig.java
index 0a87da37..0b4b55b8 100644
--- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestWebSecurityConfig.java
+++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/TestWebSecurityConfig.java
@@ -30,7 +30,6 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
-import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@@ -61,13 +60,4 @@ protected void configure( @Nonnull HttpSecurity http ) throws Exception
.and()
.httpBasic().realmName( DHIS_BASIC_REALM );
}
-
- @Override
- protected void configure( AuthenticationManagerBuilder auth ) throws Exception
- {
- auth.inMemoryAuthentication()
- .withUser( "code" )
- .password( "code" )
- .roles( "CODE_MAPPING" );
- }
}
diff --git a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CodeCategoryRepositoryTest.java b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CodeCategoryRepositoryRestDocsTest.java
similarity index 54%
rename from fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CodeCategoryRepositoryTest.java
rename to fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CodeCategoryRepositoryRestDocsTest.java
index f53b5e55..5bf604fb 100644
--- a/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CodeCategoryRepositoryTest.java
+++ b/fhir/src/test/java/org/dhis2/fhir/adapter/fhir/metadata/repository/CodeCategoryRepositoryRestDocsTest.java
@@ -29,16 +29,22 @@
*/
import org.apache.commons.io.IOUtils;
-import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryTest;
+import org.dhis2.fhir.adapter.fhir.AbstractJpaRepositoryRestDocsTest;
+import org.dhis2.fhir.adapter.fhir.ConstrainedFields;
+import org.dhis2.fhir.adapter.fhir.metadata.model.CodeCategory;
import org.junit.Test;
import org.springframework.http.MediaType;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.security.test.context.support.WithMockUser;
-import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
+import java.util.Objects;
+
+import static org.hamcrest.Matchers.is;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
-import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
+import static org.springframework.restdocs.snippet.Attributes.attributes;
+import static org.springframework.restdocs.snippet.Attributes.key;
+import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
/**
@@ -46,19 +52,30 @@
*
* @author volsch
*/
-public class CodeCategoryRepositoryTest extends AbstractJpaRepositoryTest
+public class CodeCategoryRepositoryRestDocsTest extends AbstractJpaRepositoryRestDocsTest
{
- @WithMockUser( username = "2h2maqu827da1", password = "code_test", roles = "CODE_MAPPING" )
@Test
+ @WithMockUser( username = "2h2maqu827d", password = "code_test", roles = "CODE_MAPPING" )
public void createCodeCategory() throws Exception
{
- mockMvc.perform( post( "/api/codeCategories" ).with( createRequestPostProcessor() ).contentType( MediaType.APPLICATION_JSON ).accept( MediaType.APPLICATION_JSON )
+ final ConstrainedFields fields = new ConstrainedFields( CodeCategory.class );
+ final String location = docMockMvc.perform( post( "/api/codeCategories" ).contentType( MediaType.APPLICATION_JSON )
.content( IOUtils.resourceToByteArray( "/org/dhis2/fhir/adapter/fhir/metadata/repository/createCodeCategory.json" ) ) )
.andExpect( status().isCreated() )
- .andDo( document( "{method-name}/", requestFields(
- fieldWithPath( "name" ).description( "The unique name of the code category." ).type( JsonFieldType.STRING ),
- fieldWithPath( "code" ).description( "The unique code of the code category." ).type( JsonFieldType.STRING ),
- fieldWithPath( "description" ).description( "The detailed description that describes for which purpose the code category is used." ).type( JsonFieldType.STRING ).optional().attributes()
- ) ) );
+ .andExpect( header().exists( "Location" ) )
+ .andDo( documentationHandler.document( requestFields(
+ attributes( key( "title" ).value( "Fields for code category creation" ) ),
+ fields.withPath( "name" ).description( "The unique name of the code category." ).type( JsonFieldType.STRING ),
+ fields.withPath( "code" ).description( "The unique code of the code category." ).type( JsonFieldType.STRING ),
+ fields.withPath( "description" ).description( "The detailed description that describes for which purpose the code category is used." ).type( JsonFieldType.STRING ).optional()
+ ) ) ).andReturn().getResponse().getHeader( "Location" );
+
+ mockMvc
+ .perform( get( Objects.requireNonNull( location ) ) )
+ .andExpect( status().isOk() )
+ .andExpect( jsonPath( "lastUpdatedBy", is( "2h2maqu827d" ) ) )
+ .andExpect( jsonPath( "name", is( "Test Code Category" ) ) )
+ .andExpect( jsonPath( "code", is( "TEST_CODE_CATEGORY" ) ) )
+ .andExpect( jsonPath( "_links.self.href", is( location ) ) );
}
}
\ No newline at end of file
diff --git a/fhir/src/test/resources/data.sql b/fhir/src/test/resources/data.sql
new file mode 100644
index 00000000..adaecbc3
--- /dev/null
+++ b/fhir/src/test/resources/data.sql
@@ -0,0 +1,30 @@
+--
+-- Copyright (c) 2004-2018, University of Oslo
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+-- Redistributions of source code must retain the above copyright notice, this
+-- list of conditions and the following disclaimer.
+--
+-- Redistributions in binary form must reproduce the above copyright notice,
+-- this list of conditions and the following disclaimer in the documentation
+-- and/or other materials provided with the distribution.
+-- Neither the name of the HISP project nor the names of its contributors may
+-- be used to endorse or promote products derived from this software without
+-- specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+-- WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+-- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+-- ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+-- LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+-- ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+-- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+
+INSERT INTO fhir_code_category(id, version, created_at, last_updated_at, last_updated_by, name, code, description)
+VALUES (RANDOM_UUID(), 0, CURRENT_TIMESTAMP(), CURRENT_TIMESTAMP(), '2h2maqu827d', 'Organization Unit', 'ORGANIZATION_UNIT', 'Includes the mapping for organization units.');
diff --git a/fhir/src/test/resources/org/springframework/restdocs/templates/request-fields.snippet b/fhir/src/test/resources/org/springframework/restdocs/templates/request-fields.snippet
new file mode 100644
index 00000000..ba2f3608
--- /dev/null
+++ b/fhir/src/test/resources/org/springframework/restdocs/templates/request-fields.snippet
@@ -0,0 +1,12 @@
+.{{title}}
+|===
+|Path|Type|Description|Constraints
+
+{{#fields}}
+|{{path}}
+|{{type}}
+|{{description}}
+|{{constraints}}
+
+{{/fields}}
+|===