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

Ft/3832 add switches for disabling rendering of large payloads #9625

Open
wants to merge 3 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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 18 additions & 1 deletion docs/usage/configuration.md
Expand Up @@ -206,6 +206,15 @@ Parameter name | Docker variable | Description
Swagger UI has finished rendering a newly provided definition.
</td>
</tr>
<tr>
<td>
<a name="user-content-payload.render.sizeThreshold"></a><code>payload.render.sizeThreshold</code>
</td>
<td><em>Unavailable</em></td>
<td>The maximum size (in bytes) of a payload to render.
Any payload above this will not be rendered, but may be available for copy or download.
</td>
</tr>
<tr>
<td>
<a name="user-content-syntaxhighlight"></a><code>syntaxHighlight</code>
Expand All @@ -217,13 +226,21 @@ Parameter name | Docker variable | Description
</td>
</tr>
<tr>
<td><a name="user-content-syntaxhighlight.activate"></a><code>syntaxHighlight.activate</code>
<td><a name="user-content-syntaxhighlight.activated"></a><code>syntaxHighlight.activated</code>
</td>
<td><em>Unavailable</em></td>
<td><code>Boolean=true</code>. Whether syntax highlighting should be
activated or not.
</td>
</tr>
<tr>
<td><a name="user-content-syntaxhighlight.sizethreshold"></a><code>syntaxHighlight.sizeThreshold</code>
</td>
<td><em>Unavailable</em></td>
<td>The maximum size (in bytes) of a payload to syntax highlight.
Any payload above this will not be syntax highlighted. Use this to avoid long delays caused by larged payloads.
</td>
</tr>
<tr>
<td><a name="user-content-syntaxhighlight.theme"></a><code>syntaxHighlight.theme</code>
</td>
Expand Down
40 changes: 30 additions & 10 deletions src/core/components/highlight-code.jsx
Expand Up @@ -9,7 +9,9 @@ import { CopyToClipboard } from "react-copy-to-clipboard"

const HighlightCode = ({value, fileName = "response.txt", className, downloadable, getConfigs, canCopy, language}) => {
const config = isFunction(getConfigs) ? getConfigs() : null
const renderSizeThreshold = get(config, "payload.render.sizeThreshold")
const canSyntaxHighlight = get(config, "syntaxHighlight") !== false && get(config, "syntaxHighlight.activated", true)
const syntaxHighlightSizeThreshold = canSyntaxHighlight ? get(config, "syntaxHighlight.sizeThreshold", undefined) : undefined
const rootRef = useRef(null)

useEffect(() => {
Expand Down Expand Up @@ -43,8 +45,25 @@ const HighlightCode = ({value, fileName = "response.txt", className, downloadabl
}
}

const getRenderValues = () => {
if (renderSizeThreshold || syntaxHighlightSizeThreshold) {
const valueSizeInBytes = (new TextEncoder().encode(value)).byteLength
const shouldRenderValue = renderSizeThreshold ? valueSizeInBytes < renderSizeThreshold : true
const shouldSyntaxHighlight = syntaxHighlightSizeThreshold ? valueSizeInBytes < syntaxHighlightSizeThreshold : true
return [shouldRenderValue, shouldSyntaxHighlight, valueSizeInBytes]
}
return [true, true, undefined]
}
const [shouldRenderValue, shouldSyntaxHighlight, valueSizeInBytes] = getRenderValues()

return (
<div className="highlight-code" ref={rootRef}>
{!shouldRenderValue && (
<div className={cx(className, "microlight")}>
Value is too large ({valueSizeInBytes} bytes), rendering disabled.
</div>
)}

{canCopy && (
<div className="copy-to-clipboard">
<CopyToClipboard text={value}><button/></CopyToClipboard>
Expand All @@ -57,16 +76,17 @@ const HighlightCode = ({value, fileName = "response.txt", className, downloadabl
</button>
}

{canSyntaxHighlight
? <SyntaxHighlighter
language={language}
className={cx(className, "microlight")}
style={getStyle(get(config, "syntaxHighlight.theme", "agate"))}
>
{value}
</SyntaxHighlighter>
: <pre className={cx(className, "microlight")}>{value}</pre>
}
{shouldRenderValue && (
canSyntaxHighlight && shouldSyntaxHighlight
? <SyntaxHighlighter
language={language}
className={cx(className, "microlight")}
style={getStyle(get(config, "syntaxHighlight.theme", "agate"))}
>
{value}
</SyntaxHighlighter>
: <pre className={cx(className, "microlight")}>{value}</pre>
)}

</div>
)
Expand Down
63 changes: 59 additions & 4 deletions test/unit/components/highlight-code.jsx
Expand Up @@ -3,27 +3,82 @@ import expect from "expect"
import { shallow, mount } from "enzyme"
import HighlightCode from "core/components/highlight-code"

const fakeGetConfigs = () => ({syntaxHighlight: {activated: true, theme: "agate"}})
const defaultSyntaxHighlightConfig = {
activated: true,
theme: "agate"
}

const fakeGetConfigs = (
renderSizeThreshold = undefined,
syntaxHighlight = defaultSyntaxHighlightConfig) => (
{
payload: {
render: {
sizeThreshold: renderSizeThreshold,
}
},
syntaxHighlight: syntaxHighlight
})

describe("<HighlightCode />", () => {
it("should render a Download button if downloadable", () => {
const props = {downloadable: true, getConfigs: fakeGetConfigs }
const props = { downloadable: true, getConfigs: fakeGetConfigs }
const wrapper = shallow(<HighlightCode {...props} />)
expect(wrapper.find(".download-contents").length).toEqual(1)
})

it("should render a Copy To Clipboard button if copyable", () => {
const props = {canCopy: true, getConfigs: fakeGetConfigs }
const props = { canCopy: true, getConfigs: fakeGetConfigs }
const wrapper = shallow(<HighlightCode {...props} />)
expect(wrapper.find("CopyToClipboard").length).toEqual(1)
})

it("should render values in a preformatted element", () => {
const value = "test text"
const props = {value: value, getConfigs: fakeGetConfigs}
const syntaxHighlightConfig = {
activated: false
}
const props = { value: value, getConfigs: () => fakeGetConfigs(undefined, syntaxHighlightConfig) }
const wrapper = mount(<HighlightCode {...props} />)
const highlighterTag = wrapper.find("SyntaxHighlighter")
expect(highlighterTag.length).toEqual(0)

const preTag = wrapper.find("pre")
expect(preTag.length).toEqual(1)
expect(preTag.text()).toEqual(value)
})

it("should render values in a syntax highlighted element", () => {
const value = "test text"
const props = { value: value, getConfigs: fakeGetConfigs }
const wrapper = mount(<HighlightCode {...props} />)
const syntaxHighlighterTag = wrapper.find("SyntaxHighlighter")

expect(syntaxHighlighterTag.length).toEqual(1)
expect(syntaxHighlighterTag.text()).toEqual(value)
})

it("should not render values larger than threshold", () => {
const value = "aaaaaaaa" //8 bytes
const props = { value: value, getConfigs: () => fakeGetConfigs(7) }
const wrapper = mount(<HighlightCode {...props} />)
const infoTag = wrapper.find("div.microlight")

expect(infoTag.text()).toEqual("Value is too large (8 bytes), rendering disabled.")
})

it("should not highlight values larger larger than syntax highlight threshold", () => {
const value = "aaaaaaaa" //8 bytes
const syntaxHighlightConfig = {
defaultSyntaxHighlightConfig,
sizeThreshold: 8
}
const props = { value: value, getConfigs: () => fakeGetConfigs(undefined, syntaxHighlightConfig) }
const wrapper = mount(<HighlightCode {...props} />)
const highlighterTag = wrapper.find("SyntaxHighlighter")
expect(highlighterTag.length).toEqual(0)

const preTag = wrapper.find("pre")
expect(preTag.length).toEqual(1)
expect(preTag.text()).toEqual(value)
})
Expand Down