Compare commits

...
90 Commits
Author SHA1 Message Date
kyle 1d00c952d6 Merge pull request #3717 from swagger-api/v/3.3.0
v/3.3.0
2017-09-29 18:54:05 -07:00
Kyle Shockey 4e6dc3beec Rebuild dist 2017-09-29 18:48:30 -07:00
Kyle Shockey 4ff629eddd v3.3.0 2017-09-29 18:43:21 -07:00
kyle dd02778b55 Merge pull request #3716 from swagger-api/ft/oas3-disable-auth
Disable Swagger2 auth features in OAS3
2017-09-29 17:56:15 -07:00
Kyle Shockey e15b4c85c0 ESLint.... 2017-09-29 17:51:12 -07:00
Kyle Shockey 7e6f74080f Disable Swagger2 auth features in OAS3 2017-09-29 17:49:15 -07:00
kyle c6a664302a Merge pull request #3421 from dalbani/feature/request-url
Restore "Request URL" in live response section
2017-09-29 14:51:37 -07:00
kyle ac634c61ce Merge branch 'master' into feature/request-url 2017-09-29 14:38:42 -07:00
kyle 37399958a2 Merge pull request #3531 from mhw/array-model-markdown-description
Array description should be processed as Markdown.
2017-09-29 14:15:20 -07:00
kyle 44882700c2 Merge branch 'master' into array-model-markdown-description 2017-09-29 14:06:01 -07:00
kyle cecc3b3573 Merge pull request #3628 from gilbode/ft/default_model_rendering
Add defaultModelRendering parameter.
2017-09-29 13:55:15 -07:00
kyle 263f6feb2f Merge branch 'master' into ft/default_model_rendering 2017-09-29 13:29:04 -07:00
kyle 356dc81b18 Merge pull request #3712 from owenconti/bug/swagger-editor-1502
Fixes swagger-editor/#1502.
2017-09-29 12:45:00 -07:00
Kyle Shockey a7acd9e004 Remove react-remarkable from package.json 2017-09-29 12:38:00 -07:00
kyle ef9fe9d755 Merge branch 'master' into bug/swagger-editor-1502 2017-09-29 12:16:01 -07:00
kyle ca98ed114a Merge pull request #3647 from JoshuaWhatley/bug/3474
Bug/3474
2017-09-28 18:16:40 -07:00
kyle c5534a506e Merge branch 'master' into bug/3474 2017-09-28 18:12:26 -07:00
kyle e0fb125a48 Merge pull request #3703 from heldersepu/ft/validation
Add validateMaximum & validateMinimum
2017-09-28 18:04:14 -07:00
Kyle Shockey 012313e236 Handle cases where maximum and minimum are 0 2017-09-28 17:59:07 -07:00
kyle 27da2a7d3b Merge branch 'master' into ft/validation 2017-09-28 17:53:14 -07:00
kyle 67dbad445d Merge pull request #3701 from heldersepu/master
Add validation for min and max length
2017-09-28 17:48:23 -07:00
HelderSepu a408fb1f23 Correction from @shockey 2017-09-28 20:40:22 -04:00
kyle 3a7a8c9c67 Merge branch 'master' into master 2017-09-28 15:58:41 -07:00
kyle 239d105974 Merge pull request #3708 from owenconti/bug/3706-enum-param
Fixes #3706
2017-09-27 20:21:12 -07:00
kyle 4f1a8abd0d Merge branch 'master' into bug/3706-enum-param 2017-09-27 19:48:37 -07:00
kyle 13fd88f1d2 Merge pull request #3709 from ELE3E/master
Fixes #3694: Apply conditions for generating download link correctly
2017-09-27 19:48:02 -07:00
Owen Conti 590819ad9b Fixes swagger-editor/#1502.
Change logic for markdown rendering to:

1. Convert source markdown to HTML
2. Sanitize HTML
3. Send sanitized HTML to markdown renderer
2017-09-27 18:05:12 -06:00
Elvin Lemmens ca1a0fa544 Apply conditions for generating download link correctly
Invalid application of AND/OR statements prevented file downloads of other types than application/octet-stream from generating a download link
2017-09-27 12:34:46 +02:00
Owen Conti 31e7ce0c5e Fixes #3706
Add missing "in" argument to `getParameter`
2017-09-25 21:26:44 -06:00
kyle d1258c6b8c Merge branch 'master' into ft/validation 2017-09-24 18:09:19 -07:00
HelderSepu 515726b386 Add test for negative num
Testing valid negative number with min and max
2017-09-24 15:45:42 -04:00
HelderSepu 7d40d72281 Add validateMaximum & validateMinimum
This address some of the validation requested on Issue #993
2017-09-24 11:43:47 -04:00
kyle 774a06606d Merge pull request #3699 from shockey/v/3.2.2
v3.2.2
2017-09-23 14:43:44 -07:00
Kyle Shockey 2d10a740af Rebuild with changes from #3702 2017-09-23 13:09:08 -07:00
Kyle Shockey 45e7a54182 Merge branch 'master' of github.com:swagger-api/swagger-ui into v/3.2.2 2017-09-23 12:58:06 -07:00
kyle 9e418ad68b Merge pull request #3702 from owenconti/bug/3511-query-formData-parameters
Fixes #3511 - 2nd attempt - Query & formData parameters together
2017-09-23 12:57:35 -07:00
Kyle Shockey de61dccff0 Revert "Revert "Merge pull request #3516 from owenconti/bug/3511-query-formData-parameters""
This reverts commit beeb6b608e.
2017-09-23 12:54:17 -07:00
Owen Conti fd00a0489a Remove shouldComponentUpdate from parameter-row component. It will be put back in eventually as part of the performance optimizations once the parameter components are converted to the smart/dumb approach. 2017-09-23 13:10:09 -06:00
HelderSepu a5c7083726 Add validation for min and max length 2017-09-23 14:14:58 -04:00
Kyle Shockey beeb6b608e Revert "Merge pull request #3516 from owenconti/bug/3511-query-formData-parameters"
This reverts commit 6a7e9d2e88, reversing
changes made to eb01beedfa.
2017-09-23 10:51:32 -07:00
Kyle Shockey c8a9ddbf94 v3.2.2 2017-09-23 00:02:10 -07:00
kyle 1de6010629 Merge pull request #3666 from AlexanderVangelov/master
OAuth2 authorizationUrl allow extra query parameters ('&' vs '?')
2017-09-22 20:49:21 -07:00
kyle b6eb23217f Merge branch 'master' into master 2017-09-22 20:45:07 -07:00
kyle a3f923eec7 Merge pull request #3698 from shockey/heldersepu-master
Heldersepu master
2017-09-22 20:16:08 -07:00
Kyle Shockey 6b59707af1 Fix tests 2017-09-22 19:50:36 -07:00
kyle 827bcd2f36 Merge branch 'master' into master 2017-09-22 19:50:19 -07:00
kyle 6a7e9d2e88 Merge pull request #3516 from owenconti/bug/3511-query-formData-parameters
Fixes #3511 - Query & formData parameters together
2017-09-22 19:27:31 -07:00
HelderSepu e08f31d674 Add UnitTests for validateDateTime & validateGuid 2017-09-22 21:37:33 -04:00
HelderSepu 7d9b56255c Correction to the validateDateTime 2017-09-22 17:44:01 -04:00
Helder Sepulveda b2abf769de Merge branch 'master' into master 2017-09-22 13:04:09 -04:00
HelderSepu 11768b16bf Correct IF for validateDateTime & validateGuid 2017-09-22 11:30:07 -04:00
Joshua Whatley 14f47654ee Merge branch 'master' into bug/3474 2017-09-21 16:54:54 -07:00
kyle 54a2d402c6 Merge branch 'master' into master 2017-09-21 00:15:41 -07:00
Owen Conti a1758da87c Merge branch 'master' into bug/3511-query-formData-parameters 2017-09-20 22:37:43 -06:00
kyle eb01beedfa Merge pull request #3691 from shockey/bug/3638-61338ref-in-examples
Remove $$ref values from response examples
2017-09-20 17:42:03 -07:00
kyle deebe1f840 Merge branch 'master' into bug/3638-61338ref-in-examples 2017-09-20 17:36:57 -07:00
Kyle Shockey 69941a6d9a Remove $$ref values from response examples 2017-09-20 17:34:23 -07:00
kyle 6a8f821901 Merge pull request #3690 from shockey/bug/3636-tag-description-markdown
Display Tag descriptions as Markdown
2017-09-20 17:01:45 -07:00
Kyle Shockey b0a580bdc1 Display Tag descriptions as Markdown 2017-09-20 16:55:45 -07:00
Alexander Vangelov 696bdcf961 Merge branch 'master' into master 2017-09-20 13:11:53 -04:00
HelderSepu 85b7b7241d Add validateDateTime & validateGuid
Initial work to tacke some of the missing validation (Issue #993)
2017-09-19 14:31:27 -04:00
HelderSepu bd6e482df2 Merge remote-tracking branch 'refs/remotes/swagger-api/master' 2017-09-19 13:37:04 -04:00
Owen Conti 7ef8a7ddc7 Merge branch 'master' of github.com:swagger-api/swagger-ui into bug/3511-query-formData-parameters
# Conflicts:
#	src/core/components/parameter-row.jsx
#	src/core/plugins/spec/actions.js
2017-09-18 16:59:08 -06:00
Joshua Whatley 6488cbb649 Merge branch 'master' into bug/3474 2017-09-18 11:27:10 -07:00
Alexander Vangelov 90fa7065f8 Merge branch 'master' into master 2017-09-16 11:24:36 -04:00
AlexVangelov c1abdfb1c4 follow lowercase naming convention in tests 2017-09-15 21:04:38 -04:00
AlexVangelov 5bf6d2ff0b Merge branches 'master' and 'master' of github.com:AlexanderVangelov/swagger-ui 2017-09-15 20:53:52 -04:00
AlexVangelov 4172e33e04 satisfy project lint rules 2017-09-15 20:52:55 -04:00
Alexander Vangelov 34e8fffb65 Merge branch 'master' into master 2017-09-15 20:40:46 -04:00
AlexVangelov 9b1a6141df OAuth2 authorizationUrl with extra query parameters (should include double '?') 2017-09-15 15:57:41 -04:00
Joshua Whatley 82b9341a06 Changing word-break to follow standard
Changed "break-word" to "break-all" as this is standard across all
browsers and results with consistent behavior.
2017-09-13 21:23:49 -07:00
Ron b9be09709a Merge branch 'master' into feature/request-url 2017-09-11 05:05:08 -07:00
Joshua Whatley 63ee0a874c break path if it would otherwise overflow 2017-09-08 16:53:43 -07:00
Joshua Whatley 7a4ef07c73 Merge remote-tracking branch 'refs/remotes/swagger-api/master' 2017-09-08 12:55:49 -07:00
Mike Gilbode d7ae284a0c Add defaultModelRendering parameter. 2017-08-30 23:30:57 -04:00
Kyle Shockey a6944a279c Remove getComponent call for RequestUrl 2017-08-21 17:21:48 -07:00
Kyle Shockey b2f7953319 Merge branch 'master' of github.com:swagger-api/swagger-ui into dalbani-feature/request-url 2017-08-21 17:19:33 -07:00
Kyle Shockey 39450f7364 Merge branch 'feature/request-url' of https://github.com/dalbani/swagger-ui into dalbani-feature/request-url 2017-08-21 17:19:17 -07:00
Kyle 04fb27b46d Merge branch 'master' into array-model-markdown-description 2017-08-11 17:42:30 -07:00
Kyle fd44416238 Merge branch 'master' into array-model-markdown-description 2017-08-10 13:58:38 -07:00
Mark H. Wilkinson d7424ff248 Array description should be processed as Markdown. 2017-08-07 12:33:15 +01:00
Owen Conti 5d7d20ec5e Merge branch 'master' into bug/3511-query-formData-parameters 2017-08-03 19:30:50 -06:00
Owen Conti 7a694e287a Change name format to in.name and update tests 2017-08-03 19:29:49 -06:00
Owen Conti 17e99428c7 Merge branch 'bug/3511-query-formData-parameters' of github.com:owenconti/swagger-ui into bug/3511-query-formData-parameters 2017-08-03 07:14:15 -06:00
Owen Conti ce8adb91a5 Fix failing selector test 2017-08-03 07:14:03 -06:00
Owen Conti 053d032e94 Merge branch 'master' into bug/3511-query-formData-parameters 2017-08-02 22:37:49 -06:00
Owen Conti 51016c33f4 Attach in value to parameters map so parameters with the same name from different in types do not override each other. 2017-08-02 22:37:31 -06:00
Owen Conti fdb0d13089 Fixes #3511 - Update changeParameter calls to accept in value to identify parameters based on name plus in value 2017-08-02 22:07:48 -06:00
Damiano Albani 175bc486c7 Merge branch 'master' into feature/request-url 2017-07-21 23:41:21 +02:00
Damiano Albani cd6b86e710 Restore "Request URL" in live response section 2017-07-20 14:12:34 +02:00
39 changed files with 652 additions and 101 deletions
+3 -1
View File
@@ -22,7 +22,7 @@ The OpenAPI Specification has undergone 5 revisions since initial creation in 20
Swagger UI Version | Release Date | OpenAPI Spec compatibility | Notes
------------------ | ------------ | -------------------------- | -----
3.2.1 | 2017-09-15 | 2.0, 3.0 | [tag v3.2.1](https://github.com/swagger-api/swagger-ui/tree/v3.2.1)
3.3.0 | 2017-09-29 | 2.0, 3.0 | [tag v3.3.0](https://github.com/swagger-api/swagger-ui/tree/v3.3.0)
3.0.21 | 2017-07-26 | 2.0 | [tag v3.0.21](https://github.com/swagger-api/swagger-ui/tree/v3.0.21)
2.2.10 | 2017-01-04 | 1.1, 1.2, 2.0 | [tag v2.2.10](https://github.com/swagger-api/swagger-ui/tree/v2.2.10)
2.1.5 | 2016-07-20 | 1.1, 1.2, 2.0 | [tag v2.1.5](https://github.com/swagger-api/swagger-ui/tree/v2.1.5)
@@ -151,6 +151,8 @@ domNode | The HTML DOM element inside which SwaggerUi will put the user interfac
oauth2RedirectUrl | OAuth redirect URL
tagsSorter | Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function (see [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger-UI.
operationsSorter | Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
defaultModelRendering | Controls how models are shown when the API is first rendered. (The user can always switch the rendering for a given model by clicking the 'Model' and 'Example Value' links.) It can be set to 'model' or 'example', and the default is 'example'.
defaultModelExpandDepth | The default expansion depth for models. The default value is 1.
configUrl | Configs URL
parameterMacro | MUST be a function. Function to set default value to parameters. Accepts two arguments parameterMacro(operation, parameter). Operation and parameter are objects passed for context, both remain immutable
modelPropertyMacro | MUST be a function. Function to set default values to each property in model. Accepts one argument modelPropertyMacro(property), property is immutable
+13 -12
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;AAwjMA;;;;;;AA65DA;;;;;;;;;;;;;;;;;;;;;;;;;;AAs9TA;;;;;;;;;;;;;;AAs8JA;;;;;;;;;AAm/pBA;;;;;AAu5QA;;;;;AAynBA;AAi0CA;;;;;;AAq/YA;;;;;;AAojaA;AA8lvBA","sourceRoot":""}
{"version":3,"file":"swagger-ui-bundle.js","sources":["webpack:///swagger-ui-bundle.js"],"mappings":"AAAA;;;;;AAonMA;;;;;;AAm5DA;;;;;;;;;;;;;;;;;;;;;;;;;;AAukUA;;;;;;;;;;;;;;AAq4JA;AAw+iBA;;;;;;;;;AA8oIA;;;;;AA87QA;;;;;AAynBA;AAo0CA;;;;;;AA6gZA;;;;;;AAkzZA;AAixYA","sourceRoot":""}
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA80CA;;;;;;AAqpFA","sourceRoot":""}
{"version":3,"file":"swagger-ui-standalone-preset.js","sources":["webpack:///swagger-ui-standalone-preset.js"],"mappings":"AAAA;;;;;AA6mCA;;;;;;AA41FA","sourceRoot":""}
+1 -1
View File
File diff suppressed because one or more lines are too long
+2 -2
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -1 +1 @@
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAmxeA","sourceRoot":""}
{"version":3,"file":"swagger-ui.js","sources":["webpack:///swagger-ui.js"],"mappings":"AAAA;;;;;;AAy7eA","sourceRoot":""}
+4 -3
View File
@@ -1,6 +1,6 @@
{
"name": "swagger-ui",
"version": "3.2.1",
"version": "3.3.0",
"main": "dist/swagger-ui.js",
"repository": "git@github.com:swagger-api/swagger-ui.git",
"contributors": [
@@ -42,6 +42,7 @@
"base64-js": "^1.2.0",
"brace": "0.7.0",
"classnames": "^2.2.5",
"commonmark": "^0.28.1",
"css.escape": "1.5.1",
"deep-extend": "0.4.1",
"expect": "1.20.2",
@@ -67,17 +68,17 @@
"react-motion": "0.4.4",
"react-object-inspector": "0.2.1",
"react-redux": "^4.x.x",
"react-remarkable": "1.1.1",
"react-split-pane": "0.1.57",
"redux": "^3.x.x",
"redux-immutable": "3.0.8",
"redux-logger": "*",
"remarkable": "^1.7.1",
"reselect": "2.5.3",
"sanitize-html": "^1.14.1",
"scroll-to-element": "^2.0.0",
"serialize-error": "2.0.0",
"shallowequal": "0.2.2",
"swagger-client": "3.1.1",
"swagger-client": "^3.2.0",
"url-parse": "^1.1.8",
"whatwg-fetch": "0.11.1",
"worker-loader": "^0.7.1",
+12 -8
View File
@@ -16,10 +16,12 @@ export default class ArrayModel extends Component {
render(){
let { getComponent, schema, depth, expandDepth, name } = this.props
let description = schema.get("description")
let items = schema.get("items")
let title = schema.get("title") || name
let properties = schema.filter( ( v, key) => ["type", "items", "$$ref"].indexOf(key) === -1 )
let properties = schema.filter( ( v, key) => ["type", "items", "description", "$$ref"].indexOf(key) === -1 )
const Markdown = getComponent("Markdown")
const ModelCollapse = getComponent("ModelCollapse")
const Model = getComponent("Model")
@@ -36,15 +38,17 @@ export default class ArrayModel extends Component {
return <span className="model">
<ModelCollapse title={titleEl} collapsed={ depth > expandDepth } collapsedContent="[...]">
[
{
properties.size ? properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={ propStyle }>
<br />{ key }: { String(v) }</span>)
: null
}
{
!description ? null :
<Markdown source={ description } />
}
<span><Model { ...this.props } name={null} schema={ items } required={ false } depth={ depth + 1 } /></span>
]
{
properties.size ? <span>
{ properties.entrySeq().map( ( [ key, v ] ) => <span key={`${key}-${v}`} style={propStyle}>
<br />{ key }: { String(v) }</span>)
}<br /></span>
: null
}
</ModelCollapse>
</span>
}
+7
View File
@@ -61,6 +61,13 @@ export default class LiveResponse extends React.Component {
return (
<div>
{ curlRequest && <Curl request={ curlRequest }/> }
{ url && <div>
<h4>Request URL</h4>
<div className="request-url">
<pre>{url}</pre>
</div>
</div>
}
<h4>Server response</h4>
<table className="responses-table">
<thead>
+11 -5
View File
@@ -7,14 +7,19 @@ export default class ModelExample extends React.Component {
specSelectors: PropTypes.object.isRequired,
schema: PropTypes.object.isRequired,
example: PropTypes.any.isRequired,
isExecute: PropTypes.bool
isExecute: PropTypes.bool,
getConfigs: PropTypes.func.isRequired
}
constructor(props, context) {
super(props, context)
let { getConfigs } = this.props
let { defaultModelRendering } = getConfigs()
if (defaultModelRendering !== "example" && defaultModelRendering !== "model") {
defaultModelRendering = "example"
}
this.state = {
activeTab: "example"
activeTab: defaultModelRendering
}
}
@@ -27,7 +32,8 @@ export default class ModelExample extends React.Component {
}
render() {
let { getComponent, specSelectors, schema, example, isExecute } = this.props
let { getComponent, specSelectors, schema, example, isExecute, getConfigs } = this.props
let { defaultModelExpandDepth } = getConfigs()
const ModelWrapper = getComponent("ModelWrapper")
return <div>
@@ -47,7 +53,7 @@ export default class ModelExample extends React.Component {
!isExecute && this.state.activeTab === "model" && <ModelWrapper schema={ schema }
getComponent={ getComponent }
specSelectors={ specSelectors }
expandDepth={ 1 } />
expandDepth={ defaultModelExpandDepth } />
}
+2 -1
View File
@@ -13,7 +13,7 @@ export default class Models extends Component {
render(){
let { specSelectors, getComponent, layoutSelectors, layoutActions, getConfigs } = this.props
let definitions = specSelectors.definitions()
let { docExpansion } = getConfigs()
let { docExpansion, defaultModelExpandDepth } = getConfigs()
let showModels = layoutSelectors.isShown("models", docExpansion === "full" || docExpansion === "list" )
const ModelWrapper = getComponent("ModelWrapper")
@@ -33,6 +33,7 @@ export default class Models extends Component {
definitions.entrySeq().map( ( [ name, model ])=>{
return <div className="model-container" key={ `models-section-${name}` }>
<ModelWrapper name={ name }
expandDepth={ defaultModelExpandDepth }
schema={ model }
getComponent={ getComponent }
specSelectors={ specSelectors }/>
+2 -1
View File
@@ -149,7 +149,7 @@ export default class Operation extends PureComponent {
const isDeepLinkingEnabled = deepLinking && deepLinking !== "false"
// Merge in Live Response
if(response && response.size > 0) {
if(responses && response && response.size > 0) {
let notDocumented = !responses.get(String(response.get("status")))
response = response.set("notDocumented", notDocumented)
}
@@ -224,6 +224,7 @@ export default class Operation extends PureComponent {
specActions={ specActions }
specSelectors={ specSelectors }
pathMethod={ [path, method] }
getConfigs={ getConfigs }
/>
{!tryItOutEnabled || !allowTryItOut ? null : schemes && schemes.size ? <div className="opblock-schemes">
+2 -1
View File
@@ -36,6 +36,7 @@ export default class Operations extends React.Component {
const Operation = getComponent("operation")
const Collapse = getComponent("Collapse")
const Markdown = getComponent("Markdown")
let showSummary = layoutSelectors.showSummary()
let {
@@ -89,7 +90,7 @@ export default class Operations extends React.Component {
</a>
{ !tagDescription ? null :
<small>
{ tagDescription }
<Markdown source={tagDescription} />
</small>
}
+2 -2
View File
@@ -47,7 +47,7 @@ export default class ParamBody extends PureComponent {
updateValues = (props) => {
let { specSelectors, pathMethod, param, isExecute, consumesValue="" } = props
let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : {}
let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) : {}
let isXml = /xml/i.test(consumesValue)
let isJson = /json/i.test(consumesValue)
let paramValue = isXml ? parameter.get("value_xml") : parameter.get("value")
@@ -107,7 +107,7 @@ export default class ParamBody extends PureComponent {
const HighlightCode = getComponent("highlightCode")
const ContentType = getComponent("contentType")
// for domains where specSelectors not passed
let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name")) : param
let parameter = specSelectors ? specSelectors.getParameter(pathMethod, param.get("name"), param.get("in")) : param
let errors = parameter.get("errors", List())
let consumesValue = specSelectors.contentTypeValues(pathMethod).get("requestContentType")
let consumes = this.props.consumes && this.props.consumes.size ? this.props.consumes : ParamBody.defaultProp.consumes
+7 -5
View File
@@ -11,7 +11,8 @@ export default class ParameterRow extends Component {
isExecute: PropTypes.bool,
onChangeConsumes: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired
pathMethod: PropTypes.array.isRequired,
getConfigs: PropTypes.func.isRequired
}
constructor(props, context) {
@@ -19,7 +20,7 @@ export default class ParameterRow extends Component {
let { specSelectors, pathMethod, param } = props
let defaultValue = param.get("default")
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in"))
let value = parameter ? parameter.get("value") : ""
if ( defaultValue !== undefined && value === undefined ) {
this.onChangeWrapper(defaultValue)
@@ -30,7 +31,7 @@ export default class ParameterRow extends Component {
let { specSelectors, pathMethod, param } = props
let example = param.get("example")
let defaultValue = param.get("default")
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in"))
let paramValue = parameter ? parameter.get("value") : undefined
let enumValue = parameter ? parameter.get("enum") : undefined
let value
@@ -56,7 +57,7 @@ export default class ParameterRow extends Component {
}
render() {
let {param, onChange, getComponent, isExecute, fn, onChangeConsumes, specSelectors, pathMethod} = this.props
let {param, onChange, getComponent, getConfigs, isExecute, fn, onChangeConsumes, specSelectors, pathMethod} = this.props
let { isOAS3 } = specSelectors
@@ -86,7 +87,7 @@ export default class ParameterRow extends Component {
let isFormDataSupported = "FormData" in win
let required = param.get("required")
let itemType = param.getIn(isOAS3 && isOAS3() ? ["schema", "items", "type"] : ["items", "type"])
let parameter = specSelectors.getParameter(pathMethod, param.get("name"))
let parameter = specSelectors.getParameter(pathMethod, param.get("name"), param.get("in"))
let value = parameter ? parameter.get("value") : ""
return (
@@ -120,6 +121,7 @@ export default class ParameterRow extends Component {
{
bodyParam && schema ? <ModelExample getComponent={ getComponent }
getConfigs={ getConfigs }
isExecute={ isExecute }
specSelectors={ specSelectors }
schema={ schema }
+6 -3
View File
@@ -19,7 +19,8 @@ export default class Parameters extends Component {
onTryoutClick: PropTypes.func,
onCancelClick: PropTypes.func,
onChangeKey: PropTypes.array,
pathMethod: PropTypes.array.isRequired
pathMethod: PropTypes.array.isRequired,
getConfigs: PropTypes.func.isRequired
}
@@ -37,7 +38,7 @@ export default class Parameters extends Component {
onChangeKey,
} = this.props
changeParam( onChangeKey, param.get("name"), value, isXml)
changeParam( onChangeKey, param.get("name"), param.get("in"), value, isXml)
}
onChangeConsumesWrapper = ( val ) => {
@@ -60,6 +61,7 @@ export default class Parameters extends Component {
fn,
getComponent,
getConfigs,
specSelectors,
pathMethod
} = this.props
@@ -93,8 +95,9 @@ export default class Parameters extends Component {
eachMap(parameters, (parameter) => (
<ParameterRow fn={ fn }
getComponent={ getComponent }
getConfigs={ getConfigs }
param={ parameter }
key={ parameter.get( "name" ) }
key={ `${parameter.get( "in" )}.${parameter.get("name")}` }
onChange={ this.onChange }
onChangeConsumes={this.onChangeConsumesWrapper}
specSelectors={ specSelectors }
+21 -18
View File
@@ -1,37 +1,40 @@
import React from "react"
import PropTypes from "prop-types"
import Remarkable from "react-remarkable"
import Remarkable from "remarkable"
import sanitize from "sanitize-html"
function Markdown({ source }) {
const sanitized = sanitizer(source)
const html = new Remarkable({
html: true,
typographer: true,
breaks: true,
linkify: true,
linkTarget: "_blank"
}).render(source)
const sanitized = sanitizer(html)
// sometimes the sanitizer returns "undefined" as a string
if(!source || !sanitized || sanitized === "undefined") {
return null
}
if ( !source || !html || !sanitized ) {
return null
}
return <div className="markdown">
<Remarkable
options={{html: true, typographer: true, breaks: true, linkify: true, linkTarget: "_blank"}}
source={sanitized}
></Remarkable>
</div>
return (
<div className="markdown" dangerouslySetInnerHTML={{ __html: sanitized }}></div>
)
}
Markdown.propTypes = {
source: PropTypes.string.isRequired
source: PropTypes.string.isRequired
}
export default Markdown
const sanitizeOptions = {
textFilter: function(text) {
return text
.replace(/&quot;/g, "\"")
}
allowedTags: sanitize.defaults.allowedTags.concat([ "img" ]),
textFilter: function(text) {
return text.replace(/&quot;/g, "\"")
}
}
export function sanitizer(str) {
return sanitize(str, sanitizeOptions)
return sanitize(str, sanitizeOptions)
}
+4 -4
View File
@@ -49,10 +49,10 @@ export default class ResponseBody extends React.Component {
// Download
} else if (
/^application\/octet-stream/i.test(contentType) ||
headers["Content-Disposition"] && (/attachment/i).test(headers["Content-Disposition"]) ||
headers["content-disposition"] && (/attachment/i).test(headers["content-disposition"]) ||
headers["Content-Description"] && (/File Transfer/i).test(headers["Content-Description"]) ||
headers["content-description"] && (/File Transfer/i).test(headers["content-description"])) {
(headers["Content-Disposition"] && (/attachment/i).test(headers["Content-Disposition"])) ||
(headers["content-disposition"] && (/attachment/i).test(headers["content-disposition"])) ||
(headers["Content-Description"] && (/File Transfer/i).test(headers["Content-Description"])) ||
(headers["content-description"] && (/File Transfer/i).test(headers["content-description"]))) {
let contentLength = headers["content-length"] || headers["Content-Length"]
if ( !(+contentLength) ) return null
+11
View File
@@ -45,6 +45,7 @@ export default class Response extends React.Component {
response: PropTypes.object,
className: PropTypes.string,
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
fn: PropTypes.object.isRequired,
contentType: PropTypes.string,
@@ -73,6 +74,7 @@ export default class Response extends React.Component {
className,
fn,
getComponent,
getConfigs,
specSelectors,
contentType,
controlsAcceptHeader
@@ -107,6 +109,14 @@ export default class Response extends React.Component {
includeWriteOnly: true // writeOnly has no filtering effect in swagger 2.0
}) : null
}
if(examples) {
examples = examples.map(example => {
// Remove unwanted properties from examples
return example.set ? example.set("$$ref", undefined) : example
})
}
let example = getExampleComponent( sampleResponse, examples, HighlightCode )
return (
@@ -136,6 +146,7 @@ export default class Response extends React.Component {
{ example ? (
<ModelExample
getComponent={ getComponent }
getConfigs={ getConfigs }
specSelectors={ specSelectors }
schema={ fromJSOrdered(schema) }
example={ example }/>
+3 -2
View File
@@ -12,13 +12,13 @@ export default class Responses extends React.Component {
produces: PropTypes.object,
producesValue: PropTypes.any,
getComponent: PropTypes.func.isRequired,
getConfigs: PropTypes.func.isRequired,
specSelectors: PropTypes.object.isRequired,
specActions: PropTypes.object.isRequired,
oas3Actions: PropTypes.object.isRequired,
pathMethod: PropTypes.array.isRequired,
displayRequestDuration: PropTypes.bool.isRequired,
fn: PropTypes.object.isRequired,
getConfigs: PropTypes.func.isRequired
fn: PropTypes.object.isRequired
}
static defaultProps = {
@@ -116,6 +116,7 @@ export default class Responses extends React.Component {
controlsAcceptHeader={response === acceptControllingResponse}
onContentTypeChange={this.onResponseContentTypeChange}
contentType={ producesValue }
getConfigs={ getConfigs }
getComponent={ getComponent }/>
)
}).toArray()
+2
View File
@@ -45,6 +45,8 @@ module.exports = function SwaggerUI(opts) {
requestInterceptor: (a => a),
responseInterceptor: (a => a),
showMutatedRequest: true,
defaultModelRendering: "example",
defaultModelExpandDepth: 1,
// Initial set of plugins ( TODO rename this, or refactor - we don't need presets _and_ plugins. Its just there for performance.
// Instead, we can compile the first plugin ( it can be a collection of plugins ), then batch the rest.
+2 -1
View File
@@ -64,7 +64,8 @@ export default function authorize ( { auth, authActions, errActions, configs, au
}
}
let url = [schema.get("authorizationUrl"), query.join("&")].join("?")
let authorizationUrl = schema.get("authorizationUrl")
let url = [authorizationUrl, query.join("&")].join(authorizationUrl.indexOf("?") === -1 ? "?" : "&")
// pass action authorizeOauth2 and authentication data through window
// to authorize with oauth2
@@ -0,0 +1,28 @@
import { createSelector } from "reselect"
import { isOAS3 as isOAS3Helper } from "../helpers"
// Helpers
function onlyOAS3(selector) {
return (ori, system) => (...args) => {
const spec = system.getSystem().specSelectors.specJson()
if(isOAS3Helper(spec)) {
return selector(...args)
} else {
return ori(...args)
}
}
}
const nullSelector = createSelector(() => null)
const OAS3NullSelector = onlyOAS3(nullSelector)
// Hasta la vista, authentication!
export const shownDefinitions = OAS3NullSelector
export const definitionsToAuthorize = OAS3NullSelector
export const getDefinitionsByNames = OAS3NullSelector
export const authorized = OAS3NullSelector
export const isAuthorized = OAS3NullSelector
export const getConfigs = OAS3NullSelector
+4
View File
@@ -1,6 +1,7 @@
// import reducers from "./reducers"
// import * as actions from "./actions"
import * as specWrapSelectors from "./spec-extensions/wrap-selectors"
import * as authWrapSelectors from "./auth-extensions/wrap-selectors"
import * as specSelectors from "./spec-extensions/selectors"
import components from "./components"
import wrapComponents from "./wrap-components"
@@ -17,6 +18,9 @@ export default function() {
wrapSelectors: specWrapSelectors,
selectors: specSelectors
},
auth: {
wrapSelectors: authWrapSelectors
},
oas3: {
actions: oas3Actions,
reducers: oas3Reducers,
@@ -53,6 +53,7 @@ export const basePath = OAS3NullSelector
export const consumes = OAS3NullSelector
export const produces = OAS3NullSelector
export const schemes = OAS3NullSelector
export const securityDefinitions = OAS3NullSelector
// New selectors
@@ -1,11 +1,26 @@
import React from "react"
import ReactMarkdown from "react-markdown"
import { Parser, HtmlRenderer } from "commonmark"
import { OAS3ComponentWrapFactory } from "../helpers"
import { sanitizer } from "core/components/providers/markdown"
export default OAS3ComponentWrapFactory(({ source }) => { return source ? (
<ReactMarkdown
source={sanitizer(source)}
className={"renderedMarkdown"}
/>
) : null})
export default OAS3ComponentWrapFactory(({ source }) => {
if ( source ) {
const parser = new Parser()
const writer = new HtmlRenderer()
const html = writer.render(parser.parse(source || ""))
const sanitized = sanitizer(html)
if ( !source || !html || !sanitized ) {
return null
}
return (
<ReactMarkdown
source={sanitized}
className={"renderedMarkdown"}
/>
)
}
return null
})
@@ -49,7 +49,7 @@ class Parameters extends Component {
onChangeKey,
} = this.props
changeParam( onChangeKey, param.get("name"), value, isXml)
changeParam( onChangeKey, param.get("name"), param.get("in"), value, isXml)
}
onChangeConsumesWrapper = ( val ) => {
+2 -3
View File
@@ -130,10 +130,10 @@ export const formatIntoYaml = () => ({specActions, specSelectors}) => {
}
}
export function changeParam( path, paramName, value, isXml ){
export function changeParam( path, paramName, paramIn, value, isXml ){
return {
type: UPDATE_PARAM,
payload:{ path, value, paramName, isXml }
payload:{ path, value, paramName, paramIn, isXml }
}
}
@@ -206,7 +206,6 @@ export const executeRequest = (req) =>
// if url is relative, parseUrl makes it absolute by inferring from `window.location`
req.contextUrl = parseUrl(specSelectors.url()).toString()
if(op && op.operationId) {
req.operationId = op.operationId
} else if(op && pathName && method) {
+3 -2
View File
@@ -40,9 +40,10 @@ export default {
},
[UPDATE_PARAM]: ( state, {payload} ) => {
let { path, paramName, value, isXml } = payload
let { path, paramName, paramIn, value, isXml } = payload
return state.updateIn( [ "resolved", "paths", ...path, "parameters" ], fromJS([]), parameters => {
const index = parameters.findIndex(p => p.get( "name" ) === paramName )
const index = parameters.findIndex(p => p.get( "name" ) === paramName && p.get("in") === paramIn )
if (!(value instanceof win.File)) {
value = fromJSOrdered( value )
}
+3 -3
View File
@@ -260,10 +260,10 @@ export const allowTryItOutFor = () => {
}
// Get the parameter value by parameter name
export function getParameter(state, pathMethod, name) {
export function getParameter(state, pathMethod, name, inType) {
let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([]))
return params.filter( (p) => {
return Map.isMap(p) && p.get("name") === name
return Map.isMap(p) && p.get("name") === name && p.get("in") === inType
}).first()
}
@@ -280,7 +280,7 @@ export function parameterValues(state, pathMethod, isXml) {
let params = spec(state).getIn(["paths", ...pathMethod, "parameters"], fromJS([]))
return params.reduce( (hash, p) => {
let value = isXml && p.get("in") === "body" ? p.get("value_xml") : p.get("value")
return hash.set(p.get("name"), value)
return hash.set(`${p.get("in")}.${p.get("name")}`, value)
}, fromJS({}))
}
+69 -1
View File
@@ -470,6 +470,18 @@ export const propChecker = (props, nextProps, objectList=[], ignoreList=[]) => {
|| objectList.some( objectPropName => !eq(props[objectPropName], nextProps[objectPropName])))
}
export const validateMaximum = ( val, max ) => {
if (val > max) {
return "Value must be less than Maximum"
}
}
export const validateMinimum = ( val, min ) => {
if (val < min) {
return "Value must be greater than Minimum"
}
}
export const validateNumber = ( val ) => {
if (!/^-?\d+(\.?\d+)?$/.test(val)) {
return "Value must be a number"
@@ -500,12 +512,41 @@ export const validateString = ( val ) => {
}
}
export const validateDateTime = (val) => {
if (isNaN(Date.parse(val))) {
return "Value must be a DateTime"
}
}
export const validateGuid = (val) => {
if (!/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}[)}]?$/.test(val)) {
return "Value must be a Guid"
}
}
export const validateMaxLength = (val, max) => {
if (val.length > max) {
return "Value must be less than MaxLength"
}
}
export const validateMinLength = (val, min) => {
if (val.length < min) {
return "Value must be greater than MinLength"
}
}
// validation of parameters before execute
export const validateParam = (param, isXml) => {
let errors = []
let value = isXml && param.get("in") === "body" ? param.get("value_xml") : param.get("value")
let required = param.get("required")
let maximum = param.get("maximum")
let minimum = param.get("minimum")
let type = param.get("type")
let format = param.get("format")
let maxLength = param.get("maxLength")
let minLength = param.get("minLength")
/*
If the parameter is required OR the parameter has a value (meaning optional, but filled in)
@@ -522,13 +563,40 @@ export const validateParam = (param, isXml) => {
let numberCheck = type === "number" && !validateNumber(value) // validateNumber returns undefined if the value is a number
let integerCheck = type === "integer" && !validateInteger(value) // validateInteger returns undefined if the value is an integer
if (maxLength || maxLength === 0) {
let err = validateMaxLength(value, maxLength)
if (err) errors.push(err)
}
if (minLength) {
let err = validateMinLength(value, minLength)
if (err) errors.push(err)
}
if ( required && !(stringCheck || arrayCheck || listCheck || fileCheck || booleanCheck || numberCheck || integerCheck) ) {
errors.push("Required field is not provided")
return errors
}
if (maximum || maximum === 0) {
let err = validateMaximum(value, maximum)
if (err) errors.push(err)
}
if (minimum || minimum === 0) {
let err = validateMinimum(value, minimum)
if (err) errors.push(err)
}
if ( type === "string" ) {
let err = validateString(value)
let err
if (format === "date-time") {
err = validateDateTime(value)
} else if (format === "uuid") {
err = validateGuid(value)
} else {
err = validateString(value)
}
if (!err) return errors
errors.push(err)
} else if ( type === "boolean" ) {
+3
View File
@@ -252,8 +252,11 @@
font-size: 16px;
display: flex;
flex: 0 3 auto;
align-items: center;
word-break: break-all;
padding: 0 10px;
@include text_code();
+116
View File
@@ -0,0 +1,116 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import ModelExample from "components/model-example"
import ModelComponent from "components/model-wrapper"
describe("<ModelExample/>", function(){
// Given
let components = {
ModelWrapper: ModelComponent
}
let props = {
getComponent: (c) => {
return components[c]
},
specSelectors: {},
schema: {},
example: "{\"example\": \"value\"}",
isExecute: false,
getConfigs: () => ({
defaultModelRendering: "model",
defaultModelExpandDepth: 1
})
}
let exampleSelectedTestInputs = [
{ defaultModelRendering: "model", isExecute: true },
{ defaultModelRendering: "example", isExecute: true },
{ defaultModelRendering: "example", isExecute: false },
{ defaultModelRendering: "othervalue", isExecute: true },
{ defaultModelRendering: "othervalue", isExecute: false }
]
let modelSelectedTestInputs = [
{ defaultModelRendering: "model", isExecute: false }
]
it("renders model and example tabs", function(){
// When
let wrapper = shallow(<ModelExample {...props}/>)
// Then should render tabs
expect(wrapper.find("div > ul.tab").length).toEqual(1)
let tabs = wrapper.find("div > ul.tab").children()
expect(tabs.length).toEqual(2)
tabs.forEach((node) => {
expect(node.length).toEqual(1)
expect(node.name()).toEqual("li")
expect(node.hasClass("tabitem")).toEqual(true)
})
expect(tabs.at(0).text()).toEqual("Example Value")
expect(tabs.at(1).text()).toEqual("Model")
})
exampleSelectedTestInputs.forEach(function(testInputs) {
it("example tab is selected if isExecute = " + testInputs.isExecute + " and defaultModelRendering = " + testInputs.defaultModelRendering, function(){
// When
props.isExecute = testInputs.isExecute
props.getConfigs = () => ({
defaultModelRendering: testInputs.defaultModelRendering,
defaultModelExpandDepth: 1
})
let wrapper = shallow(<ModelExample {...props}/>)
// Then
let tabs = wrapper.find("div > ul.tab").children()
let exampleTab = tabs.at(0)
expect(exampleTab.hasClass("active")).toEqual(true)
let modelTab = tabs.at(1)
expect(modelTab.hasClass("active")).toEqual(false)
expect(wrapper.find("div > div").length).toEqual(1)
expect(wrapper.find("div > div").text()).toEqual(props.example)
})
})
modelSelectedTestInputs.forEach(function(testInputs) {
it("model tab is selected if isExecute = " + testInputs.isExecute + " and defaultModelRendering = " + testInputs.defaultModelRendering, function(){
// When
props.isExecute = testInputs.isExecute
props.getConfigs = () => ({
defaultModelRendering: testInputs.defaultModelRendering,
defaultModelExpandDepth: 1
})
let wrapper = shallow(<ModelExample {...props}/>)
// Then
let tabs = wrapper.find("div > ul.tab").children()
let exampleTab = tabs.at(0)
expect(exampleTab.hasClass("active")).toEqual(false)
let modelTab = tabs.at(1)
expect(modelTab.hasClass("active")).toEqual(true)
expect(wrapper.find("div > div").length).toEqual(1)
expect(wrapper.find("div > div").find(ModelComponent).props().expandDepth).toBe(1)
})
})
it("passes defaultModelExpandDepth to ModelComponent", function(){
// When
let expandDepth = 0
props.isExecute = false
props.getConfigs = () => ({
defaultModelRendering: "model",
defaultModelExpandDepth: expandDepth
})
let wrapper = shallow(<ModelExample {...props}/>)
// Then
expect(wrapper.find("div > div").find(ModelComponent).props().expandDepth).toBe(expandDepth)
})
})
+51
View File
@@ -0,0 +1,51 @@
/* eslint-env mocha */
import React from "react"
import expect, { createSpy } from "expect"
import { shallow } from "enzyme"
import { fromJS } from "immutable"
import Models from "components/models"
import ModelCollpase from "components/model-collapse"
import ModelComponent from "components/model-wrapper"
describe("<Models/>", function(){
// Given
let components = {
Collapse: ModelCollpase,
ModelWrapper: ModelComponent
}
let props = {
getComponent: (c) => {
return components[c]
},
specSelectors: {
definitions: function() {
return fromJS({
def1: {},
def2: {}
})
}
},
layoutSelectors: {
isShown: createSpy()
},
layoutActions: {},
getConfigs: () => ({
docExpansion: "list",
defaultModelExpandDepth: 0
})
}
it("passes defaultModelExpandDepth to ModelWrapper", function(){
// When
let wrapper = shallow(<Models {...props}/>)
// Then should render tabs
expect(wrapper.find("ModelCollapse").length).toEqual(1)
expect(wrapper.find("ModelComponent").length).toBeGreaterThan(0)
wrapper.find("ModelComponent").forEach((modelWrapper) => {
expect(modelWrapper.props().expandDepth).toBe(0)
})
})
})
+39
View File
@@ -0,0 +1,39 @@
/* eslint-env mocha */
import expect, { createSpy } from "expect"
import { fromJS } from "immutable"
import win from "core/window"
import oauth2Authorize from "core/oauth2-authorize"
describe("oauth2", function () {
let mockSchema = {
flow: "accessCode",
authorizationUrl: "https://testAuthorizationUrl"
}
let authConfig = {
auth: { schema: { get: (key)=> mockSchema[key] } },
authActions: {},
errActions: {},
configs: { oauth2RedirectUrl: "" },
authConfigs: {}
}
describe("authorize redirect", function () {
it("should build authorize url", function() {
win.open = createSpy()
oauth2Authorize(authConfig)
expect(win.open.calls.length).toEqual(1)
expect(win.open.calls[0].arguments[0]).toMatch("https://testAuthorizationUrl?response_type=code&redirect_uri=&state=")
})
it("should append query paramters to authorizeUrl with query parameters", function() {
win.open = createSpy()
mockSchema.authorizationUrl = "https://testAuthorizationUrl?param=1"
oauth2Authorize(authConfig)
expect(win.open.calls.length).toEqual(1)
expect(win.open.calls[0].arguments[0]).toMatch("https://testAuthorizationUrl?param=1&response_type=code&redirect_uri=&state=")
})
})
})
+4 -4
View File
@@ -29,8 +29,8 @@ describe("spec plugin - selectors", function(){
"/one": {
get: {
parameters: [
{ name: "one", value: 1},
{ name: "two", value: "duos"}
{ name: "one", in: "query", value: 1},
{ name: "two", in: "query", value: "duos"}
]
}
}
@@ -43,8 +43,8 @@ describe("spec plugin - selectors", function(){
// Then
expect(paramValues.toJS()).toEqual({
one: 1,
two: "duos"
"query.one": 1,
"query.two": "duos"
})
})
+184 -5
View File
@@ -1,7 +1,23 @@
/* eslint-env mocha */
import expect from "expect"
import { fromJS, OrderedMap } from "immutable"
import { mapToList, validateNumber, validateInteger, validateParam, validateFile, fromJSOrdered, getAcceptControllingResponse, createDeepLinkPath, escapeDeepLinkPath } from "core/utils"
import {
mapToList,
validateMinLength,
validateMaxLength,
validateDateTime,
validateGuid,
validateNumber,
validateInteger,
validateParam,
validateFile,
validateMaximum,
validateMinimum,
fromJSOrdered,
getAcceptControllingResponse,
createDeepLinkPath,
escapeDeepLinkPath
} from "core/utils"
import win from "core/window"
describe("utils", function() {
@@ -72,6 +88,36 @@ describe("utils", function() {
})
describe("validateMaximum", function() {
let errorMessage = "Value must be less than Maximum"
it("doesn't return for valid input", function() {
expect(validateMaximum(9, 10)).toBeFalsy()
expect(validateMaximum(19, 20)).toBeFalsy()
})
it("returns a message for invalid input", function() {
expect(validateMaximum(1, 0)).toEqual(errorMessage)
expect(validateMaximum(10, 9)).toEqual(errorMessage)
expect(validateMaximum(20, 19)).toEqual(errorMessage)
})
})
describe("validateMinimum", function() {
let errorMessage = "Value must be greater than Minimum"
it("doesn't return for valid input", function() {
expect(validateMinimum(2, 1)).toBeFalsy()
expect(validateMinimum(20, 10)).toBeFalsy()
})
it("returns a message for invalid input", function() {
expect(validateMinimum(-1, 0)).toEqual(errorMessage)
expect(validateMinimum(1, 2)).toEqual(errorMessage)
expect(validateMinimum(10, 20)).toEqual(errorMessage)
})
})
describe("validateNumber", function() {
let errorMessage = "Value must be a number"
@@ -158,7 +204,7 @@ describe("utils", function() {
})
})
describe("validateFile", function() {
describe("validateFile", function() {
let errorMessage = "Value must be a file"
it("validates against objects which are instances of 'File'", function() {
@@ -171,6 +217,62 @@ describe("utils", function() {
})
})
describe("validateDateTime", function() {
let errorMessage = "Value must be a DateTime"
it("doesn't return for valid dates", function() {
expect(validateDateTime("Mon, 25 Dec 1995 13:30:00 +0430")).toBeFalsy()
})
it("returns a message for invalid input'", function() {
expect(validateDateTime(null)).toEqual(errorMessage)
expect(validateDateTime("string")).toEqual(errorMessage)
})
})
describe("validateGuid", function() {
let errorMessage = "Value must be a Guid"
it("doesn't return for valid guid", function() {
expect(validateGuid("8ce4811e-cec5-4a29-891a-15d1917153c1")).toBeFalsy()
expect(validateGuid("{8ce4811e-cec5-4a29-891a-15d1917153c1}")).toBeFalsy()
})
it("returns a message for invalid input'", function() {
expect(validateGuid(1)).toEqual(errorMessage)
expect(validateGuid("string")).toEqual(errorMessage)
})
})
describe("validateMaxLength", function() {
let errorMessage = "Value must be less than MaxLength"
it("doesn't return for valid guid", function() {
expect(validateMaxLength("a", 1)).toBeFalsy()
expect(validateMaxLength("abc", 5)).toBeFalsy()
})
it("returns a message for invalid input'", function() {
expect(validateMaxLength("abc", 0)).toEqual(errorMessage)
expect(validateMaxLength("abc", 1)).toEqual(errorMessage)
expect(validateMaxLength("abc", 2)).toEqual(errorMessage)
})
})
describe("validateMinLength", function() {
let errorMessage = "Value must be greater than MinLength"
it("doesn't return for valid guid", function() {
expect(validateMinLength("a", 1)).toBeFalsy()
expect(validateMinLength("abc", 2)).toBeFalsy()
})
it("returns a message for invalid input'", function() {
expect(validateMinLength("abc", 5)).toEqual(errorMessage)
expect(validateMinLength("abc", 8)).toEqual(errorMessage)
})
})
describe("validateParam", function() {
let param = null
let result = null
@@ -196,7 +298,7 @@ describe("utils", function() {
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )
// valid string
// valid string
param = fromJS({
required: true,
type: "string",
@@ -204,6 +306,50 @@ describe("utils", function() {
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
// valid string with min and max length
param = fromJS({
required: true,
type: "string",
value: "test string",
maxLength: 50,
minLength: 1
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
})
it("validates required strings with min and max length", function() {
// invalid string with max length
param = fromJS({
required: true,
type: "string",
value: "test string",
maxLength: 5
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be less than MaxLength"] )
// invalid string with max length 0
param = fromJS({
required: true,
type: "string",
value: "test string",
maxLength: 0
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be less than MaxLength"] )
// invalid string with min length
param = fromJS({
required: true,
type: "string",
value: "test string",
minLength: 50
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be greater than MinLength"] )
})
it("validates optional strings", function() {
@@ -458,14 +604,47 @@ describe("utils", function() {
result = validateParam( param, false )
expect( result ).toEqual( ["Required field is not provided"] )
// valid number
// valid number with min and max
param = fromJS({
required: true,
type: "number",
value: 10
value: 10,
minimum: 5,
maximum: 99
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
// valid negative number with min and max
param = fromJS({
required: true,
type: "number",
value: -10,
minimum: -50,
maximum: -5
})
result = validateParam( param, false )
expect( result ).toEqual( [] )
// invalid number with maximum:0
param = fromJS({
required: true,
type: "number",
value: 1,
maximum: 0
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be less than Maximum"] )
// invalid number with minimum:0
param = fromJS({
required: true,
type: "number",
value: -10,
minimum: 0
})
result = validateParam( param, false )
expect( result ).toEqual( ["Value must be greater than Minimum"] )
})
it("validates optional numbers", function() {