aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/js/__tests__/components/FlowView
diff options
context:
space:
mode:
authorMatthew Shao <me@matshao.com>2017-05-31 16:04:28 +0800
committerMatthew Shao <me@matshao.com>2017-05-31 16:04:28 +0800
commite1c5f2a93e057c502ec557105b340f0db30fcb10 (patch)
tree4e92d2269a877c5caef9ec57c551d044356ad905 /web/src/js/__tests__/components/FlowView
parentd6e318b41dfb8c9e1306eacf91e9b952c8f82171 (diff)
downloadmitmproxy-e1c5f2a93e057c502ec557105b340f0db30fcb10.tar.gz
mitmproxy-e1c5f2a93e057c502ec557105b340f0db30fcb10.tar.bz2
mitmproxy-e1c5f2a93e057c502ec557105b340f0db30fcb10.zip
[web] Add tests for js/components/FlowView/Messages.jsx
Diffstat (limited to 'web/src/js/__tests__/components/FlowView')
-rw-r--r--web/src/js/__tests__/components/FlowView/MessagesSpec.js150
-rw-r--r--web/src/js/__tests__/components/FlowView/__snapshots__/MessagesSpec.js.snap568
2 files changed, 718 insertions, 0 deletions
diff --git a/web/src/js/__tests__/components/FlowView/MessagesSpec.js b/web/src/js/__tests__/components/FlowView/MessagesSpec.js
new file mode 100644
index 00000000..e59149d6
--- /dev/null
+++ b/web/src/js/__tests__/components/FlowView/MessagesSpec.js
@@ -0,0 +1,150 @@
+import React from 'react'
+import renderer from 'react-test-renderer'
+import TestUtils from 'react-dom/test-utils'
+import { Request, Response, ErrorView } from '../../../components/FlowView/Messages'
+import { Provider } from 'react-redux'
+import { TFlow, TStore } from '../../ducks/tutils'
+import { updateEdit } from '../../../ducks/ui/flow'
+import { parseUrl } from '../../../flow/utils'
+import ContentView from '../../../components/ContentView'
+import ContentViewOptions from '../../../components/ContentView/ContentViewOptions'
+import Headers from '../../../components/FlowView/Headers'
+import ValueEditor from '../../../components/ValueEditor/ValueEditor'
+import mockXMLHttpRequest from 'mock-xmlhttprequest'
+
+global.XMLHttpRequest = mockXMLHttpRequest
+global.fetch = jest.fn()
+
+let tflow = new TFlow(),
+ store = TStore()
+store.getState().ui.flow.modifiedFlow = false
+
+mockXMLHttpRequest.onSend = xhr => {
+ let response = {result: 'success'},
+ responseHeaders = {'Content-Type': 'application/json'}
+ xhr.respond(200, responseHeaders, JSON.stringify(response))
+}
+
+describe('Request Component', () => {
+
+ afterEach(() => {store.clearActions()})
+
+ it('should render correctly', () => {
+ let provider = renderer.create(
+ <Provider store={store}>
+ <Request/>
+ </Provider>
+ ),
+ tree = provider.toJSON()
+ expect(tree).toMatchSnapshot()
+ })
+
+ let provider = TestUtils.renderIntoDocument(
+ <Provider store={store}>
+ <Request/>
+ </Provider>),
+ valueEditors = TestUtils.scryRenderedComponentsWithType(provider, ValueEditor)
+
+ it('should handle done on flow request method', () => {
+ let valueEditor = valueEditors[0]
+ valueEditor.props.onDone('foo')
+ expect(store.getActions()).toEqual([updateEdit({ request: { method: 'foo' }})])
+ })
+
+ it('should handle done on flow request url', () => {
+ let valueEditor = valueEditors[1],
+ url = 'http://foo/bar'
+ valueEditor.props.onDone(url)
+ expect(store.getActions()).toEqual([updateEdit({ request: { path: '', ...parseUrl(url)}})])
+ })
+
+ it('should handle done on flow request http version', () => {
+ let valueEditor = valueEditors[2]
+ valueEditor.props.onDone('HTTP/9.9')
+ expect(store.getActions()).toEqual([updateEdit({ request: { http_version: 'HTTP/9.9' }})])
+ })
+
+ it('should handle change on flow request header', () => {
+ let headers = TestUtils.findRenderedComponentWithType(provider, Headers)
+ headers.props.onChange('foo')
+ expect(store.getActions()).toEqual([updateEdit({ request: { headers: 'foo' }})])
+ })
+
+ it('should handle change on flow request contentView', () => {
+ let contentView = TestUtils.findRenderedComponentWithType(provider, ContentView)
+ contentView.props.onContentChange('foo')
+ expect(store.getActions()).toEqual([updateEdit({ request: { content: 'foo' }})])
+ })
+
+ it('should handle uploadContent on flow request ContentViewOptions', () => {
+ let contentViewOptions = TestUtils.findRenderedComponentWithType(provider, ContentViewOptions)
+ contentViewOptions.props.uploadContent('foo')
+ expect(fetch).toBeCalled()
+ fetch.mockClear()
+ })
+})
+
+describe('Response Component', () => {
+ afterEach(() => {store.clearActions()})
+
+ it('should render correctly', () => {
+ let provider = renderer.create(
+ <Provider store={store}>
+ <Response/>
+ </Provider>
+ ),
+ tree = provider.toJSON()
+ expect(tree).toMatchSnapshot()
+ })
+
+ let provider = TestUtils.renderIntoDocument(
+ <Provider store={store}>
+ <Response/>
+ </Provider>),
+ valueEditors = TestUtils.scryRenderedComponentsWithType(provider, ValueEditor)
+
+ it('should handle done on flow response http version', () => {
+ let valueEditor = valueEditors[0]
+ valueEditor.props.onDone('HTTP/9.9')
+ expect(store.getActions()).toEqual([updateEdit({ response: { http_version: 'HTTP/9.9' }})])
+ })
+
+ it('should handle done on flow response status code', () => {
+ let valueEditor = valueEditors[1]
+ valueEditor.props.onDone('404')
+ expect(store.getActions()).toEqual([updateEdit({ response: { code: parseInt('404') }})])
+ })
+
+ it('should handle done on flow response reason', () => {
+ let valueEdiotr = valueEditors[2]
+ valueEdiotr.props.onDone('foo')
+ expect(store.getActions()).toEqual([updateEdit( { response: { msg: 'foo' }})])
+ })
+
+ it('should handle change on flow response headers', () => {
+ let headers = TestUtils.findRenderedComponentWithType(provider, Headers)
+ headers.props.onChange('foo')
+ expect(store.getActions()).toEqual([updateEdit( { response: { headers: 'foo' }})])
+ })
+
+ it('should handle change on flow response ContentView', () => {
+ let contentView = TestUtils.findRenderedComponentWithType(provider, ContentView)
+ contentView.props.onContentChange('foo')
+ expect(store.getActions()).toEqual([updateEdit( { response: { content: 'foo' }})])
+ })
+
+ it('should handle updateContent on flow response ContentViewOptions', () => {
+ let contentViewOptions = TestUtils.findRenderedComponentWithType(provider, ContentViewOptions)
+ contentViewOptions.props.uploadContent('foo')
+ expect(fetch).toBeCalled()
+ fetch.mockClear()
+ })
+})
+
+describe('Error Component', () => {
+ it('should render correctly', () => {
+ let errorView = renderer.create(<ErrorView flow={tflow}/>),
+ tree = errorView.toJSON()
+ expect(tree).toMatchSnapshot()
+ })
+})
diff --git a/web/src/js/__tests__/components/FlowView/__snapshots__/MessagesSpec.js.snap b/web/src/js/__tests__/components/FlowView/__snapshots__/MessagesSpec.js.snap
new file mode 100644
index 00000000..9bbdf8e9
--- /dev/null
+++ b/web/src/js/__tests__/components/FlowView/__snapshots__/MessagesSpec.js.snap
@@ -0,0 +1,568 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Error Component should render correctly 1`] = `
+<section
+ className="error"
+>
+ <div
+ className="alert alert-warning"
+ >
+ error
+ <div>
+ <small>
+ 2017-05-21 12:38:32.481
+ </small>
+ </div>
+ </div>
+</section>
+`;
+
+exports[`Request Component should render correctly 1`] = `
+<section
+ className="request"
+>
+ <article>
+ <div
+ className="edit-flow-container"
+ >
+ <a
+ className="edit-flow"
+ onClick={[Function]}
+ title="Edit Flow"
+ >
+ <i
+ className="fa fa-pencil"
+ />
+ </a>
+ </div>
+ <div
+ className="first-line request-line"
+ >
+ <div>
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "GET",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+  
+ <div
+ className="inline-input readonly has-success"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "http://address:22/path",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+  
+ <div
+ className="inline-input readonly has-success"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "HTTP/1.1",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ </div>
+ </div>
+ <table
+ className="header-table"
+ >
+ <tbody>
+ <tr>
+ <td
+ className="header-name"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "header",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ <span
+ className="header-colon"
+ >
+ :
+ </span>
+ </td>
+ <td
+ className="header-value"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "qvalue",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ </td>
+ </tr>
+ <tr>
+ <td
+ className="header-name"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "content-length",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ <span
+ className="header-colon"
+ >
+ :
+ </span>
+ </td>
+ <td
+ className="header-value"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "7",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <hr />
+ <div
+ className="contentview"
+ >
+ <div
+ className="text-center"
+ >
+ <i
+ className="fa fa-spinner fa-spin"
+ />
+ </div>
+ </div>
+ </article>
+ <footer>
+ <div
+ className="view-options"
+ >
+ <div
+ className="dropup pull-left"
+ >
+ <a
+ className="btn btn-default btn-xs"
+ href="#"
+ onClick={[Function]}
+ >
+ <span>
+
+ <b>
+ View:
+ </b>
+
+ auto
+
+ <span
+ className="caret"
+ />
+
+ </span>
+ </a>
+ <ul
+ className="dropdown-menu"
+ role="menu"
+ >
+ <li>
+
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ auto
+ </a>
+
+ </li>
+ <li>
+
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ raw
+ </a>
+
+ </li>
+ <li>
+
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ text
+ </a>
+
+ </li>
+ </ul>
+ </div>
+  
+ <a
+ className="btn btn-default btn-xs"
+ href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/request/content"
+ title="Download the content of the flow."
+ >
+ <i
+ className="fa fa-download"
+ />
+ </a>
+  
+  
+ <span>
+ foo
+ </span>
+ </div>
+ </footer>
+</section>
+`;
+
+exports[`Response Component should render correctly 1`] = `
+<section
+ className="response"
+>
+ <article>
+ <div
+ className="edit-flow-container"
+ >
+ <a
+ className="edit-flow"
+ onClick={[Function]}
+ title="Edit Flow"
+ >
+ <i
+ className="fa fa-pencil"
+ />
+ </a>
+ </div>
+ <div
+ className="first-line response-line"
+ >
+ <div
+ className="inline-input readonly has-success"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "HTTP/1.1",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+  
+ <div
+ className="inline-input readonly has-success"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "200",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+  
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "OK",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ </div>
+ <table
+ className="header-table"
+ >
+ <tbody>
+ <tr>
+ <td
+ className="header-name"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "header-response",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ <span
+ className="header-colon"
+ >
+ :
+ </span>
+ </td>
+ <td
+ className="header-value"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "svalue",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ </td>
+ </tr>
+ <tr>
+ <td
+ className="header-name"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "content-length",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ <span
+ className="header-colon"
+ >
+ :
+ </span>
+ </td>
+ <td
+ className="header-value"
+ >
+ <div
+ className="inline-input readonly"
+ contentEditable={undefined}
+ dangerouslySetInnerHTML={
+ Object {
+ "__html": "7",
+ }
+ }
+ onBlur={[Function]}
+ onClick={[Function]}
+ onFocus={[Function]}
+ onInput={[Function]}
+ onKeyDown={[Function]}
+ onMouseDown={[Function]}
+ onPaste={[Function]}
+ tabIndex={undefined}
+ />
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <hr />
+ <div
+ className="contentview"
+ >
+ <div
+ className="text-center"
+ >
+ <i
+ className="fa fa-spinner fa-spin"
+ />
+ </div>
+ </div>
+ </article>
+ <footer>
+ <div
+ className="view-options"
+ >
+ <div
+ className="dropup pull-left"
+ >
+ <a
+ className="btn btn-default btn-xs"
+ href="#"
+ onClick={[Function]}
+ >
+ <span>
+
+ <b>
+ View:
+ </b>
+
+ auto
+
+ <span
+ className="caret"
+ />
+
+ </span>
+ </a>
+ <ul
+ className="dropdown-menu"
+ role="menu"
+ >
+ <li>
+
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ auto
+ </a>
+
+ </li>
+ <li>
+
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ raw
+ </a>
+
+ </li>
+ <li>
+
+ <a
+ href="#"
+ onClick={[Function]}
+ >
+ text
+ </a>
+
+ </li>
+ </ul>
+ </div>
+  
+ <a
+ className="btn btn-default btn-xs"
+ href="/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content"
+ title="Download the content of the flow."
+ >
+ <i
+ className="fa fa-download"
+ />
+ </a>
+  
+  
+ <span>
+ foo
+ </span>
+ </div>
+ </footer>
+</section>
+`;