Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Genesys PGR
Genesys Backend
Commits
cec3f8b8
Commit
cec3f8b8
authored
Sep 28, 2018
by
Matija Obreza
Browse files
Implemented AsciiDoc controller
- Including unit tests
parent
628e9c14
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/main/java/org/genesys2/server/api/v1/AsciiDocController.java
0 → 100644
View file @
cec3f8b8
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.genesys2.server.api.v1
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
org.apache.commons.io.IOUtils
;
import
org.apache.commons.lang3.StringUtils
;
import
org.genesys2.server.api.ApiBaseController
;
import
org.genesys2.spring.ResourceNotFoundException
;
import
org.jsoup.Jsoup
;
import
org.jsoup.nodes.Document
;
import
org.jsoup.nodes.Element
;
import
org.jsoup.select.Elements
;
import
org.springframework.http.MediaType
;
import
org.springframework.security.access.prepost.PreAuthorize
;
import
org.springframework.web.bind.annotation.PathVariable
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RequestMethod
;
import
org.springframework.web.bind.annotation.ResponseBody
;
import
org.springframework.web.bind.annotation.RestController
;
import
io.swagger.annotations.Api
;
/**
* AsciiDoc API v1.
*/
@RestController
(
"asciiDocApi1"
)
@PreAuthorize
(
"isAuthenticated()"
)
@RequestMapping
(
AsciiDocController
.
API_BASE
)
@Api
(
tags
=
{
"asciiDoc"
})
public
class
AsciiDocController
{
/** The Constant DOCS_DIR. */
private
static
final
String
DOCS_DIR
=
"docs/"
;
/** The Constant DOCS_SECTIONS_DIR. */
private
static
final
String
DOCS_SECTIONS_DIR
=
"sections/"
;
/** The Constant DOCS_IMAGES_DIR. */
private
static
final
String
DOCS_IMAGES_DIR
=
"images/"
;
/** The Constant HTML_EXTENSION. */
private
static
final
String
HTML_EXTENSION
=
".html"
;
/** The Constant API_BASE. */
public
static
final
String
API_BASE
=
ApiBaseController
.
APIv1_BASE
+
"/cms/d"
;
/**
* View doc.
*
* @param documentName the document name
* @return the map
* @throws IOException Signals that an I/O exception has occurred.
*/
@RequestMapping
(
value
=
"/{documentName}"
,
method
=
RequestMethod
.
GET
,
produces
=
{
MediaType
.
APPLICATION_JSON_VALUE
})
public
ADoc
viewDoc
(
@PathVariable
(
value
=
"documentName"
)
String
documentName
)
throws
IOException
{
ADoc
resultDoc
=
new
ADoc
();
ClassLoader
classLoader
=
this
.
getClass
().
getClassLoader
();
String
docPath
=
new
StringBuilder
(
DOCS_DIR
).
append
(
documentName
).
append
(
HTML_EXTENSION
).
toString
();
InputStream
resourceStream
=
classLoader
.
getResourceAsStream
(
docPath
);
if
(
resourceStream
==
null
)
{
throw
new
ResourceNotFoundException
();
}
String
html
=
IOUtils
.
toString
(
resourceStream
);
Document
document
=
Jsoup
.
parse
(
html
);
resultDoc
.
title
=
StringUtils
.
stripToNull
(
document
.
getElementsByTag
(
"title"
).
html
());
Element
toc
=
document
.
getElementById
(
"toc"
);
if
(
toc
!=
null
)
{
toc
.
getElementById
(
"toctitle"
).
remove
();
toc
.
removeAttr
(
"id"
).
removeAttr
(
"class"
);
resultDoc
.
toc
=
StringUtils
.
stripToNull
(
toc
.
html
());
toc
.
remove
();
}
Element
header
=
document
.
getElementById
(
"header"
);
if
(
header
!=
null
)
{
Elements
headerH1
=
header
.
getElementsByTag
(
"h1"
);
if
(
headerH1
!=
null
)
{
// Use HTML title if available
resultDoc
.
title
=
StringUtils
.
defaultIfBlank
(
headerH1
.
html
(),
resultDoc
.
title
);
}
resultDoc
.
header
=
StringUtils
.
stripToNull
(
header
.
getElementsByClass
(
"details"
).
removeAttr
(
"id"
).
html
());
}
Element
content
=
document
.
getElementById
(
"content"
);
if
(
content
!=
null
)
{
resultDoc
.
content
=
StringUtils
.
stripToNull
(
content
.
html
());
}
Element
footer
=
document
.
getElementById
(
"footer-text"
);
if
(
footer
!=
null
)
{
resultDoc
.
footer
=
StringUtils
.
stripToNull
(
footer
.
html
());
}
return
resultDoc
;
}
/**
* View section.
*
* @param documentName the document name
* @return the map
* @throws IOException Signals that an I/O exception has occurred.
*/
@RequestMapping
(
value
=
"/sections/{documentName}"
,
method
=
RequestMethod
.
GET
,
produces
=
{
MediaType
.
APPLICATION_JSON_VALUE
})
public
ADoc
viewSection
(
@PathVariable
(
value
=
"documentName"
)
String
documentName
)
throws
IOException
{
String
docPath
=
new
StringBuilder
(
DOCS_SECTIONS_DIR
).
append
(
documentName
).
toString
();
return
viewDoc
(
docPath
);
}
/**
* Gets the image.
*
* @param imageName the image name
* @return the image
* @throws IOException Signals that an I/O exception has occurred.
*/
@RequestMapping
(
value
=
"/images/{imageName}"
,
method
=
RequestMethod
.
GET
,
produces
=
{
MediaType
.
IMAGE_JPEG_VALUE
})
@ResponseBody
public
byte
[]
getImage
(
@PathVariable
(
value
=
"imageName"
)
String
imageName
)
throws
IOException
{
ClassLoader
classLoader
=
this
.
getClass
().
getClassLoader
();
String
imgPath
=
new
StringBuilder
(
DOCS_DIR
).
append
(
DOCS_IMAGES_DIR
).
append
(
imageName
).
toString
();
InputStream
inputStream
=
classLoader
.
getResourceAsStream
(
imgPath
);
if
(
inputStream
==
null
)
{
throw
new
ResourceNotFoundException
();
}
return
IOUtils
.
toByteArray
(
inputStream
);
}
public
static
class
ADoc
{
public
String
title
;
public
String
toc
;
public
String
header
;
public
String
content
;
public
String
footer
;
}
}
src/test/java/org/genesys/test/server/api/v1/AsciiDocControllerTest.java
0 → 100644
View file @
cec3f8b8
/*
* Copyright 2018 Global Crop Diversity Trust
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.genesys.test.server.api.v1
;
import
static
org
.
hamcrest
.
CoreMatchers
.
nullValue
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
springframework
.
restdocs
.
mockmvc
.
MockMvcRestDocumentation
.
documentationConfiguration
;
import
static
org
.
springframework
.
test
.
web
.
servlet
.
request
.
MockMvcRequestBuilders
.
get
;
import
static
org
.
springframework
.
test
.
web
.
servlet
.
result
.
MockMvcResultMatchers
.*;
import
java.lang.reflect.Field
;
import
java.lang.reflect.Modifier
;
import
org.genesys.test.base.AbstractApiTest
;
import
org.genesys2.server.api.v1.AsciiDocController
;
import
org.junit.Before
;
import
org.junit.Rule
;
import
org.junit.Test
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.http.MediaType
;
import
org.springframework.restdocs.JUnitRestDocumentation
;
import
org.springframework.test.web.servlet.MockMvc
;
import
org.springframework.test.web.servlet.result.MockMvcResultHandlers
;
import
org.springframework.test.web.servlet.setup.MockMvcBuilders
;
import
org.springframework.web.context.WebApplicationContext
;
/**
* The Class AsciiDocControllerTest.
*/
public
class
AsciiDocControllerTest
extends
AbstractApiTest
{
/** The rest documentation. */
@Rule
public
final
JUnitRestDocumentation
restDocumentation
=
new
JUnitRestDocumentation
(
"target/generated-snippets"
);
/** The web application context. */
@Autowired
private
WebApplicationContext
webApplicationContext
;
/** The mock mvc. */
MockMvc
mockMvc
;
/*
* (non-Javadoc)
* @see org.genesys.test.base.AbstractApiTest#beforeTest()
*/
@Before
@Override
public
void
beforeTest
()
throws
Exception
{
super
.
beforeTest
();
/*@formatter:off*/
mockMvc
=
MockMvcBuilders
.
webAppContextSetup
(
webApplicationContext
)
.
apply
(
documentationConfiguration
(
this
.
restDocumentation
)
.
uris
().
withScheme
(
"https"
).
withHost
(
"sandbox.genesys-pgr.org"
).
withPort
(
443
))
.
build
();
/*@formatter:on*/
// setFinalStatic(AsciiDocController.class.getDeclaredField("DOCS_DIR"),
// "docs/");
}
/**
* View doc test.
*
* @throws Exception the exception
*/
@Test
public
void
viewDocTest
()
throws
Exception
{
/*@formatter:off*/
mockMvc
.
perform
(
get
(
AsciiDocController
.
API_BASE
+
"/"
+
"index"
)
.
contentType
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isOk
())
// .andDo(MockMvcResultHandlers.print())
.
andExpect
(
content
().
contentType
(
MediaType
.
APPLICATION_JSON_UTF8_VALUE
))
.
andExpect
(
jsonPath
(
"$.title"
,
is
(
"Genesys API <b>reference</b> manual"
)))
.
andExpect
(
jsonPath
(
"$.footer"
,
is
(
"Version 2.3"
)))
.
andExpect
(
jsonPath
(
"$.header"
,
is
(
"<span id=\"author\" class=\"author\">Author</span>\n<br> \n<span id=\"revnumber\">version 2.3</span>"
)))
.
andExpect
(
jsonPath
(
"$.content"
,
is
(
"Here be \n<b>dragons</b>!"
)))
;
/*@formatter:on*/
}
/**
* View section test.
*
* @throws Exception the exception
*/
@Test
public
void
viewSectionTest
()
throws
Exception
{
/*@formatter:off*/
mockMvc
.
perform
(
get
(
AsciiDocController
.
API_BASE
+
"/sections/"
+
"apis"
)
.
contentType
(
MediaType
.
APPLICATION_JSON
))
.
andExpect
(
status
().
isOk
())
// .andDo(MockMvcResultHandlers.print())
.
andExpect
(
content
().
contentType
(
MediaType
.
APPLICATION_JSON_UTF8_VALUE
))
.
andExpect
(
jsonPath
(
"$.title"
,
is
(
"Application"
)))
.
andExpect
(
jsonPath
(
"$.header"
,
nullValue
()))
.
andExpect
(
jsonPath
(
"$.footer"
,
is
(
"Last updated 2017-10-15"
)))
.
andExpect
(
jsonPath
(
"$.content"
,
is
(
"Here be \n<b>dragons</b>!"
)))
;
/*@formatter:on*/
}
/**
* Sets the final static.
*
* @param field the field
* @param newValue the new value
* @throws Exception the exception
*/
static
void
setFinalStatic
(
Field
field
,
Object
newValue
)
throws
Exception
{
field
.
setAccessible
(
true
);
// remove final modifier from field
Field
modifiersField
=
Field
.
class
.
getDeclaredField
(
"modifiers"
);
modifiersField
.
setAccessible
(
true
);
modifiersField
.
setInt
(
field
,
field
.
getModifiers
()
&
~
Modifier
.
FINAL
);
field
.
set
(
null
,
newValue
);
}
}
src/test/resources/docs/index.html
0 → 100644
View file @
cec3f8b8
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<title>
Index test
</title>
</head>
<body>
<div
id=
"header"
>
<h1>
Genesys API
<b>
reference
</b>
manual
</h1>
<div
class=
"details"
>
<span
id=
"author"
class=
"author"
>
Author
</span><br>
<span
id=
"revnumber"
>
version 2.3
</span>
</div>
<div
id=
"toc"
class=
"toc2"
>
<div
id=
"toctitle"
>
Table of Contents
</div>
<ul
class=
"sectlevel1"
>
<li><a
href=
"#chSecurity"
>
1. Security
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#obtaining-the-access-token"
>
1.1. Obtaining
the access token
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#authorization-grant"
>
1.1.1. Authorization
grant
</a></li>
<li><a
href=
"#username-and-password"
>
1.1.2. Username
and password
</a></li>
<li><a
href=
"#client-credentials"
>
1.1.3. Client
credentials
</a></li>
<li><a
href=
"#successful-authorization"
>
1.1.4.
Successful authorization
</a></li>
</ul></li>
<li><a
href=
"#using-the-refresh-token"
>
1.2. Using the
refresh token
</a></li>
</ul></li>
<li><a
href=
"#client-errors"
>
2. Client errors
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#401-unauthorized"
>
2.1. 401 Unauthorized
</a></li>
</ul></li>
<li><a
href=
"#chApiAccession"
>
3. Managing passport data
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#accession-identity"
>
3.1. Accession identity
</a></li>
<li><a
href=
"#json-data-model"
>
3.2. JSON data model
</a></li>
<li><a
href=
"#geographic-data-json-model"
>
3.3. Geographic
data JSON model
</a></li>
<li><a
href=
"#collecting-data-json-model"
>
3.4. Collecting
data JSON model
</a></li>
<li><a
href=
"#clearing-existing-values"
>
3.5. Clearing
existing values
</a></li>
<li><a
href=
"#insert-or-update-accessions"
>
3.6. Insert or
update accessions
</a></li>
<li><a
href=
"#deleting-accessions"
>
3.7. Deleting
accessions
</a></li>
</ul></li>
<li><a
href=
"#chApiImg"
>
4. Managing accession images
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#listing-existing-galleries"
>
4.1. Listing
existing galleries
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#path-parameters"
>
4.1.1. Path parameters
</a></li>
<li><a
href=
"#request-parameters"
>
4.1.2. Request
parameters
</a></li>
<li><a
href=
"#server-response"
>
4.1.3. Server response
</a></li>
</ul></li>
<li><a
href=
"#accepted-image-formats"
>
4.2. Accepted image
formats
</a></li>
<li><a
href=
"#adding-images-to-accessions"
>
4.3. Adding
images to accessions
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#path-parameters-2"
>
4.3.1. Path parameters
</a></li>
<li><a
href=
"#request-parameters-2"
>
4.3.2. Request
parameters
</a></li>
<li><a
href=
"#server-response-2"
>
4.3.3. Server response
</a></li>
</ul></li>
<li><a
href=
"#updating-image-metadata"
>
4.4. Updating
image metadata
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#path-parameters-3"
>
4.4.1. Path parameters
</a></li>
<li><a
href=
"#response-fields"
>
4.4.2. Response fields
</a></li>
</ul></li>
</ul></li>
<li><a
href=
"#chApiRequests"
>
5. Managing requests
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#listing-requests"
>
5.1. Listing requests
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#path-parameters-4"
>
5.1.1. Path parameters
</a></li>
<li><a
href=
"#request-parameters-3"
>
5.1.2. Request
parameters
</a></li>
<li><a
href=
"#server-response-3"
>
5.1.3. Server response
</a></li>
</ul></li>
<li><a
href=
"#request-details"
>
5.2. Request details
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#path-parameters-5"
>
5.2.1. Path parameters
</a></li>
<li><a
href=
"#server-response-4"
>
5.2.2. Server response
</a></li>
</ul></li>
</ul></li>
<li><a
href=
"#chApiCrop"
>
6. Managing crop data
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#crop-taxonomic-rules"
>
6.1. Crop taxonomic
rules
</a></li>
<li><a
href=
"#listing-all-crops"
>
6.2. Listing all crops
</a></li>
<li><a
href=
"#retrieving-crop-data"
>
6.3. Retrieving crop
data
</a>
<ul
class=
"sectlevel3"
>
<li><a
href=
"#taxonomic-rules"
>
6.3.1. Taxonomic rules
</a></li>
<li><a
href=
"#exclusion-rule"
>
6.3.2. Exclusion rule
</a></li>
</ul></li>
<li><a
href=
"#registering-a-new-crop"
>
6.4. Registering a
new crop
</a></li>
<li><a
href=
"#localization-of-crop-title-and-description"
>
6.5.
Localization of crop title and description
</a></li>
<li><a
href=
"#updating-taxonomic-rules"
>
6.6. Updating
taxonomic rules
</a></li>
<li><a
href=
"#deleting-a-crop"
>
6.7. Deleting a crop
</a></li>
</ul></li>
<li><a
href=
"#acknowledgements"
>
7. Acknowledgements
</a></li>
</ul>
</div>
</div>
<div
id=
"content"
>
Here be
<b>
dragons
</b>
!
</div>
<div
id=
"footer"
>
<div
id=
"footer-text"
>
Version 2.3
</div>
</div>
</body>
</html>
\ No newline at end of file
src/test/resources/docs/sections/apis.html
0 → 100644
View file @
cec3f8b8
<!DOCTYPE html>
<html
lang=
"en"
>
<head>
<meta
charset=
"UTF-8"
>
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=edge"><![endif]-->
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<meta
name=
"generator"
content=
"Asciidoctor 1.5.3"
>
<title>
Application
</title>
</head>
<body
class=
"book toc2 toc-left"
>
<div
id=
"header"
>
<div
id=
"toc"
class=
"toc2"
>
<div
id=
"toctitle"
>
Table of Contents
</div>
<ul
class=
"sectlevel1"
>
<li><a
href=
"#chBackup"
>
Application
</a></li>
<li><a
href=
"#configuration"
>
Configuration
</a></li>
<li><a
href=
"#data"
>
Data
</a>
<ul
class=
"sectlevel2"
>
<li><a
href=
"#database-backup"
>
Database backup
</a></li>
<li><a
href=
"#file-backup"
>
File backup
</a></li>
<li><a
href=
"#elasticsearch-backup"
>
Elasticsearch backup
</a></li>
</ul></li>
<li><a
href=
"#validating-backups"
>
Validating backups
</a></li>
</ul>
</div>
</div>
<div
id=
"content"
>
Here be
<b>
dragons
</b>
!
</div>
<div
id=
"footer"
>
<div
id=
"footer-text"
>
Last updated 2017-10-15
</div>
</div>
</body>
</html>
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment