mirror of
https://github.com/Grasscutters/mitmproxy.git
synced 2024-11-22 07:08:10 +00:00
fix web tests
This commit is contained in:
parent
0585e690c4
commit
3ad4949c0e
@ -1,4 +1,5 @@
|
|||||||
import uuid
|
import uuid
|
||||||
|
from typing import Literal, Union
|
||||||
|
|
||||||
from mitmproxy import connection
|
from mitmproxy import connection
|
||||||
from mitmproxy import controller
|
from mitmproxy import controller
|
||||||
@ -66,14 +67,8 @@ def twebsocketflow(messages=True, err=None, close_code=None, close_reason='') ->
|
|||||||
timestamp_start=946681202,
|
timestamp_start=946681202,
|
||||||
timestamp_end=946681203,
|
timestamp_end=946681203,
|
||||||
)
|
)
|
||||||
flow.websocket = websocket.WebSocketData()
|
|
||||||
|
|
||||||
if messages is True:
|
flow.websocket = twebsocket()
|
||||||
flow.websocket.messages = [
|
|
||||||
websocket.WebSocketMessage(Opcode.BINARY, True, b"hello binary", 946681203),
|
|
||||||
websocket.WebSocketMessage(Opcode.TEXT, True, b"hello text", 946681204),
|
|
||||||
websocket.WebSocketMessage(Opcode.TEXT, False, b"it's me", 946681205),
|
|
||||||
]
|
|
||||||
|
|
||||||
flow.websocket.close_reason = close_reason
|
flow.websocket.close_reason = close_reason
|
||||||
|
|
||||||
@ -91,15 +86,15 @@ def twebsocketflow(messages=True, err=None, close_code=None, close_reason='') ->
|
|||||||
return flow
|
return flow
|
||||||
|
|
||||||
|
|
||||||
def tflow(client_conn=True, server_conn=True, req=True, resp=None, err=None) -> http.HTTPFlow:
|
def tflow(
|
||||||
"""
|
client_conn: Union[Literal[True], None, connection.Client] = True,
|
||||||
@type client_conn: bool | None | mitmproxy.proxy.connection.ClientConnection
|
server_conn: Union[Literal[True], None, connection.Server] = True,
|
||||||
@type server_conn: bool | None | mitmproxy.proxy.connection.ServerConnection
|
req: Union[Literal[True], None, http.Request] = True,
|
||||||
@type req: bool | None | mitmproxy.proxy.protocol.http.Request
|
resp: Union[Literal[True], None, http.Response] = None,
|
||||||
@type resp: bool | None | mitmproxy.proxy.protocol.http.Response
|
err: Union[Literal[True], None, flow.Error] = None,
|
||||||
@type err: bool | None | mitmproxy.proxy.protocol.primitives.Error
|
ws: Union[Literal[True], None, websocket.WebSocketData] = None,
|
||||||
@return: mitmproxy.proxy.protocol.http.HTTPFlow
|
) -> http.HTTPFlow:
|
||||||
"""
|
"""Create a flow for testing."""
|
||||||
if client_conn is True:
|
if client_conn is True:
|
||||||
client_conn = tclient_conn()
|
client_conn = tclient_conn()
|
||||||
if server_conn is True:
|
if server_conn is True:
|
||||||
@ -110,11 +105,14 @@ def tflow(client_conn=True, server_conn=True, req=True, resp=None, err=None) ->
|
|||||||
resp = tresp()
|
resp = tresp()
|
||||||
if err is True:
|
if err is True:
|
||||||
err = terr()
|
err = terr()
|
||||||
|
if ws is True:
|
||||||
|
ws = twebsocket()
|
||||||
|
|
||||||
f = http.HTTPFlow(client_conn, server_conn)
|
f = http.HTTPFlow(client_conn, server_conn)
|
||||||
f.request = req
|
f.request = req
|
||||||
f.response = resp
|
f.response = resp
|
||||||
f.error = err
|
f.error = err
|
||||||
|
f.websocket = ws
|
||||||
f.reply = controller.DummyReply()
|
f.reply = controller.DummyReply()
|
||||||
return f
|
return f
|
||||||
|
|
||||||
@ -197,3 +195,20 @@ def tserver_conn() -> connection.Server:
|
|||||||
def terr(content: str = "error") -> flow.Error:
|
def terr(content: str = "error") -> flow.Error:
|
||||||
err = flow.Error(content, 946681207)
|
err = flow.Error(content, 946681207)
|
||||||
return err
|
return err
|
||||||
|
|
||||||
|
|
||||||
|
def twebsocket(messages: bool = True) -> websocket.WebSocketData:
|
||||||
|
ws = websocket.WebSocketData()
|
||||||
|
|
||||||
|
if messages:
|
||||||
|
ws.messages = [
|
||||||
|
websocket.WebSocketMessage(Opcode.BINARY, True, b"hello binary", 946681203),
|
||||||
|
websocket.WebSocketMessage(Opcode.TEXT, True, b"hello text", 946681204),
|
||||||
|
websocket.WebSocketMessage(Opcode.TEXT, False, b"it's me", 946681205),
|
||||||
|
]
|
||||||
|
ws.close_reason = "Close Reason"
|
||||||
|
ws.close_code = 1000
|
||||||
|
ws.closed_by_client = False
|
||||||
|
ws.timestamp_end = 946681205
|
||||||
|
|
||||||
|
return ws
|
||||||
|
2
mitmproxy/tools/web/static/app.css
vendored
2
mitmproxy/tools/web/static/app.css
vendored
File diff suppressed because one or more lines are too long
103
mitmproxy/tools/web/static/app.js
vendored
103
mitmproxy/tools/web/static/app.js
vendored
File diff suppressed because one or more lines are too long
6
mitmproxy/tools/web/static/vendor.css
vendored
6
mitmproxy/tools/web/static/vendor.css
vendored
File diff suppressed because one or more lines are too long
@ -324,7 +324,7 @@ class TestApp(tornado.testing.AsyncHTTPTestCase):
|
|||||||
ws_client2.close()
|
ws_client2.close()
|
||||||
|
|
||||||
def test_generate_tflow_js(self):
|
def test_generate_tflow_js(self):
|
||||||
tf = tflow.tflow(resp=True, err=True)
|
tf = tflow.tflow(resp=True, err=True, ws=True)
|
||||||
tf.request.trailers = Headers(trailer="qvalue")
|
tf.request.trailers = Headers(trailer="qvalue")
|
||||||
tf.response.trailers = Headers(trailer="qvalue")
|
tf.response.trailers = Headers(trailer="qvalue")
|
||||||
|
|
||||||
@ -342,9 +342,9 @@ class TestApp(tornado.testing.AsyncHTTPTestCase):
|
|||||||
).replace(": null", ": undefined")
|
).replace(": null", ": undefined")
|
||||||
|
|
||||||
content = (
|
content = (
|
||||||
"/** Auto-generated by test_app.py:TestApp._test_generate_tflow_js */\n"
|
"/** Auto-generated by test_app.py:TestApp.test_generate_tflow_js */\n"
|
||||||
"import {HTTPFlow} from '../../flow';\n"
|
"import {HTTPFlow} from '../../flow';\n"
|
||||||
"export default function(): HTTPFlow {\n"
|
"export default function(): Required<HTTPFlow> {\n"
|
||||||
f" return {tflow_json}\n"
|
f" return {tflow_json}\n"
|
||||||
"}"
|
"}"
|
||||||
)
|
)
|
||||||
|
133
web/package-lock.json
generated
133
web/package-lock.json
generated
@ -2651,12 +2651,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"core-js": {
|
|
||||||
"version": "3.15.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/core-js/-/core-js-3.15.2.tgz",
|
|
||||||
"integrity": "sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"core-js-pure": {
|
"core-js-pure": {
|
||||||
"version": "3.15.0",
|
"version": "3.15.0",
|
||||||
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.0.tgz",
|
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.0.tgz",
|
||||||
@ -2669,6 +2663,15 @@
|
|||||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"cross-fetch": {
|
||||||
|
"version": "3.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.4.tgz",
|
||||||
|
"integrity": "sha512-1eAtFWdIubi6T4XPy6ei9iUFoKpUkIF971QLN8lIvvvwueI65+Nw5haMNKUwfJxabqlIIDODJKGrQ66gxC0PbQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"node-fetch": "2.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"cross-spawn": {
|
"cross-spawn": {
|
||||||
"version": "7.0.3",
|
"version": "7.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
|
||||||
@ -3521,52 +3524,6 @@
|
|||||||
"bser": "^2.0.0"
|
"bser": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fetch-mock": {
|
|
||||||
"version": "9.11.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-9.11.0.tgz",
|
|
||||||
"integrity": "sha512-PG1XUv+x7iag5p/iNHD4/jdpxL9FtVSqRMUQhPab4hVDt80T1MH5ehzVrL2IdXO9Q2iBggArFvPqjUbHFuI58Q==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"@babel/core": "^7.0.0",
|
|
||||||
"@babel/runtime": "^7.0.0",
|
|
||||||
"core-js": "^3.0.0",
|
|
||||||
"debug": "^4.1.1",
|
|
||||||
"glob-to-regexp": "^0.4.0",
|
|
||||||
"is-subset": "^0.1.1",
|
|
||||||
"lodash.isequal": "^4.5.0",
|
|
||||||
"path-to-regexp": "^2.2.1",
|
|
||||||
"querystring": "^0.2.0",
|
|
||||||
"whatwg-url": "^6.5.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"tr46": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"punycode": "^2.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"webidl-conversions": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"whatwg-url": {
|
|
||||||
"version": "6.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
|
|
||||||
"integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"lodash.sortby": "^4.7.0",
|
|
||||||
"tr46": "^1.0.1",
|
|
||||||
"webidl-conversions": "^4.0.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fill-range": {
|
"fill-range": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
|
||||||
@ -3864,12 +3821,6 @@
|
|||||||
"unique-stream": "^2.0.2"
|
"unique-stream": "^2.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"glob-to-regexp": {
|
|
||||||
"version": "0.4.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz",
|
|
||||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"glob-watcher": {
|
"glob-watcher": {
|
||||||
"version": "5.0.3",
|
"version": "5.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
|
||||||
@ -5191,12 +5142,6 @@
|
|||||||
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
|
"integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"is-subset": {
|
|
||||||
"version": "0.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz",
|
|
||||||
"integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"is-typedarray": {
|
"is-typedarray": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||||
@ -5535,6 +5480,16 @@
|
|||||||
"jest-util": "^27.0.2"
|
"jest-util": "^27.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"jest-fetch-mock": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/jest-fetch-mock/-/jest-fetch-mock-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-Ux1nWprtLrdrH4XwE7O7InRY6psIi3GOsqNESJgMJ+M5cv4A8Lh7SN9d2V2kKRZ8ebAfcd1LNyZguAOb6JiDqw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"cross-fetch": "^3.0.4",
|
||||||
|
"promise-polyfill": "^8.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"jest-get-type": {
|
"jest-get-type": {
|
||||||
"version": "27.0.1",
|
"version": "27.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.0.1.tgz",
|
||||||
@ -6313,12 +6268,6 @@
|
|||||||
"integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
|
"integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash.isequal": {
|
|
||||||
"version": "4.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
|
||||||
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"lodash.isobject": {
|
"lodash.isobject": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
|
||||||
@ -6331,7 +6280,8 @@
|
|||||||
"lodash.isplainobject": {
|
"lodash.isplainobject": {
|
||||||
"version": "4.0.6",
|
"version": "4.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
|
||||||
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs="
|
"integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash.keys": {
|
"lodash.keys": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
@ -6362,12 +6312,6 @@
|
|||||||
"integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
|
"integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"lodash.sortby": {
|
|
||||||
"version": "4.7.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
|
||||||
"integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"lodash.template": {
|
"lodash.template": {
|
||||||
"version": "4.5.0",
|
"version": "4.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
|
"resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz",
|
||||||
@ -6768,11 +6712,6 @@
|
|||||||
"minimist": "^1.2.5"
|
"minimist": "^1.2.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"mock-xmlhttprequest": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/mock-xmlhttprequest/-/mock-xmlhttprequest-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-iCP2jcd8WUrswkminVid7gL3PQ1hhD2UnfEV0dkQjdZmvLPS8mVhIooX1sooGF8/8RkVp4wwVI+wj7zo2S7seQ=="
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
@ -7294,12 +7233,6 @@
|
|||||||
"integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
|
"integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"path-to-regexp": {
|
|
||||||
"version": "2.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.4.0.tgz",
|
|
||||||
"integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"path-type": {
|
"path-type": {
|
||||||
"version": "1.1.0",
|
"version": "1.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
|
||||||
@ -7494,6 +7427,12 @@
|
|||||||
"asap": "~2.0.3"
|
"asap": "~2.0.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"promise-polyfill": {
|
||||||
|
"version": "8.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-8.2.0.tgz",
|
||||||
|
"integrity": "sha512-k/TC0mIcPVF6yHhUvwAp7cvL6I2fFV7TzF1DuGPI8mBh4QQazf36xCKEHKTZKRysEoTQoQdKyP25J8MPJp7j5g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"prompts": {
|
"prompts": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz",
|
||||||
@ -7578,12 +7517,6 @@
|
|||||||
"side-channel": "^1.0.4"
|
"side-channel": "^1.0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"querystring": {
|
|
||||||
"version": "0.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.1.tgz",
|
|
||||||
"integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"raw-body": {
|
"raw-body": {
|
||||||
"version": "1.1.7",
|
"version": "1.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-1.1.7.tgz",
|
||||||
@ -7621,7 +7554,8 @@
|
|||||||
"react-is": {
|
"react-is": {
|
||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
|
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"react-popper": {
|
"react-popper": {
|
||||||
"version": "2.2.5",
|
"version": "2.2.5",
|
||||||
@ -7682,6 +7616,7 @@
|
|||||||
"version": "16.14.1",
|
"version": "16.14.1",
|
||||||
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.14.1.tgz",
|
||||||
"integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==",
|
"integrity": "sha512-rkIMcQi01/+kxiTE9D3fdS959U1g7gs+/rborw++42m1O9FAQiNI/UNRZExVUoAOprn4umcXf+pFRou8i4zuBg==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"react-is": "^16.12.0 || ^17.0.0"
|
"react-is": "^16.12.0 || ^17.0.0"
|
||||||
@ -7691,6 +7626,7 @@
|
|||||||
"version": "17.0.2",
|
"version": "17.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-17.0.2.tgz",
|
||||||
"integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==",
|
"integrity": "sha512-yaQ9cB89c17PUb0x6UfWRs7kQCorVdHlutU1boVPEsB8IDZH6n9tHxMacc3y0JoXOJUsZb/t/Mb8FUWMKaM7iQ==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"object-assign": "^4.1.1",
|
"object-assign": "^4.1.1",
|
||||||
"react-is": "^17.0.2",
|
"react-is": "^17.0.2",
|
||||||
@ -7843,6 +7779,7 @@
|
|||||||
"version": "1.5.4",
|
"version": "1.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/redux-mock-store/-/redux-mock-store-1.5.4.tgz",
|
||||||
"integrity": "sha512-xmcA0O/tjCLXhh9Fuiq6pMrJCwFRaouA8436zcikdIpYWWCjU76CRk+i2bHx8EeiSiMGnB85/lZdU3wIJVXHTA==",
|
"integrity": "sha512-xmcA0O/tjCLXhh9Fuiq6pMrJCwFRaouA8436zcikdIpYWWCjU76CRk+i2bHx8EeiSiMGnB85/lZdU3wIJVXHTA==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"lodash.isplainobject": "^4.0.6"
|
"lodash.isplainobject": "^4.0.6"
|
||||||
}
|
}
|
||||||
@ -9212,6 +9149,12 @@
|
|||||||
"is-typedarray": "^1.0.0"
|
"is-typedarray": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "4.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz",
|
||||||
|
"integrity": "sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "2.8.29",
|
"version": "2.8.29",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
"verbose": true
|
"verbose": true
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "jest --coverage",
|
"test": "tsc --noEmit && jest --coverage",
|
||||||
"build": "gulp prod",
|
"build": "gulp prod",
|
||||||
"start": "gulp"
|
"start": "gulp"
|
||||||
},
|
},
|
||||||
@ -15,15 +15,12 @@
|
|||||||
"classnames": "^2.3.1",
|
"classnames": "^2.3.1",
|
||||||
"codemirror": "^5.62.0",
|
"codemirror": "^5.62.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"mock-xmlhttprequest": "^1.1.0",
|
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^17.0.2",
|
||||||
"react-popper": "^2.2.5",
|
"react-popper": "^2.2.5",
|
||||||
"react-redux": "^7.2.4",
|
"react-redux": "^7.2.4",
|
||||||
"react-test-renderer": "^17.0.2",
|
|
||||||
"redux": "^4.1.0",
|
"redux": "^4.1.0",
|
||||||
"redux-mock-store": "^1.5.4",
|
|
||||||
"redux-thunk": "^2.3.0",
|
"redux-thunk": "^2.3.0",
|
||||||
"shallowequal": "^1.1.0",
|
"shallowequal": "^1.1.0",
|
||||||
"stable": "^0.1.8"
|
"stable": "^0.1.8"
|
||||||
@ -34,7 +31,6 @@
|
|||||||
"@types/redux-mock-store": "^1.0.2",
|
"@types/redux-mock-store": "^1.0.2",
|
||||||
"esbuild": "^0.12.9",
|
"esbuild": "^0.12.9",
|
||||||
"esbuild-jest": "^0.5.0",
|
"esbuild-jest": "^0.5.0",
|
||||||
"fetch-mock": "^9.11.0",
|
|
||||||
"gulp": "^4.0.2",
|
"gulp": "^4.0.2",
|
||||||
"gulp-clean-css": "^4.3.0",
|
"gulp-clean-css": "^4.3.0",
|
||||||
"gulp-esbuild": "^0.8.2",
|
"gulp-esbuild": "^0.8.2",
|
||||||
@ -46,7 +42,10 @@
|
|||||||
"gulp-replace": "^1.1.3",
|
"gulp-replace": "^1.1.3",
|
||||||
"gulp-sourcemaps": "^3.0.0",
|
"gulp-sourcemaps": "^3.0.0",
|
||||||
"jest": "^27.0.4",
|
"jest": "^27.0.4",
|
||||||
"node-fetch": "^2.6.1",
|
"jest-fetch-mock": "^3.0.3",
|
||||||
"through2": "^4.0.2"
|
"react-test-renderer": "^17.0.2",
|
||||||
|
"redux-mock-store": "^1.5.4",
|
||||||
|
"through2": "^4.0.2",
|
||||||
|
"typescript": "^4.3.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
import * as React from "react"
|
import * as React from "react"
|
||||||
import CommandBar from '../../../components/CommandBar'
|
import CommandBar from '../../../components/CommandBar'
|
||||||
import { render } from "../../test-utils"
|
import {render} from "../../test-utils"
|
||||||
import fetchMock from 'fetch-mock';
|
import fetchMock, {enableFetchMocks} from "jest-fetch-mock";
|
||||||
import { act, waitFor } from '@testing-library/react'
|
import {waitFor} from '@testing-library/react'
|
||||||
|
|
||||||
|
enableFetchMocks()
|
||||||
|
|
||||||
|
|
||||||
test('CommandBar Component', async () => {
|
test('CommandBar Component', async () => {
|
||||||
fetchMock.get('./commands.json', {status: 200, body: {"commands": "foo"}})
|
fetchMock.mockResponseOnce(JSON.stringify({"commands": "foo"}));
|
||||||
|
|
||||||
const {asFragment, store} = render(
|
const {asFragment, store} = render(
|
||||||
<CommandBar/>
|
<CommandBar/>
|
||||||
|
26
web/src/js/__tests__/components/CommandBarSpec.tsx
Normal file
26
web/src/js/__tests__/components/CommandBarSpec.tsx
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import {render, waitFor, screen} from "../test-utils";
|
||||||
|
import CommandBar from "../../components/CommandBar";
|
||||||
|
import fetchMock, {enableFetchMocks} from "jest-fetch-mock";
|
||||||
|
|
||||||
|
enableFetchMocks();
|
||||||
|
|
||||||
|
test("CommandBar", async () => {
|
||||||
|
fetchMock.mockResponseOnce(JSON.stringify({
|
||||||
|
"flow.decode": {"help": "Decode flows.",
|
||||||
|
"parameters": [{"name": "flows", "type": "flow[]", "kind": "POSITIONAL_OR_KEYWORD"}, {
|
||||||
|
"name": "part",
|
||||||
|
"type": "str",
|
||||||
|
"kind": "POSITIONAL_OR_KEYWORD"
|
||||||
|
}],
|
||||||
|
"return_type": null,
|
||||||
|
"signature_help": "flow.decode flows part"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
));
|
||||||
|
|
||||||
|
const {asFragment} = render(<CommandBar/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
await waitFor(() => screen.getByText('["flow.decode"]'))
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
@ -1,14 +0,0 @@
|
|||||||
jest.mock("../../../contrib/CodeMirror")
|
|
||||||
import * as React from 'react';
|
|
||||||
import CodeEditor from '../../../components/ContentView/CodeEditor'
|
|
||||||
import {render} from '@testing-library/react'
|
|
||||||
|
|
||||||
|
|
||||||
test("CodeEditor", async () => {
|
|
||||||
|
|
||||||
const changeFn = jest.fn(),
|
|
||||||
{asFragment} = render(
|
|
||||||
<CodeEditor content="foo" onChange={changeFn}/>
|
|
||||||
);
|
|
||||||
expect(asFragment()).toMatchSnapshot()
|
|
||||||
});
|
|
@ -1,74 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import withContentLoader from '../../../components/contentviews/useContent'
|
|
||||||
import { TFlow } from '../../ducks/tutils'
|
|
||||||
import TestUtils from 'react-dom/test-utils'
|
|
||||||
import mockXMLHttpRequest from 'mock-xmlhttprequest'
|
|
||||||
|
|
||||||
global.XMLHttpRequest = mockXMLHttpRequest
|
|
||||||
class tComponent extends React.Component {
|
|
||||||
constructor(props, context){
|
|
||||||
super(props, context)
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return (<p>foo</p>)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let tflow = new TFlow(),
|
|
||||||
ContentLoader = withContentLoader(tComponent)
|
|
||||||
|
|
||||||
describe('ContentLoader Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let contentLoader = renderer.create(<ContentLoader flow={tflow} message={tflow.response}/>),
|
|
||||||
tree = contentLoader.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
let contentLoader = TestUtils.renderIntoDocument(<ContentLoader flow={tflow} message={tflow.response}/>)
|
|
||||||
|
|
||||||
it('should handle updateContent', () => {
|
|
||||||
tflow.response.content = 'foo'
|
|
||||||
contentLoader.updateContent({flow: tflow, message: tflow.response})
|
|
||||||
expect(contentLoader.state.request).toEqual(undefined)
|
|
||||||
expect(contentLoader.state.content).toEqual('foo')
|
|
||||||
// when content length is 0 or null
|
|
||||||
tflow.response.contentLength = 0
|
|
||||||
tflow.response.content = undefined
|
|
||||||
contentLoader.updateContent({flow: tflow, message: tflow.response})
|
|
||||||
expect(contentLoader.state.request).toEqual(undefined)
|
|
||||||
expect(contentLoader.state.content).toEqual('')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle componentWillReceiveProps', () => {
|
|
||||||
contentLoader.updateContent = jest.fn()
|
|
||||||
contentLoader.UNSAFE_componentWillReceiveProps({flow: tflow, message: tflow.request})
|
|
||||||
expect(contentLoader.updateContent).toBeCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle requestComplete', () => {
|
|
||||||
expect(contentLoader.requestComplete(tflow.request, {})).toEqual(undefined)
|
|
||||||
// request == this.state.request
|
|
||||||
contentLoader.state.request = tflow.request
|
|
||||||
contentLoader.requestComplete(tflow.request, {})
|
|
||||||
expect(contentLoader.state.content).toEqual(tflow.request.responseText)
|
|
||||||
expect(contentLoader.state.request).toEqual(undefined)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle requestFailed', () => {
|
|
||||||
console.error = jest.fn()
|
|
||||||
expect(contentLoader.requestFailed(tflow.request, {})).toEqual(undefined)
|
|
||||||
//request == this.state.request
|
|
||||||
contentLoader.state.request = tflow.request
|
|
||||||
contentLoader.requestFailed(tflow.request, 'foo error')
|
|
||||||
expect(contentLoader.state.content).toEqual('Error getting content.')
|
|
||||||
expect(contentLoader.state.request).toEqual(undefined)
|
|
||||||
expect(console.error).toBeCalledWith('foo error')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle componentWillUnmount', () => {
|
|
||||||
contentLoader.state.request = { abort : jest.fn() }
|
|
||||||
contentLoader.componentWillUnmount()
|
|
||||||
expect(contentLoader.state.request.abort).toBeCalled()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,20 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import ContentViewOptions from '../../../components/ContentView/ContentViewOptions'
|
|
||||||
import { Provider } from 'react-redux'
|
|
||||||
import { TFlow, TStore } from '../../ducks/tutils'
|
|
||||||
import { uploadContent } from '../../../ducks/flows'
|
|
||||||
|
|
||||||
let tflow = new TFlow()
|
|
||||||
|
|
||||||
describe('ContentViewOptions Component', () => {
|
|
||||||
let store = TStore()
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ContentViewOptions flow={tflow} message={tflow.response} uploadContent={uploadContent}/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,60 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import TestUtils from 'react-dom/test-utils'
|
|
||||||
import { Provider } from 'react-redux'
|
|
||||||
import { ViewServer, ViewImage, PureViewServer, Edit } from '../../../components/ContentView/ContentViews'
|
|
||||||
import { TFlow, TStore } from '../../ducks/tutils'
|
|
||||||
import mockXMLHttpRequest from 'mock-xmlhttprequest'
|
|
||||||
|
|
||||||
window.XMLHttpRequest = mockXMLHttpRequest
|
|
||||||
let tflow = new TFlow()
|
|
||||||
|
|
||||||
describe('ViewImage Component', () => {
|
|
||||||
let viewImage = renderer.create(<ViewImage flow={tflow} message={tflow.response}/>),
|
|
||||||
tree = viewImage.toJSON()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('ViewServer Component', () => {
|
|
||||||
let store = TStore()
|
|
||||||
|
|
||||||
it('should render correctly and connect to state', () => {
|
|
||||||
let provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ViewServer
|
|
||||||
flow={tflow}
|
|
||||||
message={tflow.response}
|
|
||||||
/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
|
|
||||||
let viewServer = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<PureViewServer
|
|
||||||
flow={tflow}
|
|
||||||
message={tflow.response}
|
|
||||||
content={JSON.stringify({lines: [['k1', 'v1']]})}
|
|
||||||
/>
|
|
||||||
</Provider>
|
|
||||||
)
|
|
||||||
tree = viewServer.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Edit Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let edit = renderer.create(<Edit
|
|
||||||
content="foo"
|
|
||||||
onChange={jest.fn}
|
|
||||||
flow={tflow}
|
|
||||||
message={tflow.response}
|
|
||||||
/>),
|
|
||||||
tree = edit.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,15 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import DownloadContentButton from '../../../components/ContentView/DownloadContentButton'
|
|
||||||
import { TFlow } from '../../ducks/tutils'
|
|
||||||
|
|
||||||
let tflow = new TFlow()
|
|
||||||
describe('DownloadContentButton Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let downloadContentButton = renderer.create(
|
|
||||||
<DownloadContentButton flow={tflow} message={tflow.response}/>
|
|
||||||
),
|
|
||||||
tree = downloadContentButton.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,37 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import { ContentEmpty, ContentMissing, ContentTooLarge } from '../../../components/ContentView/MetaViews'
|
|
||||||
import { TFlow } from '../../ducks/tutils'
|
|
||||||
|
|
||||||
let tflow = new TFlow()
|
|
||||||
|
|
||||||
describe('ContentEmpty Components', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let contentEmpty = renderer.create(<ContentEmpty flow={tflow} message={tflow.response}/>),
|
|
||||||
tree = contentEmpty.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('ContentMissing Components', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let contentMissing = renderer.create(<ContentMissing flow={tflow} message={tflow.response}/>),
|
|
||||||
tree = contentMissing.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('ContentTooLarge Components', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let clickFn = jest.fn(),
|
|
||||||
uploadContentFn = jest.fn(),
|
|
||||||
contentTooLarge = renderer.create(<ContentTooLarge
|
|
||||||
flow={tflow}
|
|
||||||
message={tflow.response}
|
|
||||||
onClick={clickFn}
|
|
||||||
uploadContent={uploadContentFn}
|
|
||||||
/>),
|
|
||||||
tree = contentTooLarge.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,22 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import { Provider } from 'react-redux'
|
|
||||||
import ShowFullContentButton from '../../../components/ContentView/ShowFullContentButton'
|
|
||||||
import { TStore } from '../../ducks/tutils'
|
|
||||||
|
|
||||||
|
|
||||||
describe('ShowFullContentButton Component', () => {
|
|
||||||
let store = TStore()
|
|
||||||
|
|
||||||
let setShowFullContentFn = jest.fn(),
|
|
||||||
showFullContentButton = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ShowFullContentButton />
|
|
||||||
</Provider>
|
|
||||||
),
|
|
||||||
tree = showFullContentButton.toJSON()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,12 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import UploadContentButton from '../../../components/ContentView/UploadContentButton'
|
|
||||||
|
|
||||||
describe('UpdateContentButton Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let uploadContentFn = jest.fn(),
|
|
||||||
uploadContentButton = renderer.create(<UploadContentButton uploadContent={uploadContentFn}/>),
|
|
||||||
tree = uploadContentButton.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,20 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import ViewSelector from '../../../components/ContentView/ViewSelector'
|
|
||||||
import { Provider } from 'react-redux'
|
|
||||||
import { TStore } from '../../ducks/tutils'
|
|
||||||
|
|
||||||
|
|
||||||
describe('ViewSelector Component', () => {
|
|
||||||
let store = TStore(),
|
|
||||||
viewSelector = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ViewSelector/>
|
|
||||||
</Provider>
|
|
||||||
),
|
|
||||||
tree = viewSelector.toJSON()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,11 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ContentLoader Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="text-center"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-spinner fa-spin"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,41 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ContentViewOptions Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="view-options"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<b>
|
|
||||||
View:
|
|
||||||
</b>
|
|
||||||
edit
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
|
|
||||||
title="Download the content of the flow."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-download"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="Upload a file to replace the content."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-upload"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
className="hidden"
|
|
||||||
onChange={[Function]}
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,39 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Edit Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="text-center"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-spinner fa-spin"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ViewImage Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="flowview-image"
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
alt="preview"
|
|
||||||
className="img-thumbnail"
|
|
||||||
src="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ViewServer Component should render correctly and connect to state 1`] = `
|
|
||||||
<div
|
|
||||||
className="text-center"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-spinner fa-spin"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ViewServer Component should render correctly and connect to state 2`] = `
|
|
||||||
<div>
|
|
||||||
<pre />
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,13 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`DownloadContentButton Component should render correctly 1`] = `
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
|
|
||||||
title="Download the content of the flow."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-download"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
`;
|
|
@ -1,66 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ContentEmpty Components should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="alert alert-info"
|
|
||||||
>
|
|
||||||
No
|
|
||||||
response
|
|
||||||
content.
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ContentMissing Components should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="alert alert-info"
|
|
||||||
>
|
|
||||||
Response
|
|
||||||
content missing.
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ContentTooLarge Components should render correctly 1`] = `
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
className="alert alert-warning"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="btn btn-xs btn-warning pull-right"
|
|
||||||
onClick={[MockFunction]}
|
|
||||||
>
|
|
||||||
Display anyway
|
|
||||||
</button>
|
|
||||||
7b
|
|
||||||
content size.
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="view-options text-center"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="Upload a file to replace the content."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-upload"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
className="hidden"
|
|
||||||
onChange={[Function]}
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
|
|
||||||
title="Download the content of the flow."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-download"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,3 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ShowFullContentButton Component should render correctly 1`] = `null`;
|
|
@ -1,19 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`UpdateContentButton Component should render correctly 1`] = `
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="Upload a file to replace the content."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-upload"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
className="hidden"
|
|
||||||
onChange={[Function]}
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
`;
|
|
@ -1,21 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ViewSelector Component should render correctly 1`] = `
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs pull-left"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<b>
|
|
||||||
View:
|
|
||||||
</b>
|
|
||||||
|
|
||||||
auto
|
|
||||||
|
|
||||||
<span
|
|
||||||
className="caret"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</a>
|
|
||||||
`;
|
|
@ -1,62 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import ContentView from '../../components/ContentView'
|
|
||||||
import { TStore, TFlow } from '../ducks/tutils'
|
|
||||||
import { Provider } from 'react-redux'
|
|
||||||
import mockXMLHttpRequest from 'mock-xmlhttprequest'
|
|
||||||
|
|
||||||
window.XMLHttpRequest = mockXMLHttpRequest
|
|
||||||
|
|
||||||
describe('ContentView Component', () => {
|
|
||||||
let store = TStore()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
store.getState().ui.flow.contentView = 'Edit'
|
|
||||||
let tflow = TFlow(),
|
|
||||||
provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ContentView flow={tflow} message={tflow.request}/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render correctly with empty content', () => {
|
|
||||||
let tflow = TFlow()
|
|
||||||
tflow.response.contentLength = 0
|
|
||||||
let provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ContentView flow={tflow} message={tflow.response} readonly={true}/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render correctly with missing content', () => {
|
|
||||||
let tflow = TFlow()
|
|
||||||
tflow.response.contentLength = null
|
|
||||||
let provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ContentView flow={tflow} message={tflow.response} readonly={true}/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render correctly with content too large', () => {
|
|
||||||
let tflow = TFlow()
|
|
||||||
tflow.response.contentLength = 1024 * 1024 * 100
|
|
||||||
let provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<ContentView
|
|
||||||
flow={tflow}
|
|
||||||
message={tflow.response}
|
|
||||||
readonly={true}
|
|
||||||
uploadContent={jest.fn()}
|
|
||||||
onOpenFile={jest.fn()}
|
|
||||||
/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,137 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import {
|
|
||||||
icon,
|
|
||||||
method,
|
|
||||||
path,
|
|
||||||
quickactions,
|
|
||||||
size,
|
|
||||||
status,
|
|
||||||
time,
|
|
||||||
timestamp,
|
|
||||||
tls
|
|
||||||
} from '../../../components/FlowTable/FlowColumns'
|
|
||||||
import {TFlow, TStore} from '../../ducks/tutils'
|
|
||||||
import {Provider} from 'react-redux'
|
|
||||||
|
|
||||||
describe('Flowcolumns Components', () => {
|
|
||||||
|
|
||||||
let tflow = TFlow()
|
|
||||||
it('should render TLSColumn', () => {
|
|
||||||
let tlsColumn = renderer.create(<tls flow={tflow}/>),
|
|
||||||
tree = tlsColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render IconColumn', () => {
|
|
||||||
let tflow = TFlow(),
|
|
||||||
iconColumn = renderer.create(<icon flow={tflow}/>),
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
// plain
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// not modified
|
|
||||||
tflow.response.status_code = 304
|
|
||||||
iconColumn = renderer.create(<icon flow={tflow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// redirect
|
|
||||||
tflow.response.status_code = 302
|
|
||||||
iconColumn = renderer.create(<icon flow={tflow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// image
|
|
||||||
let imageFlow = TFlow()
|
|
||||||
imageFlow.response.headers = [['Content-Type', 'image/jpeg']]
|
|
||||||
iconColumn = renderer.create(<icon flow={imageFlow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// javascript
|
|
||||||
let jsFlow = TFlow()
|
|
||||||
jsFlow.response.headers = [['Content-Type', 'application/x-javascript']]
|
|
||||||
iconColumn = renderer.create(<icon flow={jsFlow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// css
|
|
||||||
let cssFlow = TFlow()
|
|
||||||
cssFlow.response.headers = [['Content-Type', 'text/css']]
|
|
||||||
iconColumn = renderer.create(<icon flow={cssFlow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// html
|
|
||||||
let htmlFlow = TFlow()
|
|
||||||
htmlFlow.response.headers = [['Content-Type', 'text/html']]
|
|
||||||
iconColumn = renderer.create(<icon flow={htmlFlow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// default
|
|
||||||
let fooFlow = TFlow()
|
|
||||||
fooFlow.response.headers = [['Content-Type', 'foo']]
|
|
||||||
iconColumn = renderer.create(<icon flow={fooFlow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// no response
|
|
||||||
tflow.response = null
|
|
||||||
iconColumn = renderer.create(<icon flow={tflow}/>)
|
|
||||||
tree = iconColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render pathColumn', () => {
|
|
||||||
let tflow = TFlow(),
|
|
||||||
pathColumn = renderer.create(<path flow={tflow}/>),
|
|
||||||
tree = pathColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
|
|
||||||
tflow.error.msg = 'Connection killed.'
|
|
||||||
tflow.intercepted = true
|
|
||||||
pathColumn = renderer.create(<path flow={tflow}/>)
|
|
||||||
tree = pathColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render MethodColumn', () => {
|
|
||||||
let methodColumn = renderer.create(<method flow={tflow}/>),
|
|
||||||
tree = methodColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render StatusColumn', () => {
|
|
||||||
let statusColumn = renderer.create(<status flow={tflow}/>),
|
|
||||||
tree = statusColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render SizeColumn', () => {
|
|
||||||
let sizeColumn = renderer.create(<size flow={tflow}/>),
|
|
||||||
tree = sizeColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render TimeColumn', () => {
|
|
||||||
let tflow = TFlow(),
|
|
||||||
timeColumn = renderer.create(<time flow={tflow}/>),
|
|
||||||
tree = timeColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
|
|
||||||
tflow.response = null
|
|
||||||
timeColumn = renderer.create(<time flow={tflow}/>)
|
|
||||||
tree = timeColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render TimeStampColumn', () => {
|
|
||||||
let timeStampColumn = renderer.create(<timestamp flow={tflow}/>),
|
|
||||||
tree = timeStampColumn.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render QuickActionsColumn', () => {
|
|
||||||
let store = TStore(),
|
|
||||||
provider = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<quickactions flow={tflow}/>
|
|
||||||
</Provider>),
|
|
||||||
tree = provider.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
@ -0,0 +1,98 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import renderer from 'react-test-renderer'
|
||||||
|
import FlowColumns from '../../../components/FlowTable/FlowColumns'
|
||||||
|
import {TFlow} from '../../ducks/tutils'
|
||||||
|
import {render} from "../../test-utils";
|
||||||
|
|
||||||
|
test("should render columns", async () => {
|
||||||
|
const tflow = TFlow();
|
||||||
|
Object.entries(FlowColumns).forEach(([name, Col]) => {
|
||||||
|
const {asFragment} = render(<table>
|
||||||
|
<tbody>
|
||||||
|
<tr><Col flow={tflow}/></tr>
|
||||||
|
</tbody>
|
||||||
|
</table>)
|
||||||
|
expect(asFragment()).toMatchSnapshot(name);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('Flowcolumns Components', () => {
|
||||||
|
it('should render IconColumn', () => {
|
||||||
|
let tflow = {...TFlow(), websocket: undefined},
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={tflow}/>),
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
// plain
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// not modified
|
||||||
|
tflow.response.status_code = 304
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={tflow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// redirect
|
||||||
|
tflow.response.status_code = 302
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={tflow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// image
|
||||||
|
let imageFlow = {...TFlow(), websocket: undefined}
|
||||||
|
imageFlow.response.headers = [['Content-Type', 'image/jpeg']]
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={imageFlow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// javascript
|
||||||
|
let jsFlow = {...TFlow(), websocket: undefined}
|
||||||
|
jsFlow.response.headers = [['Content-Type', 'application/x-javascript']]
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={jsFlow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// css
|
||||||
|
let cssFlow = {...TFlow(), websocket: undefined}
|
||||||
|
cssFlow.response.headers = [['Content-Type', 'text/css']]
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={cssFlow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// html
|
||||||
|
let htmlFlow = {...TFlow(), websocket: undefined}
|
||||||
|
htmlFlow.response.headers = [['Content-Type', 'text/html']]
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={htmlFlow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// default
|
||||||
|
let fooFlow = {...TFlow(), websocket: undefined}
|
||||||
|
fooFlow.response.headers = [['Content-Type', 'foo']]
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={fooFlow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
// no response
|
||||||
|
let noResponseFlow = {...TFlow(), response: undefined}
|
||||||
|
iconColumn = renderer.create(<FlowColumns.icon flow={noResponseFlow}/>)
|
||||||
|
tree = iconColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render pathColumn', () => {
|
||||||
|
let tflow = TFlow(),
|
||||||
|
pathColumn = renderer.create(<FlowColumns.path flow={tflow}/>),
|
||||||
|
tree = pathColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
|
||||||
|
tflow.error.msg = 'Connection killed.'
|
||||||
|
tflow.intercepted = true
|
||||||
|
pathColumn = renderer.create(<FlowColumns.path flow={tflow}/>)
|
||||||
|
tree = pathColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should render TimeColumn', () => {
|
||||||
|
let tflow = TFlow(),
|
||||||
|
timeColumn = renderer.create(<FlowColumns.time flow={tflow}/>),
|
||||||
|
tree = timeColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
|
||||||
|
let noResponseFlow = {...tflow, response: undefined}
|
||||||
|
timeColumn = renderer.create(<FlowColumns.time flow={noResponseFlow}/>)
|
||||||
|
tree = timeColumn.toJSON()
|
||||||
|
expect(tree).toMatchSnapshot()
|
||||||
|
})
|
||||||
|
})
|
@ -7,15 +7,15 @@ import {createAppStore} from "../../../ducks";
|
|||||||
|
|
||||||
test("FlowRow", async () => {
|
test("FlowRow", async () => {
|
||||||
const store = createAppStore(testState),
|
const store = createAppStore(testState),
|
||||||
tflow2 = store.getState().flows.view[1],
|
tflow2 = store.getState().flows.list[0],
|
||||||
{asFragment} = render(<table>
|
{asFragment} = render(<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<FlowRow flow={tflow2} selected highlighted/>
|
<FlowRow flow={tflow2} selected highlighted/>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>, {store})
|
</table>, {store})
|
||||||
expect(asFragment()).toMatchSnapshot()
|
expect(asFragment()).toMatchSnapshot()
|
||||||
expect(store.getState().flows.selected[0]).toBe(store.getState().flows.view[0].id)
|
|
||||||
|
|
||||||
fireEvent.click(screen.getByText("http://address:22/second"))
|
expect(store.getState().flows.selected[0]).not.toBe(store.getState().flows.list[0].id)
|
||||||
expect(store.getState().flows.selected[0]).toBe(store.getState().flows.view[1].id)
|
fireEvent.click(screen.getByText("http://address:22/path"))
|
||||||
|
expect(store.getState().flows.selected[0]).toBe(store.getState().flows.list[0].id)
|
||||||
})
|
})
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-plain"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 2`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-not-modified"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 3`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-redirect"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 4`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-image"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 5`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-js"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 6`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-css"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 7`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-document"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 8`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-plain"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render IconColumn 9`] = `
|
|
||||||
<td
|
|
||||||
className="col-icon"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="resource-icon resource-icon-plain"
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render MethodColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-method"
|
|
||||||
>
|
|
||||||
GET
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render QuickActionsColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-quickactions"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<a
|
|
||||||
className="quickaction"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-repeat text-primary"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
className="quickaction"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-ellipsis-h text-muted"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render SizeColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-size"
|
|
||||||
>
|
|
||||||
14b
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render StatusColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-status"
|
|
||||||
style={
|
|
||||||
Object {
|
|
||||||
"color": "darkgreen",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>
|
|
||||||
200
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render TLSColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-tls col-tls-https"
|
|
||||||
/>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render TimeColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-time"
|
|
||||||
>
|
|
||||||
3s
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render TimeColumn 2`] = `
|
|
||||||
<td
|
|
||||||
className="col-time"
|
|
||||||
>
|
|
||||||
...
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render TimeStampColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-start"
|
|
||||||
>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render pathColumn 1`] = `
|
|
||||||
<td
|
|
||||||
className="col-path"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-exclamation pull-right"
|
|
||||||
/>
|
|
||||||
http://address:22/path
|
|
||||||
</td>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Flowcolumns Components should render pathColumn 2`] = `
|
|
||||||
<td
|
|
||||||
className="col-path"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-pause pull-right"
|
|
||||||
/>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-times pull-right"
|
|
||||||
/>
|
|
||||||
http://address:22/path
|
|
||||||
</td>
|
|
||||||
`;
|
|
@ -0,0 +1,310 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 1`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-plain"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 2`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-not-modified"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 3`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-redirect"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 4`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-image"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 5`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-js"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 6`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-css"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 7`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-document"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 8`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-plain"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render IconColumn 9`] = `
|
||||||
|
<td
|
||||||
|
className="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="resource-icon resource-icon-plain"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render TimeColumn 1`] = `
|
||||||
|
<td
|
||||||
|
className="col-time"
|
||||||
|
>
|
||||||
|
5s
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render TimeColumn 2`] = `
|
||||||
|
<td
|
||||||
|
className="col-time"
|
||||||
|
>
|
||||||
|
5s
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render pathColumn 1`] = `
|
||||||
|
<td
|
||||||
|
className="col-path"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-fw fa-exclamation pull-right"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="marker pull-right"
|
||||||
|
>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
http://address:22/path
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`Flowcolumns Components should render pathColumn 2`] = `
|
||||||
|
<td
|
||||||
|
className="col-path"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
className="fa fa-fw fa-pause pull-right"
|
||||||
|
/>
|
||||||
|
<i
|
||||||
|
className="fa fa-fw fa-times pull-right"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
className="marker pull-right"
|
||||||
|
>
|
||||||
|
|
||||||
|
</span>
|
||||||
|
http://address:22/path
|
||||||
|
</td>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: icon 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-icon"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="resource-icon resource-icon-websocket"
|
||||||
|
/>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: method 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-method"
|
||||||
|
>
|
||||||
|
GET
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: path 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-path"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-exclamation pull-right"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
class="marker pull-right"
|
||||||
|
/>
|
||||||
|
http://address:22/path
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: quickactions 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-quickactions"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<a
|
||||||
|
class="quickaction"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-repeat text-primary"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="quickaction"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-ellipsis-h text-muted"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: size 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-size"
|
||||||
|
>
|
||||||
|
14b
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: status 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-status"
|
||||||
|
style="color: darkgreen;"
|
||||||
|
>
|
||||||
|
200
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: time 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-time"
|
||||||
|
>
|
||||||
|
5s
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: timestamp 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-start"
|
||||||
|
>
|
||||||
|
1999-12-31 23:00:00.000
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`should render columns: tls 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<table>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td
|
||||||
|
class="col-tls col-tls-https"
|
||||||
|
/>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -5,7 +5,7 @@ exports[`FlowRow 1`] = `
|
|||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
class="selected highlighted has-request has-response"
|
class="selected highlighted intercepted has-request has-response"
|
||||||
>
|
>
|
||||||
<td
|
<td
|
||||||
class="col-tls col-tls-https"
|
class="col-tls col-tls-https"
|
||||||
@ -14,16 +14,22 @@ exports[`FlowRow 1`] = `
|
|||||||
class="col-icon"
|
class="col-icon"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="resource-icon resource-icon-plain"
|
class="resource-icon resource-icon-websocket"
|
||||||
/>
|
/>
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="col-path"
|
class="col-path"
|
||||||
>
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-pause pull-right"
|
||||||
|
/>
|
||||||
<i
|
<i
|
||||||
class="fa fa-fw fa-exclamation pull-right"
|
class="fa fa-fw fa-exclamation pull-right"
|
||||||
/>
|
/>
|
||||||
http://address:22/second
|
<span
|
||||||
|
class="marker pull-right"
|
||||||
|
/>
|
||||||
|
http://address:22/path
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="col-method"
|
class="col-method"
|
||||||
@ -44,7 +50,7 @@ exports[`FlowRow 1`] = `
|
|||||||
<td
|
<td
|
||||||
class="col-time"
|
class="col-time"
|
||||||
>
|
>
|
||||||
3s
|
5s
|
||||||
</td>
|
</td>
|
||||||
<td
|
<td
|
||||||
class="col-quickactions"
|
class="col-quickactions"
|
||||||
@ -55,7 +61,7 @@ exports[`FlowRow 1`] = `
|
|||||||
href="#"
|
href="#"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
class="fa fa-fw fa-repeat text-primary"
|
class="fa fa-fw fa-play text-success"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import Connection, { TimeStamp, ConnectionInfo, CertificateInfo, Timing } from '../../../components/FlowView/Connection'
|
|
||||||
import { TFlow } from '../../ducks/tutils'
|
|
||||||
|
|
||||||
let tflow = TFlow()
|
|
||||||
|
|
||||||
describe('TimeStamp Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let timestamp = renderer.create(<TimeStamp t={1483228800} deltaTo={1483228700} title="foo"/>),
|
|
||||||
tree = timestamp.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
// without timestamp
|
|
||||||
timestamp = renderer.create(<TimeStamp/>)
|
|
||||||
tree = timestamp.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('ConnectionInfo Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let connectionInfo = renderer.create(<ConnectionInfo conn={tflow.client_conn}/>),
|
|
||||||
tree = connectionInfo.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('CertificateInfo Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let certificateInfo = renderer.create(<CertificateInfo flow={tflow}/>),
|
|
||||||
tree = certificateInfo.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Timing Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let timing = renderer.create(<Timing flow={tflow}/>),
|
|
||||||
tree = timing.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Details Component', () => {
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let details = renderer.create(<Connection flow={tflow}/>),
|
|
||||||
tree = details.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should render correctly when server address is missing', () => {
|
|
||||||
let tflowServerAddressNull = tflow
|
|
||||||
|
|
||||||
tflowServerAddressNull.server_conn.address = null
|
|
||||||
tflowServerAddressNull.server_conn.ip_address = null
|
|
||||||
tflowServerAddressNull.server_conn.sni = null
|
|
||||||
tflowServerAddressNull.server_conn.ssl_established = false
|
|
||||||
tflowServerAddressNull.server_conn.tls_version = null
|
|
||||||
tflowServerAddressNull.server_conn.timestamp_tcp_setup = null
|
|
||||||
tflowServerAddressNull.server_conn.timestamp_ssl_setup = null
|
|
||||||
tflowServerAddressNull.server_conn.timestamp_start = null
|
|
||||||
tflowServerAddressNull.server_conn.timestamp_end = null
|
|
||||||
|
|
||||||
let details = renderer.create(<Connection flow={tflowServerAddressNull}/>),
|
|
||||||
tree = details.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
@ -1,132 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import ReactDOM from 'react-dom'
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import TestUtils from 'react-dom/test-utils'
|
|
||||||
import KeyValueListEditor, { HeaderEditor } from '../../../components/editors/KeyValueListEditor'
|
|
||||||
import { Key } from '../../../utils'
|
|
||||||
|
|
||||||
describe('HeaderEditor Component', () => {
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let headerEditor = renderer.create(
|
|
||||||
<HeaderEditor content="foo" onDone={jest.fn()}/>),
|
|
||||||
tree = headerEditor.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
let doneFn = jest.fn(),
|
|
||||||
removeFn = jest.fn(),
|
|
||||||
tabFn = jest.fn(),
|
|
||||||
headerEditor = TestUtils.renderIntoDocument(
|
|
||||||
<HeaderEditor content="foo" onDone={doneFn} onRemove={removeFn} onTab={tabFn}/>)
|
|
||||||
|
|
||||||
it('should handle focus', () => {
|
|
||||||
let focusFn = jest.fn()
|
|
||||||
ReactDOM.findDOMNode = jest.fn( node => {
|
|
||||||
return {focus: focusFn}
|
|
||||||
})
|
|
||||||
headerEditor.focus()
|
|
||||||
expect(ReactDOM.findDOMNode).toBeCalledWith(headerEditor)
|
|
||||||
expect(focusFn).toBeCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle keyDown', () => {
|
|
||||||
let mockEvent = { keyCode: Key.BACKSPACE },
|
|
||||||
getRangeAt = jest.fn( s => {
|
|
||||||
return { startOffset: 0, endOffset: 0 }
|
|
||||||
})
|
|
||||||
window.getSelection = jest.fn(selection => {
|
|
||||||
return { getRangeAt }
|
|
||||||
})
|
|
||||||
// Backspace
|
|
||||||
headerEditor.onKeyDown(mockEvent)
|
|
||||||
expect(window.getSelection).toBeCalled()
|
|
||||||
expect(getRangeAt).toBeCalledWith(0)
|
|
||||||
expect(headerEditor.props.onRemove).toBeCalledWith(mockEvent)
|
|
||||||
// Enter & Tab
|
|
||||||
mockEvent.keyCode = Key.ENTER
|
|
||||||
headerEditor.onKeyDown(mockEvent)
|
|
||||||
expect(headerEditor.props.onTab).toBeCalledWith(mockEvent)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('Headers Component', () => {
|
|
||||||
let changeFn = jest.fn(),
|
|
||||||
mockMessage = { headers: [['k1', 'v1'], ['k2', '']] }
|
|
||||||
it('should handle correctly', () => {
|
|
||||||
let headers = renderer.create(<KeyValueListEditor onChange={changeFn} message={mockMessage}/>),
|
|
||||||
tree = headers.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
let headers = TestUtils.renderIntoDocument(<KeyValueListEditor onChange={changeFn} message={mockMessage}/>),
|
|
||||||
headerEditors = TestUtils.scryRenderedComponentsWithType(headers, HeaderEditor),
|
|
||||||
key1Editor = headerEditors[0],
|
|
||||||
value1Editor = headerEditors[1],
|
|
||||||
key2Editor = headerEditors[2],
|
|
||||||
value2Editor = headerEditors[3]
|
|
||||||
|
|
||||||
it('should handle change on header name', () => {
|
|
||||||
key2Editor.props.onDone('')
|
|
||||||
expect(changeFn).toBeCalled()
|
|
||||||
expect(headers._nextSel).toEqual('0-value')
|
|
||||||
changeFn.mockClear()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle change on header value', () => {
|
|
||||||
value2Editor.props.onDone('')
|
|
||||||
expect(changeFn).toBeCalled()
|
|
||||||
expect(headers._nextSel).toEqual('0-value')
|
|
||||||
changeFn.mockClear()
|
|
||||||
})
|
|
||||||
|
|
||||||
let mockEvent = { preventDefault: jest.fn() }
|
|
||||||
it('should handle remove on header name', () => {
|
|
||||||
key2Editor.props.onRemove(mockEvent)
|
|
||||||
expect(mockEvent.preventDefault).toBeCalled()
|
|
||||||
mockEvent.preventDefault.mockClear()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle remove on header value', () => {
|
|
||||||
value2Editor.props.onRemove(mockEvent)
|
|
||||||
expect(mockEvent.preventDefault).toBeCalled()
|
|
||||||
mockEvent.preventDefault.mockClear()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle tab on header name', () => {
|
|
||||||
key1Editor.props.onTab(mockEvent)
|
|
||||||
expect(headers._nextSel).toEqual('0-value')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle tab on header value', () => {
|
|
||||||
value1Editor.props.onTab(mockEvent)
|
|
||||||
expect(headers._nextSel).toEqual('1-key')
|
|
||||||
|
|
||||||
value2Editor.props.onTab(mockEvent)
|
|
||||||
expect(mockEvent.preventDefault).toBeCalled()
|
|
||||||
expect(headers._nextSel).toEqual('2-key')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle componentDidUpdate', () => {
|
|
||||||
headers._nextSel = '1-value'
|
|
||||||
headers.refs['1-value'] = { focus: jest.fn() }
|
|
||||||
headers.componentDidUpdate()
|
|
||||||
expect(headers.refs['1-value'].focus).toBeCalled()
|
|
||||||
expect(headers._nextSel).toEqual(undefined)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle edit', () => {
|
|
||||||
headers.refs['0-key'] = { focus: jest.fn() }
|
|
||||||
headers.edit()
|
|
||||||
expect(headers.refs['0-key'].focus).toBeCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not delete last row when handle remove', () => {
|
|
||||||
mockMessage = { headers: [['', '']] }
|
|
||||||
headers = TestUtils.renderIntoDocument(<KeyValueListEditor onChange={changeFn} message={mockMessage}/>)
|
|
||||||
headers.onChange(0, 0, '')
|
|
||||||
expect(changeFn).toBeCalledWith([['Name', 'Value']])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
@ -1,146 +0,0 @@
|
|||||||
jest.mock('../../../components/ContentView', () => () => null)
|
|
||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import {ErrorView, Request, Response} from '../../../components/FlowView/HttpMessages'
|
|
||||||
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 KeyValueListEditor from '../../../components/editors/KeyValueListEditor'
|
|
||||||
import ValueEditor from '../../../components/editors/ValueEditor'
|
|
||||||
|
|
||||||
global.fetch = jest.fn()
|
|
||||||
|
|
||||||
let tflow = new TFlow(),
|
|
||||||
store = TStore()
|
|
||||||
store.getState().ui.flow.modifiedFlow = false
|
|
||||||
|
|
||||||
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 = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<Request/>
|
|
||||||
</Provider>),
|
|
||||||
valueEditors = provider.root.findAllByType(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 = provider.root.findAllByType(KeyValueListEditor).filter(headers => headers.props.type === 'headers')[0]
|
|
||||||
headers.props.onChange('foo')
|
|
||||||
expect(store.getActions()).toEqual([updateEdit({request: {headers: 'foo'}})])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle change on flow request contentView', () => {
|
|
||||||
let contentView = provider.root.findByType(ContentView)
|
|
||||||
contentView.props.onContentChange('foo')
|
|
||||||
expect(store.getActions()).toEqual([updateEdit({request: {content: 'foo'}})])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle uploadContent on flow request ContentViewOptions', () => {
|
|
||||||
let contentViewOptions = provider.root.findByType(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 = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<Response/>
|
|
||||||
</Provider>),
|
|
||||||
valueEditors = provider.root.findAllByType(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 = provider.root.findAllByType(KeyValueListEditor).filter(headers => headers.props.type === 'headers')[0]
|
|
||||||
headers.props.onChange('foo')
|
|
||||||
expect(store.getActions()).toEqual([updateEdit({response: {headers: 'foo'}})])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle change on flow response ContentView', () => {
|
|
||||||
let contentView = provider.root.findByType(ContentView)
|
|
||||||
contentView.props.onContentChange('foo')
|
|
||||||
expect(store.getActions()).toEqual([updateEdit({response: {content: 'foo'}})])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle updateContent on flow response ContentViewOptions', () => {
|
|
||||||
let contentViewOptions = provider.root.findByType(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()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,38 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import Nav, { NavAction } from '../../../components/FlowView/Nav'
|
|
||||||
|
|
||||||
describe('Nav Component', () => {
|
|
||||||
let tabs = ['foo', 'bar'],
|
|
||||||
onSelectTab = jest.fn(),
|
|
||||||
nav = renderer.create(<Nav active='foo' tabs={tabs} onSelectTab={onSelectTab}/>),
|
|
||||||
tree = nav.toJSON()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle click', () => {
|
|
||||||
let mockEvent = { preventDefault: jest.fn() }
|
|
||||||
tree.children[0].props.onClick(mockEvent)
|
|
||||||
expect(mockEvent.preventDefault).toBeCalled()
|
|
||||||
expect(onSelectTab).toBeCalledWith('foo')
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('NavAction Component', () => {
|
|
||||||
let clickFn = jest.fn(),
|
|
||||||
navAction = renderer.create(<NavAction icon="foo" title="bar" onClick={clickFn}/>),
|
|
||||||
tree = navAction.toJSON()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle click', () => {
|
|
||||||
let mockEvent = { preventDefault: jest.fn() }
|
|
||||||
tree.props.onClick(mockEvent)
|
|
||||||
expect(mockEvent.preventDefault).toBeCalled()
|
|
||||||
expect(clickFn).toBeCalledWith(mockEvent)
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,21 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import ToggleEdit from '../../../components/FlowView/ToggleEdit'
|
|
||||||
import {TFlow} from '../../ducks/tutils'
|
|
||||||
import {render} from "../../test-utils"
|
|
||||||
import {fireEvent, screen} from "@testing-library/react";
|
|
||||||
|
|
||||||
let tflow = TFlow();
|
|
||||||
|
|
||||||
test("ToggleEdit", async () => {
|
|
||||||
const {asFragment, store} = render(
|
|
||||||
<ToggleEdit/>,
|
|
||||||
);
|
|
||||||
|
|
||||||
fireEvent.click(screen.getByTitle("Edit Flow"));
|
|
||||||
expect(asFragment()).toMatchSnapshot();
|
|
||||||
expect(store.getState().ui.flow.modifiedFlow).toBeTruthy();
|
|
||||||
|
|
||||||
fireEvent.click(screen.getByTitle("Finish Edit"));
|
|
||||||
expect(asFragment()).toMatchSnapshot();
|
|
||||||
expect(store.getState().ui.flow.modifiedFlow).toBeFalsy();
|
|
||||||
});
|
|
@ -1,591 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`CertificateInfo Component should render correctly 1`] = `<div />`;
|
|
||||||
|
|
||||||
exports[`ConnectionInfo Component should render correctly 1`] = `
|
|
||||||
<table
|
|
||||||
className="connection-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Address:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
127.0.0.1:22
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="TLS Server Name Indication"
|
|
||||||
>
|
|
||||||
TLS SNI:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
address
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
TLS version:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
TLSv1.2
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
cipher name:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
cipher
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="ALPN protocol negotiated"
|
|
||||||
>
|
|
||||||
ALPN:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
http/1.1
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Details Component should render correctly 1`] = `
|
|
||||||
<section
|
|
||||||
className="detail"
|
|
||||||
>
|
|
||||||
<h4>
|
|
||||||
Client Connection
|
|
||||||
</h4>
|
|
||||||
<table
|
|
||||||
className="connection-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Address:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
127.0.0.1:22
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="TLS Server Name Indication"
|
|
||||||
>
|
|
||||||
TLS SNI:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
address
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
TLS version:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
TLSv1.2
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
cipher name:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
cipher
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="ALPN protocol negotiated"
|
|
||||||
>
|
|
||||||
ALPN:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
http/1.1
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<h4>
|
|
||||||
Server Connection
|
|
||||||
</h4>
|
|
||||||
<table
|
|
||||||
className="connection-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Address:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
address:22
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="TLS Server Name Indication"
|
|
||||||
>
|
|
||||||
TLS SNI:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
address
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
TLS version:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
TLSv1.2
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Resolved address:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
192.168.0.1:22
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Source address:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
address:22
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div />
|
|
||||||
<div>
|
|
||||||
<h4>
|
|
||||||
Timing
|
|
||||||
</h4>
|
|
||||||
<table
|
|
||||||
className="timing-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Server conn. initiated
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:02.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
2s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Server conn. TCP handshake
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:03.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
3s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr />
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Client conn. established
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
0ms
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr />
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
First request byte
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Request complete
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:01.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
1s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
First response byte
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:02.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
2s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Response complete
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:03.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
3s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`Details Component should render correctly when server address is missing 1`] = `
|
|
||||||
<section
|
|
||||||
className="detail"
|
|
||||||
>
|
|
||||||
<h4>
|
|
||||||
Client Connection
|
|
||||||
</h4>
|
|
||||||
<table
|
|
||||||
className="connection-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Address:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
127.0.0.1:22
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="TLS Server Name Indication"
|
|
||||||
>
|
|
||||||
TLS SNI:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
address
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
TLS version:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
TLSv1.2
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
cipher name:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
cipher
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<abbr
|
|
||||||
title="ALPN protocol negotiated"
|
|
||||||
>
|
|
||||||
ALPN:
|
|
||||||
</abbr>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
http/1.1
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<div />
|
|
||||||
<div>
|
|
||||||
<h4>
|
|
||||||
Timing
|
|
||||||
</h4>
|
|
||||||
<table
|
|
||||||
className="timing-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr />
|
|
||||||
<tr />
|
|
||||||
<tr />
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Client conn. established
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
0ms
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr />
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
First request byte
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Request complete
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:01.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
1s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
First response byte
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:02.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
2s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Response complete
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:03.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
3s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`TimeStamp Component should render correctly 1`] = `
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
foo
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
2017-01-01 00:00:00.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
2min
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`TimeStamp Component should render correctly 2`] = `<tr />`;
|
|
||||||
|
|
||||||
exports[`Timing Component should render correctly 1`] = `
|
|
||||||
<div>
|
|
||||||
<h4>
|
|
||||||
Timing
|
|
||||||
</h4>
|
|
||||||
<table
|
|
||||||
className="timing-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Server conn. initiated
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:02.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
2s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Server conn. TCP handshake
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:03.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
3s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr />
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Client conn. established
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
0ms
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr />
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
First request byte
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:00.000
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Request complete
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:01.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
1s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
First response byte
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:02.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
2s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
Response complete
|
|
||||||
:
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
1999-12-31 23:00:03.000
|
|
||||||
<span
|
|
||||||
className="text-muted"
|
|
||||||
>
|
|
||||||
(
|
|
||||||
3s
|
|
||||||
)
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -1,123 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`HeaderEditor Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="inline-input editable"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "foo",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`KeyValueListEditor Component should handle correctly 1`] = `
|
|
||||||
<table
|
|
||||||
className="header-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input editable"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "k1",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input editable"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "v1",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input editable"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "k2",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input editable"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
`;
|
|
@ -1,496 +0,0 @@
|
|||||||
// 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>
|
|
||||||
1999-12-31 23:00:07.000
|
|
||||||
</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"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "GET",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
className="inline-input readonly has-success"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "http://address:22/path",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
className="inline-input readonly has-success"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "HTTP/1.1",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<table
|
|
||||||
className="header-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "header",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "qvalue",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "content-length",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "7",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<hr />
|
|
||||||
<hr />
|
|
||||||
<table
|
|
||||||
className="header-table"
|
|
||||||
>
|
|
||||||
<tbody />
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
<footer>
|
|
||||||
<div
|
|
||||||
className="view-options"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<b>
|
|
||||||
View:
|
|
||||||
</b>
|
|
||||||
edit
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/request/content.data"
|
|
||||||
title="Download the content of the flow."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-download"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="Upload a file to replace the content."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-upload"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
className="hidden"
|
|
||||||
onChange={[Function]}
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</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"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "HTTP/1.1",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
className="inline-input readonly has-success"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "200",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "OK",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<table
|
|
||||||
className="header-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "header-response",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "svalue",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "content-length",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "7",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<hr />
|
|
||||||
<hr />
|
|
||||||
<table
|
|
||||||
className="header-table"
|
|
||||||
>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td
|
|
||||||
className="header-name"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "trailer",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
className="header-colon"
|
|
||||||
>
|
|
||||||
:
|
|
||||||
</span>
|
|
||||||
</td>
|
|
||||||
<td
|
|
||||||
className="header-value"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="inline-input readonly"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "qvalue",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</article>
|
|
||||||
<footer>
|
|
||||||
<div
|
|
||||||
className="view-options"
|
|
||||||
>
|
|
||||||
<span>
|
|
||||||
<b>
|
|
||||||
View:
|
|
||||||
</b>
|
|
||||||
edit
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
|
|
||||||
title="Download the content of the flow."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-download"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="Upload a file to replace the content."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-upload"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
className="hidden"
|
|
||||||
onChange={[Function]}
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</footer>
|
|
||||||
</section>
|
|
||||||
`;
|
|
@ -1,35 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`Nav Component should render correctly 1`] = `
|
|
||||||
<nav
|
|
||||||
className="nav-tabs nav-tabs-sm"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className="active"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
Foo
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
className=""
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
Bar
|
|
||||||
</a>
|
|
||||||
</nav>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`NavAction Component should render correctly 1`] = `
|
|
||||||
<a
|
|
||||||
className="nav-action"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="bar"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw foo"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
`;
|
|
@ -1,35 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ToggleEdit 1`] = `
|
|
||||||
<DocumentFragment>
|
|
||||||
<div
|
|
||||||
class="edit-flow-container"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="edit-flow"
|
|
||||||
title="Finish Edit"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-check"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</DocumentFragment>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ToggleEdit 2`] = `
|
|
||||||
<DocumentFragment>
|
|
||||||
<div
|
|
||||||
class="edit-flow-container"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
class="edit-flow"
|
|
||||||
title="Edit Flow"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-pencil"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</DocumentFragment>
|
|
||||||
`;
|
|
29
web/src/js/__tests__/components/FlowViewSpec.tsx
Normal file
29
web/src/js/__tests__/components/FlowViewSpec.tsx
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import {render, screen, waitFor} from "../test-utils";
|
||||||
|
import FlowView from "../../components/FlowView";
|
||||||
|
import fetchMock, {enableFetchMocks} from "jest-fetch-mock";
|
||||||
|
import {fireEvent} from "@testing-library/react";
|
||||||
|
|
||||||
|
enableFetchMocks();
|
||||||
|
|
||||||
|
test("FlowView", async () => {
|
||||||
|
fetchMock.mockReject(new Error("backend missing"));
|
||||||
|
|
||||||
|
const {asFragment} = render(<FlowView/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Response"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("WebSocket"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Connection"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Timing"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Error"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
@ -1,35 +0,0 @@
|
|||||||
jest.mock('../../../flow/utils')
|
|
||||||
|
|
||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import FlowMenu from '../../../components/Header/FlowMenu'
|
|
||||||
import { TFlow, TStore }from '../../ducks/tutils'
|
|
||||||
import { MessageUtils } from "../../../flow/utils"
|
|
||||||
import { Provider } from 'react-redux'
|
|
||||||
|
|
||||||
describe('FlowMenu Component', () => {
|
|
||||||
let tflow = new TFlow(),
|
|
||||||
store = new TStore()
|
|
||||||
tflow.modified = true
|
|
||||||
tflow.intercepted = true
|
|
||||||
global.fetch = jest.fn()
|
|
||||||
|
|
||||||
let flowMenu = renderer.create(
|
|
||||||
<Provider store={store}>
|
|
||||||
<FlowMenu />
|
|
||||||
</Provider>
|
|
||||||
),
|
|
||||||
tree = flowMenu.toJSON()
|
|
||||||
|
|
||||||
it('should render correctly with flow', () => {
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
let menu_content_2 = tree.children[1].children[0]
|
|
||||||
it('should handle download', () => {
|
|
||||||
let button = menu_content_2.children[0]
|
|
||||||
button.props.onClick()
|
|
||||||
expect(MessageUtils.getContentURL).toBeCalledWith(tflow, tflow.response)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
8
web/src/js/__tests__/components/Header/FlowMenuSpec.tsx
Normal file
8
web/src/js/__tests__/components/Header/FlowMenuSpec.tsx
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import FlowMenu from '../../../components/Header/FlowMenu'
|
||||||
|
import {render} from "../../test-utils"
|
||||||
|
|
||||||
|
test("FlowMenu", async () => {
|
||||||
|
const {asFragment} = render(<FlowMenu/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
@ -6,6 +6,6 @@ exports[`FileMenu Component should render correctly 1`] = `
|
|||||||
href="#"
|
href="#"
|
||||||
onClick={[Function]}
|
onClick={[Function]}
|
||||||
>
|
>
|
||||||
mitmproxy
|
File
|
||||||
</a>
|
</a>
|
||||||
`;
|
`;
|
||||||
|
@ -1,120 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`FlowMenu Component should render correctly with flow 1`] = `
|
|
||||||
<div
|
|
||||||
className="flow-menu"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="menu-group"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="menu-content"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="[r]eplay flow"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-repeat text-primary"
|
|
||||||
/>
|
|
||||||
Replay
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="[D]uplicate flow"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-copy text-info"
|
|
||||||
/>
|
|
||||||
Duplicate
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
disabled={false}
|
|
||||||
onClick={[Function]}
|
|
||||||
title="revert changes to flow [V]"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-history text-warning"
|
|
||||||
/>
|
|
||||||
Revert
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="[d]elete flow"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-trash text-danger"
|
|
||||||
/>
|
|
||||||
Delete
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="menu-legend"
|
|
||||||
>
|
|
||||||
Flow Modification
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="menu-group"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="menu-content"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="download"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-download"
|
|
||||||
/>
|
|
||||||
Download
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="menu-legend"
|
|
||||||
>
|
|
||||||
Export
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="menu-group"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="menu-content"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
disabled={false}
|
|
||||||
onClick={[Function]}
|
|
||||||
title="[a]ccept intercepted flow"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-play text-success"
|
|
||||||
/>
|
|
||||||
Resume
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
className="btn btn-default"
|
|
||||||
disabled={false}
|
|
||||||
onClick={[Function]}
|
|
||||||
title="kill intercepted flow [x]"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-times text-danger"
|
|
||||||
/>
|
|
||||||
Abort
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="menu-legend"
|
|
||||||
>
|
|
||||||
Interception
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -0,0 +1,134 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`FlowMenu 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-menu"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="menu-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="menu-content"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
disabled=""
|
||||||
|
title="[r]eplay flow"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-repeat text-primary"
|
||||||
|
/>
|
||||||
|
Replay
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
title="[D]uplicate flow"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-copy text-info"
|
||||||
|
/>
|
||||||
|
Duplicate
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
disabled=""
|
||||||
|
title="revert changes to flow [V]"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-history text-warning"
|
||||||
|
/>
|
||||||
|
Revert
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
title="[d]elete flow"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-trash text-danger"
|
||||||
|
/>
|
||||||
|
Delete
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="menu-legend"
|
||||||
|
>
|
||||||
|
Flow Modification
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="menu-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="menu-content"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-download"
|
||||||
|
/>
|
||||||
|
Download▾
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
title="Export flow."
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-clone"
|
||||||
|
/>
|
||||||
|
Export▾
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="menu-legend"
|
||||||
|
>
|
||||||
|
Export
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="menu-group"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="menu-content"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
disabled=""
|
||||||
|
title="[a]ccept intercepted flow"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-play text-success"
|
||||||
|
/>
|
||||||
|
Resume
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-default"
|
||||||
|
disabled=""
|
||||||
|
title="kill intercepted flow [x]"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-times text-danger"
|
||||||
|
/>
|
||||||
|
Abort
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="menu-legend"
|
||||||
|
>
|
||||||
|
Interception
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -26,7 +26,7 @@ exports[`MainMenu 1`] = `
|
|||||||
class="form-control"
|
class="form-control"
|
||||||
placeholder="Search"
|
placeholder="Search"
|
||||||
type="text"
|
type="text"
|
||||||
value="~d address"
|
value="~u /second"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@ -97,101 +97,3 @@ exports[`MainMenu 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</DocumentFragment>
|
</DocumentFragment>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`StartMenu 1`] = `
|
|
||||||
<DocumentFragment>
|
|
||||||
<div
|
|
||||||
class="main-menu"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="menu-group"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="menu-content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="filter-input input-group"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="input-group-addon"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-fw fa-search"
|
|
||||||
style="color: black;"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="form-control"
|
|
||||||
placeholder="Search"
|
|
||||||
type="text"
|
|
||||||
value="~d address"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="filter-input input-group"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="input-group-addon"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-fw fa-tag"
|
|
||||||
style="color: rgb(0, 0, 0);"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="form-control"
|
|
||||||
placeholder="Highlight"
|
|
||||||
type="text"
|
|
||||||
value="~u /path"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="menu-legend"
|
|
||||||
>
|
|
||||||
Find
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="menu-group"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="menu-content"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class="filter-input input-group"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="input-group-addon"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-fw fa-pause"
|
|
||||||
style="color: rgb(68, 68, 68);"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
<input
|
|
||||||
class="form-control"
|
|
||||||
placeholder="Intercept"
|
|
||||||
type="text"
|
|
||||||
value=""
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
class="btn-sm btn btn-default"
|
|
||||||
title="[a]ccept all"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
class="fa fa-fw fa-forward text-success"
|
|
||||||
/>
|
|
||||||
Resume All
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
class="menu-legend"
|
|
||||||
>
|
|
||||||
Intercept
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DocumentFragment>
|
|
||||||
`;
|
|
||||||
|
@ -14,8 +14,9 @@ exports[`OptionMenu Component should render correctly 1`] = `
|
|||||||
title="Open Options"
|
title="Open Options"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="fa fa-fw fa-cogs text-primary"
|
className="fa fa-cogs text-primary"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
Edit Options
|
Edit Options
|
||||||
<sup>
|
<sup>
|
||||||
alpha
|
alpha
|
||||||
@ -103,6 +104,18 @@ exports[`OptionMenu Component should render correctly 1`] = `
|
|||||||
Display Event Log
|
Display Event Log
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
className="menu-entry"
|
||||||
|
>
|
||||||
|
<label>
|
||||||
|
<input
|
||||||
|
checked={true}
|
||||||
|
onChange={[Function]}
|
||||||
|
type="checkbox"
|
||||||
|
/>
|
||||||
|
Display Command Bar
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="menu-legend"
|
className="menu-legend"
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import TestUtils from 'react-dom/test-utils'
|
|
||||||
import ValidateEditor from '../../../components/editors/ValidateEditor'
|
|
||||||
|
|
||||||
describe('ValidateEditor Component', () => {
|
|
||||||
let validateFn = jest.fn( content => content.length == 3),
|
|
||||||
doneFn = jest.fn()
|
|
||||||
|
|
||||||
it('should render correctly', () => {
|
|
||||||
let validateEditor = renderer.create(
|
|
||||||
<ValidateEditor content="foo" onEditDone={doneFn} isValid={validateFn}/>
|
|
||||||
),
|
|
||||||
tree = validateEditor.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
let validateEditor = TestUtils.renderIntoDocument(
|
|
||||||
<ValidateEditor content="foo" onEditDone={doneFn} isValid={validateFn}/>
|
|
||||||
)
|
|
||||||
it('should handle componentWillReceiveProps', () => {
|
|
||||||
let mockProps = {
|
|
||||||
isValid: s => s.length == 3,
|
|
||||||
content: "bar"
|
|
||||||
}
|
|
||||||
validateEditor.UNSAFE_componentWillReceiveProps(mockProps)
|
|
||||||
expect(validateEditor.state.valid).toBeTruthy()
|
|
||||||
validateEditor.UNSAFE_componentWillReceiveProps({...mockProps, content: "bars"})
|
|
||||||
expect(validateEditor.state.valid).toBeFalsy()
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle input', () => {
|
|
||||||
validateEditor.onInput("foo bar")
|
|
||||||
expect(validateFn).toBeCalledWith("foo bar")
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle done', () => {
|
|
||||||
// invalid
|
|
||||||
validateEditor.editor.reset = jest.fn()
|
|
||||||
validateEditor.onDone("foo bar")
|
|
||||||
expect(validateEditor.editor.reset).toBeCalled()
|
|
||||||
// valid
|
|
||||||
validateEditor.onDone("bar")
|
|
||||||
expect(doneFn).toBeCalledWith("bar")
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,155 +0,0 @@
|
|||||||
import * as React from "react"
|
|
||||||
import renderer from 'react-test-renderer'
|
|
||||||
import TestUtils from 'react-dom/test-utils'
|
|
||||||
import ValueEditor from '../../../components/editors/ValueEditor'
|
|
||||||
import { Key } from '../../../utils'
|
|
||||||
|
|
||||||
describe('ValueEditor Component', () => {
|
|
||||||
|
|
||||||
let mockFn = jest.fn()
|
|
||||||
it ('should render correctly', () => {
|
|
||||||
let valueEditor = renderer.create(
|
|
||||||
<ValueEditor content="foo" onEditDone={mockFn}/>
|
|
||||||
),
|
|
||||||
tree = valueEditor.toJSON()
|
|
||||||
expect(tree).toMatchSnapshot()
|
|
||||||
})
|
|
||||||
|
|
||||||
let valueEditor = TestUtils.renderIntoDocument(
|
|
||||||
<ValueEditor content="<script>foo</script>" onEditDone={mockFn}/>
|
|
||||||
)
|
|
||||||
it('should handle this.blur', () => {
|
|
||||||
valueEditor.input.blur = jest.fn()
|
|
||||||
valueEditor.blur()
|
|
||||||
expect(valueEditor.input.blur).toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle reset', () => {
|
|
||||||
valueEditor.reset()
|
|
||||||
expect(valueEditor.input.innerHTML).toEqual(
|
|
||||||
"<script>foo</script>"
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle paste', () => {
|
|
||||||
let mockEvent = {
|
|
||||||
preventDefault: jest.fn(),
|
|
||||||
clipboardData: { getData: (t) => "foo content"}
|
|
||||||
}
|
|
||||||
document.execCommand = jest.fn()
|
|
||||||
valueEditor.onPaste(mockEvent)
|
|
||||||
expect(document.execCommand).toBeCalledWith('insertHTML', false, "foo content")
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle mouseDown', () => {
|
|
||||||
window.addEventListener = jest.fn()
|
|
||||||
valueEditor.onMouseDown({})
|
|
||||||
expect(valueEditor._mouseDown).toBeTruthy()
|
|
||||||
expect(window.addEventListener).toBeCalledWith('mouseup', valueEditor.onMouseUp)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle mouseUp', () => {
|
|
||||||
window.removeEventListener = jest.fn()
|
|
||||||
valueEditor.onMouseUp()
|
|
||||||
expect(window.removeEventListener).toBeCalledWith('mouseup', valueEditor.onMouseUp)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle focus', () => {
|
|
||||||
let mockEvent = { clientX: 1, clientY: 2 },
|
|
||||||
mockSelection = {
|
|
||||||
rangeCount: 1,
|
|
||||||
getRangeAt: jest.fn( (index) => {return { selectNodeContents: jest.fn() }}),
|
|
||||||
removeAllRanges: jest.fn(),
|
|
||||||
addRange: jest.fn()
|
|
||||||
},
|
|
||||||
clearState = (v) => {
|
|
||||||
v._mouseDown = false
|
|
||||||
v._ignore_events = false
|
|
||||||
v.state.editable = false
|
|
||||||
}
|
|
||||||
window.getSelection = () => mockSelection
|
|
||||||
|
|
||||||
// return undefined when mouse down
|
|
||||||
valueEditor.onMouseDown()
|
|
||||||
expect(valueEditor.onFocus(mockEvent)).toEqual(undefined)
|
|
||||||
valueEditor.onMouseUp()
|
|
||||||
|
|
||||||
// sel.rangeCount > 0
|
|
||||||
valueEditor.onFocus(mockEvent)
|
|
||||||
expect(mockSelection.getRangeAt).toBeCalledWith(0)
|
|
||||||
expect(valueEditor.state.editable).toBeTruthy()
|
|
||||||
expect(mockSelection.removeAllRanges).toBeCalled()
|
|
||||||
expect(mockSelection.addRange).toBeCalled()
|
|
||||||
clearState(valueEditor)
|
|
||||||
|
|
||||||
// document.caretPositionFromPoint
|
|
||||||
mockSelection.rangeCount = 0
|
|
||||||
let mockRange = { setStart: jest.fn(), selectNodeContents: jest.fn() }
|
|
||||||
|
|
||||||
document.caretPositionFromPoint = jest.fn((x, y) => {
|
|
||||||
return { offsetNode: 0, offset: x + y}
|
|
||||||
})
|
|
||||||
document.createRange = jest.fn(() => mockRange)
|
|
||||||
valueEditor.onFocus(mockEvent)
|
|
||||||
expect(mockRange.setStart).toBeCalledWith(0, 3)
|
|
||||||
clearState(valueEditor)
|
|
||||||
document.caretPositionFromPoint = null
|
|
||||||
|
|
||||||
//document.caretRangeFromPoint
|
|
||||||
document.caretRangeFromPoint = jest.fn(() => mockRange)
|
|
||||||
valueEditor.onFocus(mockEvent)
|
|
||||||
expect(document.caretRangeFromPoint).toBeCalledWith(1, 2)
|
|
||||||
clearState(valueEditor)
|
|
||||||
document.caretRangeFromPoint = null
|
|
||||||
|
|
||||||
//else
|
|
||||||
valueEditor.onFocus(mockEvent)
|
|
||||||
expect(mockRange.selectNodeContents).toBeCalledWith(valueEditor.input)
|
|
||||||
clearState(valueEditor)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle click', () => {
|
|
||||||
valueEditor.onMouseUp = jest.fn()
|
|
||||||
valueEditor.onFocus = jest.fn()
|
|
||||||
valueEditor.onClick('foo')
|
|
||||||
expect(valueEditor.onMouseUp).toBeCalled()
|
|
||||||
expect(valueEditor.onFocus).toBeCalledWith('foo')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle blur', () => {
|
|
||||||
// return undefined
|
|
||||||
valueEditor._ignore_events = true
|
|
||||||
expect(valueEditor.onBlur({})).toEqual(undefined)
|
|
||||||
// else
|
|
||||||
valueEditor._ignore_events = false
|
|
||||||
valueEditor.onBlur({})
|
|
||||||
expect(valueEditor.state.editable).toBeFalsy()
|
|
||||||
expect(valueEditor.props.onDone).toBeCalledWith(valueEditor.input.textContent)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle key down', () => {
|
|
||||||
let mockKeyEvent = (keyCode, shiftKey=false) => {
|
|
||||||
return {
|
|
||||||
keyCode: keyCode,
|
|
||||||
shiftKey: shiftKey,
|
|
||||||
stopPropagation: jest.fn(),
|
|
||||||
preventDefault: jest.fn()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
valueEditor.reset = jest.fn()
|
|
||||||
valueEditor.blur = jest.fn()
|
|
||||||
valueEditor.onKeyDown(mockKeyEvent(Key.ESC))
|
|
||||||
expect(valueEditor.reset).toBeCalled()
|
|
||||||
expect(valueEditor.blur).toBeCalled()
|
|
||||||
valueEditor.blur.mockReset()
|
|
||||||
|
|
||||||
valueEditor.onKeyDown(mockKeyEvent(Key.ENTER))
|
|
||||||
expect(valueEditor.blur).toBeCalled()
|
|
||||||
|
|
||||||
valueEditor.onKeyDown(mockKeyEvent(Key.SPACE))
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle input', () => {
|
|
||||||
valueEditor.onInput()
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,20 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ValidateEditor Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="inline-input editable has-success"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "foo",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
`;
|
|
@ -1,20 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ValueEditor Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="inline-input editable"
|
|
||||||
dangerouslySetInnerHTML={
|
|
||||||
Object {
|
|
||||||
"__html": "foo",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onBlur={[Function]}
|
|
||||||
onClick={[Function]}
|
|
||||||
onFocus={[Function]}
|
|
||||||
onInput={[Function]}
|
|
||||||
onKeyDown={[Function]}
|
|
||||||
onMouseDown={[Function]}
|
|
||||||
onPaste={[Function]}
|
|
||||||
tabIndex={0}
|
|
||||||
/>
|
|
||||||
`;
|
|
@ -0,0 +1,111 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`CommandBar 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="command"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="command-title"
|
||||||
|
>
|
||||||
|
Command Result
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="command-result"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="argument-suggestion popover top"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="arrow"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="popover-content"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<strong>
|
||||||
|
Available Commands:
|
||||||
|
</strong>
|
||||||
|
<p
|
||||||
|
class="available-commands"
|
||||||
|
>
|
||||||
|
[]
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="command-input input-group"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="input-group-addon"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-terminal"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
placeholder="Enter command"
|
||||||
|
type="text"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`CommandBar 2`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="command"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="command-title"
|
||||||
|
>
|
||||||
|
Command Result
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="command-result"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="argument-suggestion popover top"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="arrow"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="popover-content"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<strong>
|
||||||
|
Available Commands:
|
||||||
|
</strong>
|
||||||
|
<p
|
||||||
|
class="available-commands"
|
||||||
|
>
|
||||||
|
["flow.decode"]
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="command-input input-group"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="input-group-addon"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-terminal"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<input
|
||||||
|
class="form-control"
|
||||||
|
placeholder="Enter command"
|
||||||
|
type="text"
|
||||||
|
value=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -1,80 +0,0 @@
|
|||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
||||||
|
|
||||||
exports[`ContentView Component should render correctly 1`] = `
|
|
||||||
<div
|
|
||||||
className="contentview"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
className="text-center"
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-spinner fa-spin"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ContentView Component should render correctly with content too large 1`] = `
|
|
||||||
<div>
|
|
||||||
<div
|
|
||||||
className="alert alert-warning"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
className="btn btn-xs btn-warning pull-right"
|
|
||||||
onClick={[Function]}
|
|
||||||
>
|
|
||||||
Display anyway
|
|
||||||
</button>
|
|
||||||
100mb
|
|
||||||
content size.
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
className="view-options text-center"
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="#"
|
|
||||||
onClick={[Function]}
|
|
||||||
title="Upload a file to replace the content."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-fw fa-upload"
|
|
||||||
/>
|
|
||||||
<input
|
|
||||||
className="hidden"
|
|
||||||
onChange={[Function]}
|
|
||||||
type="file"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a
|
|
||||||
className="btn btn-default btn-xs"
|
|
||||||
href="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/response/content.data"
|
|
||||||
title="Download the content of the flow."
|
|
||||||
>
|
|
||||||
<i
|
|
||||||
className="fa fa-download"
|
|
||||||
/>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ContentView Component should render correctly with empty content 1`] = `
|
|
||||||
<div
|
|
||||||
className="alert alert-info"
|
|
||||||
>
|
|
||||||
No
|
|
||||||
response
|
|
||||||
content.
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`ContentView Component should render correctly with missing content 1`] = `
|
|
||||||
<div
|
|
||||||
className="alert alert-info"
|
|
||||||
>
|
|
||||||
Response
|
|
||||||
content missing.
|
|
||||||
</div>
|
|
||||||
`;
|
|
@ -0,0 +1,854 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`FlowView 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-detail"
|
||||||
|
>
|
||||||
|
<nav
|
||||||
|
class="nav-tabs nav-tabs-sm"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="active"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
WebSocket
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Error
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Connection
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Timing
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<section
|
||||||
|
class="request"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="first-line request-line"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="inline-input has-success"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
GET
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="inline-input has-success"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
http://address:22/second
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="inline-input has-success"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
HTTP/1.1
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="kv-editor headers"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="kv-row"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="inline-input kv-key"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
header
|
||||||
|
</span>
|
||||||
|
:
|
||||||
|
<span
|
||||||
|
class="inline-input kv-value"
|
||||||
|
placeholder="empty"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
qvalue
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="kv-row"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="inline-input kv-key"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
content-length
|
||||||
|
</span>
|
||||||
|
:
|
||||||
|
<span
|
||||||
|
class="inline-input kv-value"
|
||||||
|
placeholder="empty"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
7
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-label="Add"
|
||||||
|
class="kv-add-row fa fa-plus-square-o"
|
||||||
|
role="button"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div
|
||||||
|
class="contentview"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="controls"
|
||||||
|
>
|
||||||
|
<h5>
|
||||||
|
Loading...
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-edit"
|
||||||
|
/>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
title="Upload a file to replace the content."
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-upload"
|
||||||
|
/>
|
||||||
|
Replace
|
||||||
|
<input
|
||||||
|
class="hidden"
|
||||||
|
type="file"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
auto
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`FlowView 2`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-detail"
|
||||||
|
>
|
||||||
|
<nav
|
||||||
|
class="nav-tabs nav-tabs-sm"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="active"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
WebSocket
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Error
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Connection
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Timing
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<section
|
||||||
|
class="response"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="first-line response-line"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="inline-input has-success"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
HTTP/1.1
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="inline-input has-success"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
200
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<span
|
||||||
|
class="inline-input"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
OK
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="kv-editor headers"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="kv-row"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="inline-input kv-key"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
header-response
|
||||||
|
</span>
|
||||||
|
:
|
||||||
|
<span
|
||||||
|
class="inline-input kv-value"
|
||||||
|
placeholder="empty"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
svalue
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="kv-row"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
class="inline-input kv-key"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
content-length
|
||||||
|
</span>
|
||||||
|
:
|
||||||
|
<span
|
||||||
|
class="inline-input kv-value"
|
||||||
|
placeholder="empty"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
7
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
aria-label="Add"
|
||||||
|
class="kv-add-row fa fa-plus-square-o"
|
||||||
|
role="button"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
<div
|
||||||
|
class="contentview"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="controls"
|
||||||
|
>
|
||||||
|
<h5>
|
||||||
|
Loading...
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-edit"
|
||||||
|
/>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
title="Upload a file to replace the content."
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-upload"
|
||||||
|
/>
|
||||||
|
Replace
|
||||||
|
<input
|
||||||
|
class="hidden"
|
||||||
|
type="file"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
auto
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`FlowView 3`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-detail"
|
||||||
|
>
|
||||||
|
<nav
|
||||||
|
class="nav-tabs nav-tabs-sm"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="active"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
WebSocket
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Error
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Connection
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Timing
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<section
|
||||||
|
class="websocket"
|
||||||
|
>
|
||||||
|
<h4>
|
||||||
|
WebSocket
|
||||||
|
</h4>
|
||||||
|
<div
|
||||||
|
class="contentview"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="controls"
|
||||||
|
>
|
||||||
|
<h5>
|
||||||
|
3 Messages
|
||||||
|
</h5>
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
auto
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-window-close text-muted"
|
||||||
|
/>
|
||||||
|
Closed by server with code 1000 (Close Reason).
|
||||||
|
<small
|
||||||
|
class="pull-right"
|
||||||
|
>
|
||||||
|
1999-12-31 23:00:05.000
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`FlowView 4`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-detail"
|
||||||
|
>
|
||||||
|
<nav
|
||||||
|
class="nav-tabs nav-tabs-sm"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
WebSocket
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Error
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="active"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Connection
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Timing
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<section
|
||||||
|
class="detail"
|
||||||
|
>
|
||||||
|
<h4>
|
||||||
|
Client Connection
|
||||||
|
</h4>
|
||||||
|
<table
|
||||||
|
class="connection-table"
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Address:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
127.0.0.1:22
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<abbr
|
||||||
|
title="TLS Server Name Indication"
|
||||||
|
>
|
||||||
|
SNI
|
||||||
|
</abbr>
|
||||||
|
:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
address
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<abbr
|
||||||
|
title="ALPN protocol negotiated"
|
||||||
|
>
|
||||||
|
ALPN
|
||||||
|
</abbr>
|
||||||
|
:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
http/1.1
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
TLS Version:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
TLSv1.2
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
TLS Cipher:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
cipher
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<h4>
|
||||||
|
Server Connection
|
||||||
|
</h4>
|
||||||
|
<table
|
||||||
|
class="connection-table"
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Address:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
address:22
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Resolved address:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
192.168.0.1:22
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Source address:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
address:22
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<abbr
|
||||||
|
title="TLS Server Name Indication"
|
||||||
|
>
|
||||||
|
SNI
|
||||||
|
</abbr>
|
||||||
|
:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
address
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
TLS Version:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
TLSv1.2
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`FlowView 5`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-detail"
|
||||||
|
>
|
||||||
|
<nav
|
||||||
|
class="nav-tabs nav-tabs-sm"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
WebSocket
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Error
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Connection
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="active"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Timing
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<section
|
||||||
|
class="timing"
|
||||||
|
>
|
||||||
|
<h4>
|
||||||
|
Timing
|
||||||
|
</h4>
|
||||||
|
<table
|
||||||
|
class="timing-table"
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Client conn. established:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:00.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(0ms)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
First request byte:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:00.000
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Client conn. TLS handshake:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:01.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(1s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Request complete:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:01.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(1s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Server conn. initiated:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:02.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(2s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
First response byte:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:02.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(2s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Server conn. TCP handshake:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:03.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(3s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Response complete:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:03.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(3s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
Server conn. TLS handshake:
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
1999-12-31 23:00:04.000
|
||||||
|
<span
|
||||||
|
class="text-muted"
|
||||||
|
>
|
||||||
|
(4s)
|
||||||
|
</span>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`FlowView 6`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flow-detail"
|
||||||
|
>
|
||||||
|
<nav
|
||||||
|
class="nav-tabs nav-tabs-sm"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Request
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Response
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
WebSocket
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="active"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Error
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Connection
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class=""
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
Timing
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
<section
|
||||||
|
class="error"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="alert alert-warning"
|
||||||
|
>
|
||||||
|
error
|
||||||
|
<div>
|
||||||
|
<small>
|
||||||
|
1999-12-31 23:00:07.000
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -1,6 +1,6 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import Dropdown, {Divider, MenuItem, SubMenu} from '../../../components/common/Dropdown'
|
import Dropdown, {Divider, MenuItem, SubMenu} from '../../../components/common/Dropdown'
|
||||||
import {fireEvent, render, screen, waitFor} from '@testing-library/react'
|
import {fireEvent, render, screen, waitFor} from "../../test-utils";
|
||||||
|
|
||||||
|
|
||||||
test('Dropdown', async () => {
|
test('Dropdown', async () => {
|
||||||
@ -18,11 +18,9 @@ test('Dropdown', async () => {
|
|||||||
await waitFor(() => expect(onOpen).toBeCalledWith(true))
|
await waitFor(() => expect(onOpen).toBeCalledWith(true))
|
||||||
expect(asFragment()).toMatchSnapshot()
|
expect(asFragment()).toMatchSnapshot()
|
||||||
|
|
||||||
/*
|
|
||||||
onOpen.mockClear()
|
onOpen.mockClear()
|
||||||
fireEvent.click(document.body)
|
fireEvent.click(document.body)
|
||||||
await waitFor(() => expect(onOpen).toBeCalledWith(false))
|
await waitFor(() => expect(onOpen).toBeCalledWith(false));
|
||||||
*/
|
|
||||||
})
|
})
|
||||||
|
|
||||||
test('SubMenu', async () => {
|
test('SubMenu', async () => {
|
||||||
@ -45,9 +43,9 @@ test('SubMenu', async () => {
|
|||||||
test('MenuItem', async () => {
|
test('MenuItem', async () => {
|
||||||
let click = jest.fn();
|
let click = jest.fn();
|
||||||
const {asFragment} = render(
|
const {asFragment} = render(
|
||||||
<MenuItem onClick={click}>click me</MenuItem>
|
<MenuItem onClick={click}>wtf</MenuItem>
|
||||||
)
|
)
|
||||||
expect(asFragment()).toMatchSnapshot()
|
expect(asFragment()).toMatchSnapshot()
|
||||||
fireEvent.click(screen.getByText("click me"))
|
fireEvent.click(screen.getByText("wtf"))
|
||||||
expect(click).toBeCalled()
|
await waitFor(() => expect(click).toBeCalled());
|
||||||
})
|
})
|
||||||
|
@ -18,8 +18,9 @@ exports[`Button Component should render correctly 1`] = `
|
|||||||
title="title"
|
title="title"
|
||||||
>
|
>
|
||||||
<i
|
<i
|
||||||
className="fa fa-fw icon"
|
className="fa icon"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<a>
|
<a>
|
||||||
foo
|
foo
|
||||||
</a>
|
</a>
|
||||||
|
@ -54,7 +54,7 @@ exports[`MenuItem 1`] = `
|
|||||||
<a
|
<a
|
||||||
href="#"
|
href="#"
|
||||||
>
|
>
|
||||||
click me
|
wtf
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</DocumentFragment>
|
</DocumentFragment>
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
jest.mock("../../../contrib/CodeMirror")
|
||||||
|
import * as React from 'react';
|
||||||
|
import CodeEditor from '../../../components/contentviews/CodeEditor'
|
||||||
|
import {render} from "../../test-utils"
|
||||||
|
|
||||||
|
|
||||||
|
test("CodeEditor", async () => {
|
||||||
|
const {asFragment} = render(<CodeEditor initialContent="foo"/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
@ -0,0 +1,60 @@
|
|||||||
|
import {TFlow} from "../../ducks/tutils";
|
||||||
|
import * as React from 'react';
|
||||||
|
import HttpMessage, {ViewImage} from '../../../components/contentviews/HttpMessage'
|
||||||
|
import {fireEvent, render, screen, waitFor} from "../../test-utils"
|
||||||
|
import fetchMock, {enableFetchMocks} from "jest-fetch-mock";
|
||||||
|
import {SHOW_MAX_LINES} from "../../../components/contentviews/useContent";
|
||||||
|
|
||||||
|
jest.mock("../../../contrib/CodeMirror")
|
||||||
|
|
||||||
|
enableFetchMocks();
|
||||||
|
|
||||||
|
test("HttpMessage", async () => {
|
||||||
|
const lines = Array(SHOW_MAX_LINES).fill([["text", "data"]]).concat(
|
||||||
|
Array(SHOW_MAX_LINES).fill([["text", "additional"]])
|
||||||
|
);
|
||||||
|
|
||||||
|
fetchMock.mockResponses(
|
||||||
|
JSON.stringify({
|
||||||
|
lines: lines.slice(0, SHOW_MAX_LINES + 1),
|
||||||
|
description: "Auto"
|
||||||
|
}), JSON.stringify({
|
||||||
|
lines,
|
||||||
|
description: "Auto"
|
||||||
|
}), JSON.stringify({
|
||||||
|
lines: Array(5).fill([["text", "rawdata"]]),
|
||||||
|
description: "Raw",
|
||||||
|
}),
|
||||||
|
"raw content",
|
||||||
|
JSON.stringify({
|
||||||
|
lines: Array(5).fill([["text", "rawdata"]]),
|
||||||
|
description: "Raw",
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
const tflow = TFlow();
|
||||||
|
const {asFragment} = render(<HttpMessage flow={tflow} message={tflow.request}/>);
|
||||||
|
await waitFor(() => screen.getAllByText("data"));
|
||||||
|
expect(screen.queryByText('additional')).toBeNull();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Show more"));
|
||||||
|
await waitFor(() => screen.getAllByText("additional"));
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("auto"));
|
||||||
|
fireEvent.click(screen.getByText("raw"));
|
||||||
|
await waitFor(() => screen.getAllByText("rawdata"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.click(screen.getByText("Edit"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
fireEvent.click(screen.getByText("Cancel"));
|
||||||
|
|
||||||
|
await waitFor(() => screen.getAllByText("rawdata"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("ViewImage", async () => {
|
||||||
|
const flow = TFlow();
|
||||||
|
const {asFragment} = render(<ViewImage flow={flow} message={flow.request}/>)
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
});
|
@ -0,0 +1,28 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import LineRenderer from '../../../components/contentviews/LineRenderer'
|
||||||
|
import {fireEvent, render, screen} from "../../test-utils"
|
||||||
|
|
||||||
|
|
||||||
|
test("LineRenderer", async () => {
|
||||||
|
const lines: [style: string, text: string][][] = [
|
||||||
|
[
|
||||||
|
["header", "foo: "],
|
||||||
|
["text", "42"]
|
||||||
|
],
|
||||||
|
[
|
||||||
|
["header", "bar: "],
|
||||||
|
["text", "43"]
|
||||||
|
],
|
||||||
|
]
|
||||||
|
|
||||||
|
const showMore = jest.fn();
|
||||||
|
const {asFragment} = render(<LineRenderer lines={lines} maxLines={1} showMore={showMore}/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
fireEvent.click(screen.getByText("Show more"));
|
||||||
|
expect(showMore).toBeCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("No lines", async () => {
|
||||||
|
const {asFragment} = render(<LineRenderer lines={[]} maxLines={1} showMore={() => 0}/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
})
|
@ -0,0 +1,15 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import ViewSelector from '../../../components/contentviews/ViewSelector'
|
||||||
|
import {fireEvent, render, screen} from "../../test-utils"
|
||||||
|
|
||||||
|
|
||||||
|
test("ViewSelector", async () => {
|
||||||
|
|
||||||
|
const onChange = jest.fn();
|
||||||
|
const {asFragment} = render(<ViewSelector value="Auto" onChange={onChange}/>);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
fireEvent.click(screen.getByText("auto"));
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
fireEvent.click(screen.getByText("raw"));
|
||||||
|
expect(onChange).toBeCalledWith("Raw");
|
||||||
|
});
|
@ -0,0 +1,241 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`HttpMessage 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="contentview"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="controls"
|
||||||
|
>
|
||||||
|
<h5>
|
||||||
|
Raw
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-edit"
|
||||||
|
/>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
title="Upload a file to replace the content."
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-upload"
|
||||||
|
/>
|
||||||
|
Replace
|
||||||
|
<input
|
||||||
|
class="hidden"
|
||||||
|
type="file"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
raw
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<pre>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`HttpMessage 2`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="contentview"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="controls"
|
||||||
|
>
|
||||||
|
<h5>
|
||||||
|
[Editing]
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-check text-success"
|
||||||
|
/>
|
||||||
|
Done
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-times text-danger"
|
||||||
|
/>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="codeeditor"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`HttpMessage 3`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="contentview"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="controls"
|
||||||
|
>
|
||||||
|
<h5>
|
||||||
|
Raw
|
||||||
|
</h5>
|
||||||
|
<button
|
||||||
|
class="btn-xs btn btn-default"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-edit"
|
||||||
|
/>
|
||||||
|
Edit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
title="Upload a file to replace the content."
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-upload"
|
||||||
|
/>
|
||||||
|
Replace
|
||||||
|
<input
|
||||||
|
class="hidden"
|
||||||
|
type="file"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
raw
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<pre>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
rawdata
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</pre>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`ViewImage 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<div
|
||||||
|
class="flowview-image"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="preview"
|
||||||
|
class="img-thumbnail"
|
||||||
|
src="./flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/request/content.data"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -0,0 +1,31 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`LineRenderer 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<pre>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="header"
|
||||||
|
>
|
||||||
|
foo:
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="text"
|
||||||
|
>
|
||||||
|
42
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
class="btn btn-xs btn-info"
|
||||||
|
>
|
||||||
|
<i
|
||||||
|
aria-hidden="true"
|
||||||
|
class="fa fa-angle-double-down"
|
||||||
|
/>
|
||||||
|
Show more
|
||||||
|
</button>
|
||||||
|
</pre>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`No lines 1`] = `<DocumentFragment />`;
|
@ -0,0 +1,66 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`ViewSelector 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
auto
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`ViewSelector 2`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<a
|
||||||
|
class="btn btn-default btn-xs open"
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
<i
|
||||||
|
class="fa fa-fw fa-files-o"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<b>
|
||||||
|
View:
|
||||||
|
</b>
|
||||||
|
auto
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
<ul
|
||||||
|
class="dropdown-menu show"
|
||||||
|
style="position: absolute; left: 0px; top: 0px;"
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
auto
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
>
|
||||||
|
raw
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -0,0 +1,31 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import {render, screen, waitFor} from "../../test-utils"
|
||||||
|
import {useContent} from "../../../components/contentviews/useContent";
|
||||||
|
import fetchMock, {enableFetchMocks} from 'jest-fetch-mock'
|
||||||
|
|
||||||
|
enableFetchMocks()
|
||||||
|
|
||||||
|
|
||||||
|
function TComp({url, hash}: { url: string, hash: string }) {
|
||||||
|
const content = useContent(url, hash);
|
||||||
|
return <div>{content}</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
test("caching", async () => {
|
||||||
|
fetchMock.mockResponses("hello", "world");
|
||||||
|
const {rerender} = render(<TComp url="/content" hash="hash"/>);
|
||||||
|
|
||||||
|
await waitFor(() => screen.getByText("hello"));
|
||||||
|
rerender(<TComp url="/content" hash="hash"/>);
|
||||||
|
expect(fetchMock.mock.calls).toHaveLength(1);
|
||||||
|
|
||||||
|
rerender(<TComp url="/content" hash="newhash"/>);
|
||||||
|
await waitFor(() => screen.getByText("world"));
|
||||||
|
expect(fetchMock.mock.calls).toHaveLength(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("network error", async () => {
|
||||||
|
fetchMock.mockRejectOnce(new Error("I/O error"));
|
||||||
|
render(<TComp url="/content" hash="hash"/>);
|
||||||
|
await waitFor(() => screen.getByText("Error getting content: Error: I/O error."));
|
||||||
|
});
|
@ -0,0 +1,27 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import ValidateEditor from '../../../components/editors/ValidateEditor'
|
||||||
|
import {fireEvent, render, screen, waitFor} from "../../test-utils";
|
||||||
|
|
||||||
|
test("ValidateEditor", async () => {
|
||||||
|
const onEditDone = jest.fn();
|
||||||
|
const {asFragment} = render(
|
||||||
|
<ValidateEditor content="ok" isValid={x => x.includes("ok")} onEditDone={onEditDone}/>
|
||||||
|
);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
fireEvent.mouseDown(screen.getByText("ok"));
|
||||||
|
fireEvent.mouseUp(screen.getByText("ok"));
|
||||||
|
|
||||||
|
screen.getByText("ok").innerHTML = "this is ok";
|
||||||
|
|
||||||
|
fireEvent.blur(screen.getByText("this is ok"));
|
||||||
|
|
||||||
|
await waitFor(() => expect(onEditDone).toBeCalledWith("this is ok"));
|
||||||
|
onEditDone.mockClear();
|
||||||
|
|
||||||
|
fireEvent.mouseDown(screen.getByText("this is ok"));
|
||||||
|
fireEvent.mouseUp(screen.getByText("this is ok"));
|
||||||
|
screen.getByText("this is ok").innerHTML = "wat";
|
||||||
|
fireEvent.blur(screen.getByText("wat"));
|
||||||
|
expect(screen.getByText("ok")).toBeDefined();
|
||||||
|
});
|
21
web/src/js/__tests__/components/editors/ValueEditorSpec.tsx
Normal file
21
web/src/js/__tests__/components/editors/ValueEditorSpec.tsx
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import * as React from "react"
|
||||||
|
import ValueEditor from '../../../components/editors/ValueEditor'
|
||||||
|
import {render, waitFor} from "../../test-utils";
|
||||||
|
|
||||||
|
test("ValueEditor", async () => {
|
||||||
|
const onEditDone = jest.fn();
|
||||||
|
let editor: { current?: ValueEditor | null } = {}
|
||||||
|
const {asFragment} = render(
|
||||||
|
<ValueEditor ref={x => editor.current = x} content="hello world" onEditDone={onEditDone}/>
|
||||||
|
);
|
||||||
|
expect(asFragment()).toMatchSnapshot();
|
||||||
|
|
||||||
|
if (!editor.current)
|
||||||
|
throw "err";
|
||||||
|
|
||||||
|
editor.current.startEditing();
|
||||||
|
await waitFor(() => expect(editor.current?.isEditing()).toBeTruthy());
|
||||||
|
|
||||||
|
editor.current.finishEditing();
|
||||||
|
await waitFor(() => expect(onEditDone).toBeCalledWith("hello world"));
|
||||||
|
});
|
@ -0,0 +1,12 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`ValidateEditor 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<span
|
||||||
|
class="inline-input has-success"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
ok
|
||||||
|
</span>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -0,0 +1,12 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`ValueEditor 1`] = `
|
||||||
|
<DocumentFragment>
|
||||||
|
<span
|
||||||
|
class="inline-input"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
hello world
|
||||||
|
</span>
|
||||||
|
</DocumentFragment>
|
||||||
|
`;
|
@ -1,18 +1,11 @@
|
|||||||
/** Auto-generated by test_app.py:TestApp._test_generate_tflow_js */
|
/** Auto-generated by test_app.py:TestApp.test_generate_tflow_js */
|
||||||
import {HTTPFlow} from '../../flow';
|
import {HTTPFlow} from '../../flow';
|
||||||
export default function(): HTTPFlow {
|
export default function(): Required<HTTPFlow> {
|
||||||
return {
|
return {
|
||||||
"client_conn": {
|
"client_conn": {
|
||||||
//@ts-ignore
|
|
||||||
"address": [
|
|
||||||
"127.0.0.1",
|
|
||||||
22
|
|
||||||
],
|
|
||||||
"alpn": "http/1.1",
|
"alpn": "http/1.1",
|
||||||
//@ts-ignore
|
"cert": undefined,
|
||||||
"alpn_proto_negotiated": "http/1.1",
|
|
||||||
"cipher": "cipher",
|
"cipher": "cipher",
|
||||||
"cipher_name": "cipher",
|
|
||||||
"id": "4a18d1a0-50a1-48dd-9aa6-d45d74282939",
|
"id": "4a18d1a0-50a1-48dd-9aa6-d45d74282939",
|
||||||
"peername": [
|
"peername": [
|
||||||
"127.0.0.1",
|
"127.0.0.1",
|
||||||
@ -97,14 +90,9 @@ export default function(): HTTPFlow {
|
|||||||
22
|
22
|
||||||
],
|
],
|
||||||
"alpn": undefined,
|
"alpn": undefined,
|
||||||
//@ts-ignore
|
"cert": undefined,
|
||||||
"alpn_proto_negotiated": undefined,
|
|
||||||
"cipher": undefined,
|
"cipher": undefined,
|
||||||
"id": "f087e7b2-6d0a-41a8-a8f0-e1a4761395f8",
|
"id": "f087e7b2-6d0a-41a8-a8f0-e1a4761395f8",
|
||||||
"ip_address": [
|
|
||||||
"192.168.0.1",
|
|
||||||
22
|
|
||||||
],
|
|
||||||
"peername": [
|
"peername": [
|
||||||
"192.168.0.1",
|
"192.168.0.1",
|
||||||
22
|
22
|
||||||
@ -114,10 +102,6 @@ export default function(): HTTPFlow {
|
|||||||
"address",
|
"address",
|
||||||
22
|
22
|
||||||
],
|
],
|
||||||
"source_address": [
|
|
||||||
"address",
|
|
||||||
22
|
|
||||||
],
|
|
||||||
"timestamp_end": 946681205,
|
"timestamp_end": 946681205,
|
||||||
"timestamp_start": 946681202,
|
"timestamp_start": 946681202,
|
||||||
"timestamp_tcp_setup": 946681203,
|
"timestamp_tcp_setup": 946681203,
|
||||||
@ -125,6 +109,16 @@ export default function(): HTTPFlow {
|
|||||||
"tls_established": true,
|
"tls_established": true,
|
||||||
"tls_version": "TLSv1.2"
|
"tls_version": "TLSv1.2"
|
||||||
},
|
},
|
||||||
"type": "http"
|
"type": "http",
|
||||||
|
"websocket": {
|
||||||
|
"close_code": 1000,
|
||||||
|
"close_reason": "Close Reason",
|
||||||
|
"closed_by_client": false,
|
||||||
|
"messages_meta": {
|
||||||
|
"count": 3,
|
||||||
|
"timestamp_last": 946681205
|
||||||
|
},
|
||||||
|
"timestamp_end": 946681205
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import reduceEventLog, * as eventLogActions from '../../ducks/eventLog'
|
import reduceEventLog, * as eventLogActions from '../../ducks/eventLog'
|
||||||
import reduce from '../../ducks/utils/store'
|
import {reduce} from '../../ducks/utils/store'
|
||||||
|
|
||||||
describe('event log reducer', () => {
|
describe('event log reducer', () => {
|
||||||
it('should return initial state', () => {
|
it('should return initial state', () => {
|
||||||
|
@ -1,226 +0,0 @@
|
|||||||
jest.mock('../../utils')
|
|
||||||
|
|
||||||
import reduceFlows from "../../ducks/flows"
|
|
||||||
import * as flowActions from "../../ducks/flows"
|
|
||||||
import reduce from "../../ducks/utils/store"
|
|
||||||
import { fetchApi } from "../../utils"
|
|
||||||
import { createStore } from "./tutils"
|
|
||||||
|
|
||||||
describe('flow reducer', () => {
|
|
||||||
let state = undefined
|
|
||||||
for (let i of [1, 2, 3, 4]) {
|
|
||||||
state = reduceFlows(state, { type: flowActions.ADD, data: { id: i }, cmd: 'add' })
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should return initial state', () => {
|
|
||||||
expect(reduceFlows(undefined, {})).toEqual({
|
|
||||||
highlight: null,
|
|
||||||
filter: null,
|
|
||||||
sort: { column: null, desc: false },
|
|
||||||
selected: [],
|
|
||||||
...reduce(undefined, {})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('selections', () => {
|
|
||||||
it('should be possible to select a single flow', () => {
|
|
||||||
expect(reduceFlows(state, flowActions.select(2))).toEqual(
|
|
||||||
{
|
|
||||||
...state,
|
|
||||||
selected: [2],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to deselect a flow', () => {
|
|
||||||
expect(reduceFlows({ ...state, selected: [1] }, flowActions.select())).toEqual(
|
|
||||||
{
|
|
||||||
...state,
|
|
||||||
selected: [],
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to select relative', () => {
|
|
||||||
// haven't selected any flow
|
|
||||||
expect(
|
|
||||||
flowActions.selectRelative(state, 1)
|
|
||||||
).toEqual(
|
|
||||||
flowActions.select(4)
|
|
||||||
)
|
|
||||||
|
|
||||||
// already selected some flows
|
|
||||||
expect(
|
|
||||||
flowActions.selectRelative({ ...state, selected: [2] }, 1)
|
|
||||||
).toEqual(
|
|
||||||
flowActions.select(3)
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should update state.selected on remove', () => {
|
|
||||||
let next
|
|
||||||
next = reduceFlows({ ...state, selected: [2] }, {
|
|
||||||
type: flowActions.REMOVE,
|
|
||||||
data: 2,
|
|
||||||
cmd: 'remove'
|
|
||||||
})
|
|
||||||
expect(next.selected).toEqual([3])
|
|
||||||
|
|
||||||
//last row
|
|
||||||
next = reduceFlows({ ...state, selected: [4] }, {
|
|
||||||
type: flowActions.REMOVE,
|
|
||||||
data: 4,
|
|
||||||
cmd: 'remove'
|
|
||||||
})
|
|
||||||
expect(next.selected).toEqual([3])
|
|
||||||
|
|
||||||
//multiple selection
|
|
||||||
next = reduceFlows({ ...state, selected: [2, 3, 4] }, {
|
|
||||||
type: flowActions.REMOVE,
|
|
||||||
data: 3,
|
|
||||||
cmd: 'remove'
|
|
||||||
})
|
|
||||||
expect(next.selected).toEqual([2, 4])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to set filter', () => {
|
|
||||||
let filt = "~u 123"
|
|
||||||
expect(reduceFlows(undefined, flowActions.setFilter(filt)).filter).toEqual(filt)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to set highlight', () => {
|
|
||||||
let key = "foo"
|
|
||||||
expect(reduceFlows(undefined, flowActions.setHighlight(key)).highlight).toEqual(key)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to set sort', () => {
|
|
||||||
let sort = { column: "TLSColumn", desc: 1 }
|
|
||||||
expect(reduceFlows(undefined, flowActions.setSort(sort.column, sort.desc)).sort).toEqual(sort)
|
|
||||||
})
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('flows actions', () => {
|
|
||||||
|
|
||||||
let store = createStore({ reduceFlows })
|
|
||||||
|
|
||||||
let tflow = { id: 1 }
|
|
||||||
it('should handle resume action', () => {
|
|
||||||
store.dispatch(flowActions.resume(tflow))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1/resume', { method: 'POST' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle resumeAll action', () => {
|
|
||||||
store.dispatch(flowActions.resumeAll())
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/resume', { method: 'POST' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle kill action', () => {
|
|
||||||
store.dispatch(flowActions.kill(tflow))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1/kill', { method: 'POST' })
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle killAll action', () => {
|
|
||||||
store.dispatch(flowActions.killAll())
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/kill', { method: 'POST' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle remove action', () => {
|
|
||||||
store.dispatch(flowActions.remove(tflow))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1', { method: 'DELETE' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle duplicate action', () => {
|
|
||||||
store.dispatch(flowActions.duplicate(tflow))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1/duplicate', { method: 'POST' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle replay action', () => {
|
|
||||||
store.dispatch(flowActions.replay(tflow))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1/replay', { method: 'POST' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle revert action', () => {
|
|
||||||
store.dispatch(flowActions.revert(tflow))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1/revert', { method: 'POST' })
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle update action', () => {
|
|
||||||
store.dispatch(flowActions.update(tflow, 'foo'))
|
|
||||||
expect(fetchApi.put).toBeCalledWith('/flows/1', 'foo')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle uploadContent action', () => {
|
|
||||||
let body = new FormData(),
|
|
||||||
file = new window.Blob(['foo'], { type: 'plain/text' })
|
|
||||||
body.append('file', file)
|
|
||||||
store.dispatch(flowActions.uploadContent(tflow, 'foo', 'foo'))
|
|
||||||
// window.Blob's lastModified is always the current time,
|
|
||||||
// which causes flaky tests on comparison.
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/1/foo/content.data', { method: 'POST', body: expect.anything()})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle clear action', () => {
|
|
||||||
store.dispatch(flowActions.clear())
|
|
||||||
expect(fetchApi).toBeCalledWith('/clear', { method: 'POST'} )
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle download action', () => {
|
|
||||||
let state = reduceFlows(undefined, {})
|
|
||||||
expect(reduceFlows(state, flowActions.download())).toEqual(state)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle upload action', () => {
|
|
||||||
let body = new FormData()
|
|
||||||
body.append('file', 'foo')
|
|
||||||
store.dispatch(flowActions.upload('foo'))
|
|
||||||
expect(fetchApi).toBeCalledWith('/flows/dump', { method: 'POST', body })
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('makeSort', () => {
|
|
||||||
it('should be possible to sort by TLSColumn', () => {
|
|
||||||
let sort = flowActions.makeSort({ column: 'TLSColumn', desc: true }),
|
|
||||||
a = { request: { scheme: 'http' } },
|
|
||||||
b = { request: { scheme: 'https' } }
|
|
||||||
expect(sort(a, b)).toEqual(1)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to sort by PathColumn', () => {
|
|
||||||
let sort = flowActions.makeSort({ column: 'PathColumn', desc: true }),
|
|
||||||
a = { request: {} },
|
|
||||||
b = { request: {} }
|
|
||||||
expect(sort(a, b)).toEqual(0)
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to sort by MethodColumn', () => {
|
|
||||||
let sort = flowActions.makeSort({ column: 'MethodColumn', desc: true }),
|
|
||||||
a = { request: { method: 'GET' } },
|
|
||||||
b = { request: { method: 'POST' } }
|
|
||||||
expect(sort(b, a)).toEqual(-1)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to sort by StatusColumn', () => {
|
|
||||||
let sort = flowActions.makeSort({ column: 'StatusColumn', desc: false }),
|
|
||||||
a = { response: { status_code: 200 } },
|
|
||||||
b = { response: { status_code: 404 } }
|
|
||||||
expect(sort(a, b)).toEqual(-1)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to sort by TimeColumn', () => {
|
|
||||||
let sort = flowActions.makeSort({ column: 'TimeColumn', desc: false }),
|
|
||||||
a = { response: { timestamp_end: 9 }, request: { timestamp_start: 8 } },
|
|
||||||
b = { response: { timestamp_end: 10 }, request: { timestamp_start: 8 } }
|
|
||||||
expect(sort(b, a)).toEqual(1)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should be possible to sort by SizeColumn', () => {
|
|
||||||
let sort = flowActions.makeSort({ column: 'SizeColumn', desc: true }),
|
|
||||||
a = { request: { contentLength: 1 }, response: { contentLength: 1 } },
|
|
||||||
b = { request: { contentLength: 1 } }
|
|
||||||
expect(sort(a, b)).toEqual(-1)
|
|
||||||
})
|
|
||||||
})
|
|
197
web/src/js/__tests__/ducks/flowsSpec.tsx
Normal file
197
web/src/js/__tests__/ducks/flowsSpec.tsx
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
import reduceFlows, * as flowActions from "../../ducks/flows";
|
||||||
|
import {reduce} from "../../ducks/utils/store"
|
||||||
|
import {fetchApi} from "../../utils"
|
||||||
|
import {TFlow, TStore} from "./tutils"
|
||||||
|
import FlowColumns from "../../components/FlowTable/FlowColumns"
|
||||||
|
|
||||||
|
jest.mock('../../utils')
|
||||||
|
|
||||||
|
describe('flow reducer', () => {
|
||||||
|
|
||||||
|
let s;
|
||||||
|
for (let i of ["1", "2", "3", "4"]) {
|
||||||
|
s = reduceFlows(s, {type: flowActions.ADD, data: {id: i}, cmd: 'add'})
|
||||||
|
}
|
||||||
|
let state = s;
|
||||||
|
|
||||||
|
it('should return initial state', () => {
|
||||||
|
expect(reduceFlows(undefined, {})).toEqual({
|
||||||
|
highlight: undefined,
|
||||||
|
filter: undefined,
|
||||||
|
sort: {column: undefined, desc: false},
|
||||||
|
selected: [],
|
||||||
|
...reduce(undefined, {})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('selections', () => {
|
||||||
|
it('should be possible to select a single flow', () => {
|
||||||
|
expect(reduceFlows(state, flowActions.select("2"))).toEqual(
|
||||||
|
{
|
||||||
|
...state,
|
||||||
|
selected: ["2"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be possible to deselect a flow', () => {
|
||||||
|
expect(reduceFlows({...state, selected: ["1"]}, flowActions.select())).toEqual(
|
||||||
|
{
|
||||||
|
...state,
|
||||||
|
selected: [],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be possible to select relative', () => {
|
||||||
|
// haven't selected any flow
|
||||||
|
expect(
|
||||||
|
flowActions.selectRelative(state, 1)
|
||||||
|
).toEqual(
|
||||||
|
flowActions.select("4")
|
||||||
|
)
|
||||||
|
|
||||||
|
// already selected some flows
|
||||||
|
expect(
|
||||||
|
flowActions.selectRelative({...state, selected: [2]}, 1)
|
||||||
|
).toEqual(
|
||||||
|
flowActions.select("3")
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should update state.selected on remove', () => {
|
||||||
|
let next
|
||||||
|
next = reduceFlows({...state, selected: ["2"]}, {
|
||||||
|
type: flowActions.REMOVE,
|
||||||
|
data: "2",
|
||||||
|
cmd: 'remove'
|
||||||
|
})
|
||||||
|
expect(next.selected).toEqual(["3"])
|
||||||
|
|
||||||
|
//last row
|
||||||
|
next = reduceFlows({...state, selected: ["4"]}, {
|
||||||
|
type: flowActions.REMOVE,
|
||||||
|
data: "4",
|
||||||
|
cmd: 'remove'
|
||||||
|
})
|
||||||
|
expect(next.selected).toEqual(["3"])
|
||||||
|
|
||||||
|
//multiple selection
|
||||||
|
next = reduceFlows({...state, selected: ["2", "3", "4"]}, {
|
||||||
|
type: flowActions.REMOVE,
|
||||||
|
data: "3",
|
||||||
|
cmd: 'remove'
|
||||||
|
})
|
||||||
|
expect(next.selected).toEqual(["2", "4"])
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be possible to set filter', () => {
|
||||||
|
let filt = "~u 123"
|
||||||
|
expect(reduceFlows(undefined, flowActions.setFilter(filt)).filter).toEqual(filt)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be possible to set highlight', () => {
|
||||||
|
let key = "foo"
|
||||||
|
expect(reduceFlows(undefined, flowActions.setHighlight(key)).highlight).toEqual(key)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should be possible to set sort', () => {
|
||||||
|
let sort = {column: "tls", desc: true}
|
||||||
|
expect(reduceFlows(undefined, flowActions.setSort(sort.column, sort.desc)).sort).toEqual(sort)
|
||||||
|
})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('flows actions', () => {
|
||||||
|
|
||||||
|
let store = TStore();
|
||||||
|
let tflow = TFlow();
|
||||||
|
|
||||||
|
it('should handle resume action', () => {
|
||||||
|
store.dispatch(flowActions.resume(tflow))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/resume', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle resumeAll action', () => {
|
||||||
|
store.dispatch(flowActions.resumeAll())
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/resume', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle kill action', () => {
|
||||||
|
store.dispatch(flowActions.kill(tflow))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/kill', {method: 'POST'})
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle killAll action', () => {
|
||||||
|
store.dispatch(flowActions.killAll())
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/kill', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle remove action', () => {
|
||||||
|
store.dispatch(flowActions.remove(tflow))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29', {method: 'DELETE'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle duplicate action', () => {
|
||||||
|
store.dispatch(flowActions.duplicate(tflow))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/duplicate', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle replay action', () => {
|
||||||
|
store.dispatch(flowActions.replay(tflow))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/replay', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle revert action', () => {
|
||||||
|
store.dispatch(flowActions.revert(tflow))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/revert', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle update action', () => {
|
||||||
|
store.dispatch(flowActions.update(tflow, 'foo'))
|
||||||
|
expect(fetchApi.put).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29', 'foo')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle uploadContent action', () => {
|
||||||
|
let body = new FormData(),
|
||||||
|
file = new window.Blob(['foo'], {type: 'plain/text'})
|
||||||
|
body.append('file', file)
|
||||||
|
store.dispatch(flowActions.uploadContent(tflow, 'foo', 'foo'))
|
||||||
|
// window.Blob's lastModified is always the current time,
|
||||||
|
// which causes flaky tests on comparison.
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/d91165be-ca1f-4612-88a9-c0f8696f3e29/foo/content.data', {
|
||||||
|
method: 'POST',
|
||||||
|
body: expect.anything()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle clear action', () => {
|
||||||
|
store.dispatch(flowActions.clear())
|
||||||
|
expect(fetchApi).toBeCalledWith('/clear', {method: 'POST'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle download action', () => {
|
||||||
|
let state = reduceFlows(undefined, {})
|
||||||
|
expect(reduceFlows(state, flowActions.download())).toEqual(state)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle upload action', () => {
|
||||||
|
let body = new FormData()
|
||||||
|
body.append('file', 'foo')
|
||||||
|
store.dispatch(flowActions.upload('foo'))
|
||||||
|
expect(fetchApi).toBeCalledWith('/flows/dump', {method: 'POST', body})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("makeSort", () => {
|
||||||
|
const a = TFlow(), b = TFlow();
|
||||||
|
|
||||||
|
Object.keys(FlowColumns).forEach((column) => {
|
||||||
|
// @ts-ignore
|
||||||
|
const sort = flowActions.makeSort({column, desc: true});
|
||||||
|
expect(sort(a, b)).toBeDefined();
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
@ -1,69 +0,0 @@
|
|||||||
import reduceOptions, * as OptionsActions from '../../ducks/options'
|
|
||||||
|
|
||||||
import configureStore from 'redux-mock-store'
|
|
||||||
import thunk from 'redux-thunk'
|
|
||||||
import * as OptionsEditorActions from '../../ducks/ui/optionsEditor'
|
|
||||||
import {updateError} from "../../ducks/ui/optionsEditor";
|
|
||||||
|
|
||||||
const mockStore = configureStore([ thunk ])
|
|
||||||
|
|
||||||
describe('option reducer', () => {
|
|
||||||
it('should return initial state', () => {
|
|
||||||
expect(reduceOptions(undefined, {})).toEqual(OptionsActions.defaultState)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle receive action', () => {
|
|
||||||
let action = { type: OptionsActions.RECEIVE, data: {id: {value: 'foo'} } }
|
|
||||||
expect(reduceOptions(undefined, action)).toEqual({id: 'foo'})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should handle update action', () => {
|
|
||||||
let action = {type: OptionsActions.UPDATE, data: {id: {value: 1} } }
|
|
||||||
expect(reduceOptions(undefined, action)).toEqual({...OptionsActions.defaultState, id: 1})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('option actions', () => {
|
|
||||||
|
|
||||||
it('should be possible to update option', () => {
|
|
||||||
let store = mockStore()
|
|
||||||
let mockResponse = { status: 200 },
|
|
||||||
promise = Promise.resolve(mockResponse)
|
|
||||||
global.fetch = r => { return promise }
|
|
||||||
store.dispatch(OptionsActions.update('foo', 'bar'))
|
|
||||||
expect(store.getActions()).toEqual([
|
|
||||||
{ type: OptionsEditorActions.OPTION_UPDATE_START, option: 'foo', value: 'bar'}
|
|
||||||
])
|
|
||||||
store.clearActions()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('sendUpdate', () => {
|
|
||||||
|
|
||||||
it('should handle error', async () => {
|
|
||||||
let store = mockStore()
|
|
||||||
let mockResponse = { status: 404, text: () => "fooerror" },
|
|
||||||
promise = Promise.resolve(mockResponse)
|
|
||||||
global.fetch = r => { return promise }
|
|
||||||
await store.dispatch(OptionsActions.pureSendUpdate("bar", "error"))
|
|
||||||
expect(store.getActions()).toEqual([
|
|
||||||
OptionsEditorActions.updateError("bar", "fooerror")
|
|
||||||
])
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
describe('save', () => {
|
|
||||||
|
|
||||||
it('should dump options', () => {
|
|
||||||
let store = mockStore()
|
|
||||||
global.fetch = jest.fn()
|
|
||||||
store.dispatch(OptionsActions.save())
|
|
||||||
expect(fetch).toBeCalledWith(
|
|
||||||
'./options/save?_xsrf=undefined',
|
|
||||||
{
|
|
||||||
credentials: "same-origin",
|
|
||||||
method: "POST"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
})
|
|
||||||
})
|
|
40
web/src/js/__tests__/ducks/optionsSpec.tsx
Normal file
40
web/src/js/__tests__/ducks/optionsSpec.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import reduceOptions, * as OptionsActions from '../../ducks/options'
|
||||||
|
import * as OptionsEditorActions from '../../ducks/ui/optionsEditor'
|
||||||
|
import {enableFetchMocks} from "jest-fetch-mock";
|
||||||
|
import {TStore} from "./tutils";
|
||||||
|
|
||||||
|
|
||||||
|
describe('option reducer', () => {
|
||||||
|
it('should return initial state', () => {
|
||||||
|
expect(reduceOptions(undefined, {type: "other"})).toEqual(OptionsActions.defaultState)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle receive action', () => {
|
||||||
|
let action = {type: OptionsActions.RECEIVE, data: {id: {value: 'foo'}}}
|
||||||
|
expect(reduceOptions(undefined, action)).toEqual({id: 'foo'})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle update action', () => {
|
||||||
|
let action = {type: OptionsActions.UPDATE, data: {id: {value: 1}}}
|
||||||
|
expect(reduceOptions(undefined, action)).toEqual({...OptionsActions.defaultState, id: 1})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test("sendUpdate", async () => {
|
||||||
|
enableFetchMocks();
|
||||||
|
let store = TStore();
|
||||||
|
|
||||||
|
fetchMock.mockResponseOnce("fooerror", {status: 404});
|
||||||
|
await store.dispatch(dispatch => OptionsActions.pureSendUpdate("intercept", "~~~", dispatch))
|
||||||
|
expect(store.getActions()).toEqual([
|
||||||
|
OptionsEditorActions.updateError("intercept", "fooerror")
|
||||||
|
])
|
||||||
|
|
||||||
|
store.clearActions();
|
||||||
|
fetchMock.mockResponseOnce("", {status: 200});
|
||||||
|
await store.dispatch(dispatch => OptionsActions.pureSendUpdate("intercept", "valid", dispatch))
|
||||||
|
expect(store.getActions()).toEqual([
|
||||||
|
OptionsEditorActions.updateSuccess("intercept")
|
||||||
|
])
|
||||||
|
|
||||||
|
});
|
@ -1,21 +1,13 @@
|
|||||||
import {applyMiddleware, combineReducers, createStore as createReduxStore} from 'redux'
|
|
||||||
import thunk from 'redux-thunk'
|
import thunk from 'redux-thunk'
|
||||||
import configureStore, {MockStoreCreator, MockStoreEnhanced} from 'redux-mock-store'
|
import configureStore, {MockStoreCreator, MockStoreEnhanced} from 'redux-mock-store'
|
||||||
import {ConnectionState} from '../../ducks/connection'
|
import {ConnectionState} from '../../ducks/connection'
|
||||||
import TFlow from './_tflow'
|
import TFlow from './_tflow'
|
||||||
import {RootState} from "../../ducks";
|
import {AppDispatch, RootState} from "../../ducks";
|
||||||
import {HTTPFlow} from "../../flow";
|
import {HTTPFlow} from "../../flow";
|
||||||
import {defaultState as defaultConf} from "../../ducks/conf"
|
import {defaultState as defaultConf} from "../../ducks/conf"
|
||||||
import {defaultState as defaultOptions} from "../../ducks/options"
|
import {defaultState as defaultOptions} from "../../ducks/options"
|
||||||
|
|
||||||
const mockStoreCreator: MockStoreCreator<RootState> = configureStore([thunk])
|
const mockStoreCreator: MockStoreCreator<RootState, AppDispatch> = configureStore([thunk])
|
||||||
|
|
||||||
export function createStore(parts) {
|
|
||||||
return createReduxStore(
|
|
||||||
combineReducers(parts),
|
|
||||||
applyMiddleware(...[thunk])
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export {TFlow}
|
export {TFlow}
|
||||||
|
|
||||||
@ -63,18 +55,9 @@ export const testState: RootState = {
|
|||||||
},
|
},
|
||||||
ui: {
|
ui: {
|
||||||
flow: {
|
flow: {
|
||||||
contentView: 'Auto',
|
contentViewFor: {},
|
||||||
displayLarge: false,
|
|
||||||
showFullContent: true,
|
|
||||||
maxContentLines: 10,
|
|
||||||
content: [[['foo', 'bar']]],
|
|
||||||
viewDescription: 'foo',
|
|
||||||
modifiedFlow: undefined,
|
|
||||||
tab: 'request'
|
tab: 'request'
|
||||||
},
|
},
|
||||||
header: {
|
|
||||||
tab: 'Start'
|
|
||||||
},
|
|
||||||
modal: {
|
modal: {
|
||||||
activeModal: undefined
|
activeModal: undefined
|
||||||
},
|
},
|
||||||
@ -87,15 +70,18 @@ export const testState: RootState = {
|
|||||||
},
|
},
|
||||||
options: defaultOptions,
|
options: defaultOptions,
|
||||||
flows: {
|
flows: {
|
||||||
selected: [tflow1.id],
|
selected: [tflow2.id],
|
||||||
byId: {[tflow1.id]: tflow1, [tflow2.id]: tflow2},
|
byId: {[tflow1.id]: tflow1, [tflow2.id]: tflow2},
|
||||||
filter: '~d address',
|
filter: '~u /second',
|
||||||
highlight: '~u /path',
|
highlight: '~u /path',
|
||||||
sort: {
|
sort: {
|
||||||
desc: true,
|
desc: true,
|
||||||
column: 'PathColumn'
|
column: "path"
|
||||||
},
|
},
|
||||||
view: [tflow1, tflow2]
|
view: [tflow2],
|
||||||
|
list: [tflow1, tflow2],
|
||||||
|
listIndex: {[tflow1.id]: 0, [tflow2.id]: 1},
|
||||||
|
viewIndex: {[tflow2.id]: 0},
|
||||||
},
|
},
|
||||||
connection: {
|
connection: {
|
||||||
state: ConnectionState.ESTABLISHED
|
state: ConnectionState.ESTABLISHED
|
||||||
@ -110,13 +96,20 @@ export const testState: RootState = {
|
|||||||
error: true
|
error: true
|
||||||
},
|
},
|
||||||
view: [
|
view: [
|
||||||
{id: 1, level: 'info', message: 'foo'},
|
{id: "1", level: 'info', message: 'foo'},
|
||||||
{id: 2, level: 'error', message: 'bar'}
|
{id: "2", level: 'error', message: 'bar'}
|
||||||
]
|
],
|
||||||
|
byId: {}, // TODO: incomplete
|
||||||
|
list: [], // TODO: incomplete
|
||||||
|
listIndex: {}, // TODO: incomplete
|
||||||
|
viewIndex: {}, // TODO: incomplete
|
||||||
|
},
|
||||||
|
commandBar: {
|
||||||
|
visible: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function TStore(): MockStoreEnhanced<RootState> {
|
export function TStore(): MockStoreEnhanced<RootState, AppDispatch> {
|
||||||
return mockStoreCreator(testState)
|
return mockStoreCreator(testState)
|
||||||
}
|
}
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
import _ from 'lodash'
|
|
||||||
import reducer, {
|
|
||||||
startEdit,
|
|
||||||
setContentViewDescription,
|
|
||||||
setShowFullContent,
|
|
||||||
setContent,
|
|
||||||
updateEdit,
|
|
||||||
stopEdit,
|
|
||||||
setContentView,
|
|
||||||
selectTab,
|
|
||||||
displayLarge
|
|
||||||
} from '../../../ducks/ui/flow'
|
|
||||||
|
|
||||||
import * as flowActions from '../../../ducks/flows'
|
|
||||||
|
|
||||||
describe('flow reducer', () => {
|
|
||||||
it('should return initial state', () => {
|
|
||||||
expect(reducer(undefined, {})).toEqual({
|
|
||||||
displayLarge: false,
|
|
||||||
viewDescription: '',
|
|
||||||
showFullContent: false,
|
|
||||||
modifiedFlow: undefined,
|
|
||||||
contentView: 'Auto',
|
|
||||||
tab: 'request',
|
|
||||||
content: [],
|
|
||||||
maxContentLines: 80,
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should change to edit mode', () => {
|
|
||||||
let testFlow = {flow : 'foo'}
|
|
||||||
const newState = reducer(undefined, startEdit({ flow: 'foo' }))
|
|
||||||
expect(newState.contentView).toEqual('Edit')
|
|
||||||
expect(newState.modifiedFlow).toEqual(testFlow)
|
|
||||||
expect(newState.showFullContent).toEqual(true)
|
|
||||||
})
|
|
||||||
it('should set the view description', () => {
|
|
||||||
expect(reducer(undefined, setContentViewDescription('description')).viewDescription)
|
|
||||||
.toEqual('description')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should set show full content', () => {
|
|
||||||
expect(reducer({showFullContent: false}, setShowFullContent()).showFullContent)
|
|
||||||
.toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should set showFullContent to true', () => {
|
|
||||||
let maxLines = 10
|
|
||||||
let content = _.range(maxLines)
|
|
||||||
const newState = reducer({maxContentLines: maxLines}, setContent(content) )
|
|
||||||
expect(newState.showFullContent).toBeTruthy()
|
|
||||||
expect(newState.content).toEqual(content)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should set showFullContent to false', () => {
|
|
||||||
let maxLines = 5
|
|
||||||
let content = _.range(maxLines+1);
|
|
||||||
const newState = reducer({maxContentLines: maxLines}, setContent(_.range(maxLines+1)))
|
|
||||||
expect(newState.showFullContent).toBeFalsy()
|
|
||||||
expect(newState.content).toEqual(content)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not change the contentview mode', () => {
|
|
||||||
expect(reducer({contentView: 'foo'}, flowActions.select(1)).contentView).toEqual('foo')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should change the contentview mode to auto after editing when a new flow will be selected', () => {
|
|
||||||
expect(reducer({contentView: 'foo', modifiedFlow : 'test_flow'}, flowActions.select(1)).contentView).toEqual('Auto')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should set update and merge the modifiedflow with the update values', () => {
|
|
||||||
let modifiedFlow = {headers: []}
|
|
||||||
let updateValues = {content: 'bar'}
|
|
||||||
let result = {headers: [], content: 'bar'}
|
|
||||||
expect(reducer({modifiedFlow}, updateEdit(updateValues)).modifiedFlow).toEqual(result)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not change the state when a flow is updated which is not selected', () => {
|
|
||||||
let modifiedFlow = {id: 1}
|
|
||||||
let updatedFlow = {id: 0}
|
|
||||||
expect(reducer({modifiedFlow}, stopEdit(updatedFlow, modifiedFlow)).modifiedFlow).toEqual(modifiedFlow)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should stop editing when the selected flow is updated', () => {
|
|
||||||
let modifiedFlow = {id: 1}
|
|
||||||
let updatedFlow = {id: 1}
|
|
||||||
expect(reducer(
|
|
||||||
{ modifiedFlow },
|
|
||||||
{type: flowActions.UPDATE, data: modifiedFlow}
|
|
||||||
).modifiedFlow
|
|
||||||
).toBeFalsy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should set content view', () => {
|
|
||||||
let state = reducer(undefined, setContentView('Edit'))
|
|
||||||
expect(state.contentView).toEqual('Edit')
|
|
||||||
expect(state.showFullContent).toBeTruthy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should select different tabs', () => {
|
|
||||||
let state = reducer(undefined, selectTab('response'))
|
|
||||||
expect(state.tab).toEqual('response')
|
|
||||||
expect(state.displayLarge).toBeFalsy()
|
|
||||||
expect(state.showFullContent).toBeFalsy()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should display large', () => {
|
|
||||||
expect(reducer(undefined, displayLarge()).displayLarge).toBeTruthy()
|
|
||||||
})
|
|
||||||
})
|
|
20
web/src/js/__tests__/ducks/ui/flowSpec.tsx
Normal file
20
web/src/js/__tests__/ducks/ui/flowSpec.tsx
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import reduceFlow, * as FlowActions from '../../../ducks/ui/flow'
|
||||||
|
|
||||||
|
|
||||||
|
describe('option reducer', () => {
|
||||||
|
it('should return initial state', () => {
|
||||||
|
expect(reduceFlow(undefined, {type: "other"})).toEqual(FlowActions.defaultState)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle set tab', () => {
|
||||||
|
expect(
|
||||||
|
reduceFlow(undefined, FlowActions.selectTab("response")).tab
|
||||||
|
).toEqual("response")
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should handle set content view', () => {
|
||||||
|
expect(
|
||||||
|
reduceFlow(undefined, FlowActions.setContentViewFor("foo", "Raw")).contentViewFor["foo"]
|
||||||
|
).toEqual("Raw")
|
||||||
|
})
|
||||||
|
})
|
@ -1,33 +0,0 @@
|
|||||||
import reducer, { setActiveMenu } from '../../../ducks/ui/header'
|
|
||||||
import * as flowActions from '../../../ducks/flows'
|
|
||||||
|
|
||||||
describe('header reducer', () => {
|
|
||||||
it('should return the initial state', () => {
|
|
||||||
expect(reducer(undefined, {}).activeMenu).toEqual('Start')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should return the state for view', () => {
|
|
||||||
expect(reducer(undefined, setActiveMenu('View')).activeMenu).toEqual('View')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should change the state to Start when deselecting a flow and we a currently at the flow tab', () => {
|
|
||||||
expect(reducer(
|
|
||||||
{ activeMenu: 'Flow', isFlowSelected: true },
|
|
||||||
flowActions.select(undefined)).activeMenu
|
|
||||||
).toEqual('Start')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should change the state to Flow when we selected a flow and no flow was selected before', () => {
|
|
||||||
expect(reducer(
|
|
||||||
{ activeMenu: 'Start', isFlowSelected: false },
|
|
||||||
flowActions.select(1)).activeMenu
|
|
||||||
).toEqual('Flow')
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should not change the state to Flow when OPTIONS tab is selected and we selected a flow and a flow as selected before', () => {
|
|
||||||
expect(reducer(
|
|
||||||
{ activeMenu: 'Options', isFlowSelected: true },
|
|
||||||
flowActions.select(1)
|
|
||||||
).activeMenu).toEqual('Options')
|
|
||||||
})
|
|
||||||
})
|
|
@ -4,6 +4,5 @@ describe('reduceUI in js/ducks/ui/index.js', () => {
|
|||||||
it('should combine flow and header', () => {
|
it('should combine flow and header', () => {
|
||||||
let state = reduceUI(undefined, {})
|
let state = reduceUI(undefined, {})
|
||||||
expect(state.hasOwnProperty('flow')).toBeTruthy()
|
expect(state.hasOwnProperty('flow')).toBeTruthy()
|
||||||
expect(state.hasOwnProperty('header')).toBeTruthy()
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -82,7 +82,7 @@ describe('onKeyDown', () => {
|
|||||||
|
|
||||||
it('should handle switch to left tab', () => {
|
it('should handle switch to left tab', () => {
|
||||||
store.dispatch(createKeyEvent(Key.LEFT))
|
store.dispatch(createKeyEvent(Key.LEFT))
|
||||||
expect(store.getActions()).toEqual([{ tab: 'details', type: UIActions.SET_TAB }])
|
expect(store.getActions()).toEqual([{ tab: 'timing', type: UIActions.SET_TAB }])
|
||||||
})
|
})
|
||||||
|
|
||||||
it('should handle switch to right tab', () => {
|
it('should handle switch to right tab', () => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import reduce, * as storeActions from '../../../ducks/utils/store'
|
import {reduce} from '../../../ducks/utils/store'
|
||||||
|
import * as storeActions from '../../../ducks/utils/store'
|
||||||
|
|
||||||
describe('store reducer', () => {
|
describe('store reducer', () => {
|
||||||
it('should return initial state', () => {
|
it('should return initial state', () => {
|
||||||
|
@ -6,7 +6,9 @@ import {createAppStore} from '../ducks'
|
|||||||
import {testState} from "./ducks/tutils";
|
import {testState} from "./ducks/tutils";
|
||||||
|
|
||||||
// re-export everything
|
// re-export everything
|
||||||
export * from '@testing-library/react'
|
export {
|
||||||
|
waitFor, fireEvent, act, screen
|
||||||
|
} from '@testing-library/react'
|
||||||
|
|
||||||
export function render(
|
export function render(
|
||||||
ui,
|
ui,
|
||||||
|
@ -4,6 +4,7 @@ import { updateStoreFromUrl, updateUrlFromStore } from '../urlState'
|
|||||||
import reduceFlows from '../ducks/flows'
|
import reduceFlows from '../ducks/flows'
|
||||||
import reduceUI from '../ducks/ui/index'
|
import reduceUI from '../ducks/ui/index'
|
||||||
import reduceEventLog from '../ducks/eventLog'
|
import reduceEventLog from '../ducks/eventLog'
|
||||||
|
import reduceCommandBar from '../ducks/commandBar'
|
||||||
import * as flowsActions from '../ducks/flows'
|
import * as flowsActions from '../ducks/flows'
|
||||||
|
|
||||||
import configureStore from 'redux-mock-store'
|
import configureStore from 'redux-mock-store'
|
||||||
@ -64,7 +65,8 @@ describe('updateUrlFromStore', () => {
|
|||||||
let initialState = {
|
let initialState = {
|
||||||
flows: reduceFlows(undefined, {}),
|
flows: reduceFlows(undefined, {}),
|
||||||
ui: reduceUI(undefined, {}),
|
ui: reduceUI(undefined, {}),
|
||||||
eventLog: reduceEventLog(undefined, {})
|
eventLog: reduceEventLog(undefined, {}),
|
||||||
|
commandBar: reduceCommandBar(undefined, {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should update initial url', () => {
|
it('should update initial url', () => {
|
||||||
@ -89,7 +91,8 @@ describe('initialize', () => {
|
|||||||
let initialState = {
|
let initialState = {
|
||||||
flows: reduceFlows(undefined, {}),
|
flows: reduceFlows(undefined, {}),
|
||||||
ui: reduceUI(undefined, {}),
|
ui: reduceUI(undefined, {}),
|
||||||
eventLog: reduceEventLog(undefined, {})
|
eventLog: reduceEventLog(undefined, {}),
|
||||||
|
commandBar: reduceCommandBar(undefined, {}),
|
||||||
}
|
}
|
||||||
|
|
||||||
it('should handle initial state', () => {
|
it('should handle initial state', () => {
|
||||||
|
@ -27,7 +27,7 @@ describe('formatTimeSTamp', () => {
|
|||||||
|
|
||||||
describe('reverseString', () => {
|
describe('reverseString', () => {
|
||||||
it('should return reversed string', () => {
|
it('should return reversed string', () => {
|
||||||
let str1 = "abc", str2="xyz"
|
let str1 = "abc", str2 = "xyz"
|
||||||
expect(utils.reverseString(str1) > utils.reverseString(str2)).toBeTruthy()
|
expect(utils.reverseString(str1) > utils.reverseString(str2)).toBeTruthy()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@ -36,13 +36,13 @@ describe('fetchApi', () => {
|
|||||||
it('should handle fetch operation', () => {
|
it('should handle fetch operation', () => {
|
||||||
utils.fetchApi('http://foo/bar', {method: "POST"})
|
utils.fetchApi('http://foo/bar', {method: "POST"})
|
||||||
expect(fetch.mock.calls[0][0]).toEqual(
|
expect(fetch.mock.calls[0][0]).toEqual(
|
||||||
"http://foo/bar?_xsrf=undefined"
|
"http://foo/bar"
|
||||||
)
|
)
|
||||||
fetch.mockClear()
|
fetch.mockClear()
|
||||||
|
|
||||||
utils.fetchApi('http://foo?bar=1', {method: "POST"})
|
utils.fetchApi('http://foo?bar=1', {method: "POST"})
|
||||||
expect(fetch.mock.calls[0][0]).toEqual(
|
expect(fetch.mock.calls[0][0]).toEqual(
|
||||||
"http://foo?bar=1&_xsrf=undefined"
|
"http://foo?bar=1"
|
||||||
)
|
)
|
||||||
|
|
||||||
})
|
})
|
||||||
@ -52,11 +52,14 @@ describe('fetchApi', () => {
|
|||||||
utils.fetchApi.put("http://foo", [1, 2, 3], {})
|
utils.fetchApi.put("http://foo", [1, 2, 3], {})
|
||||||
expect(fetch.mock.calls[0]).toEqual(
|
expect(fetch.mock.calls[0]).toEqual(
|
||||||
[
|
[
|
||||||
"http://foo?_xsrf=undefined",
|
"http://foo",
|
||||||
{
|
{
|
||||||
body: "[1,2,3]",
|
body: "[1,2,3]",
|
||||||
credentials: "same-origin",
|
credentials: "same-origin",
|
||||||
headers: { "Content-Type": "application/json" },
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"X-XSRFToken": undefined,
|
||||||
|
},
|
||||||
method: "PUT"
|
method: "PUT"
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
@ -66,8 +69,8 @@ describe('fetchApi', () => {
|
|||||||
|
|
||||||
describe('getDiff', () => {
|
describe('getDiff', () => {
|
||||||
it('should return json object including only the changed keys value pairs', () => {
|
it('should return json object including only the changed keys value pairs', () => {
|
||||||
let obj1 = {a: 1, b:{ foo: 1} , c: [3]},
|
let obj1 = {a: 1, b: {foo: 1}, c: [3]},
|
||||||
obj2 = {a: 1, b:{ foo: 2} , c: [4]}
|
obj2 = {a: 1, b: {foo: 2}, c: [4]}
|
||||||
expect(utils.getDiff(obj1, obj2)).toEqual({ b: {foo: 2}, c:[4]})
|
expect(utils.getDiff(obj1, obj2)).toEqual({b: {foo: 2}, c: [4]})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -100,7 +100,7 @@ export default function CommandBar() {
|
|||||||
setAllCommands(data["commands"])
|
setAllCommands(data["commands"])
|
||||||
setCompletionCandidate(getAvailableCommands(data["commands"]))
|
setCompletionCandidate(getAvailableCommands(data["commands"]))
|
||||||
setAvailableCommands(Object.keys(data))
|
setAvailableCommands(Object.keys(data))
|
||||||
})
|
}).catch(e => console.error(e))
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const parseCommand = (originalInput: string, input: string) => {
|
const parseCommand = (originalInput: string, input: string) => {
|
||||||
|
@ -204,7 +204,7 @@ export const quickactions: FlowColumn = ({flow}) => {
|
|||||||
const ct = flow.response && ResponseUtils.getContentType(flow.response);
|
const ct = flow.response && ResponseUtils.getContentType(flow.response);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<td className={classnames("col-quickactions", {hover: open})} onClick={(e) => 0/*e.stopPropagation()*/}>
|
<td className={classnames("col-quickactions", {hover: open})} onClick={() => 0}>
|
||||||
<div>
|
<div>
|
||||||
{resume_or_replay}
|
{resume_or_replay}
|
||||||
<Dropdown text={<i className="fa fa-fw fa-ellipsis-h text-muted"/>} className="quickaction"
|
<Dropdown text={<i className="fa fa-fw fa-ellipsis-h text-muted"/>} className="quickaction"
|
||||||
@ -262,3 +262,15 @@ export const quickactions: FlowColumn = ({flow}) => {
|
|||||||
|
|
||||||
quickactions.headerName = ''
|
quickactions.headerName = ''
|
||||||
quickactions.sortKey = flow => 0;
|
quickactions.sortKey = flow => 0;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
icon,
|
||||||
|
method,
|
||||||
|
path,
|
||||||
|
quickactions,
|
||||||
|
size,
|
||||||
|
status,
|
||||||
|
time,
|
||||||
|
timestamp,
|
||||||
|
tls
|
||||||
|
};
|
||||||
|
@ -15,7 +15,7 @@ type TabProps = {
|
|||||||
flow: Flow
|
flow: Flow
|
||||||
}
|
}
|
||||||
|
|
||||||
export const allTabs: { [name: string]: FunctionComponent<TabProps> } = {
|
export const allTabs: { [name: string]: FunctionComponent<TabProps> & {displayName: string} } = {
|
||||||
request: Request,
|
request: Request,
|
||||||
response: Response,
|
response: Response,
|
||||||
error: Error,
|
error: Error,
|
||||||
@ -57,7 +57,7 @@ export default function FlowView() {
|
|||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
dispatch(selectTab(tabId))
|
dispatch(selectTab(tabId))
|
||||||
}}>
|
}}>
|
||||||
{allTabs[tabId].name}
|
{allTabs[tabId].displayName}
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -149,3 +149,4 @@ export default function Connection({flow}: { flow: Flow }) {
|
|||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Connection.displayName = "Connection"
|
||||||
|
@ -18,3 +18,4 @@ export default function Error({flow}: ErrorProps) {
|
|||||||
</section>
|
</section>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Error.displayName = "Error";
|
||||||
|
@ -139,8 +139,10 @@ export function Request() {
|
|||||||
const flow = useAppSelector(state => state.flows.byId[state.flows.selected[0]]) as HTTPFlow;
|
const flow = useAppSelector(state => state.flows.byId[state.flows.selected[0]]) as HTTPFlow;
|
||||||
return <Message flow={flow} message={flow.request}/>;
|
return <Message flow={flow} message={flow.request}/>;
|
||||||
}
|
}
|
||||||
|
Request.displayName = "Request"
|
||||||
|
|
||||||
export function Response() {
|
export function Response() {
|
||||||
const flow = useAppSelector(state => state.flows.byId[state.flows.selected[0]]) as HTTPFlow & { response: HTTPResponse }
|
const flow = useAppSelector(state => state.flows.byId[state.flows.selected[0]]) as HTTPFlow & { response: HTTPResponse }
|
||||||
return <Message flow={flow} message={flow.response}/>;
|
return <Message flow={flow} message={flow.response}/>;
|
||||||
}
|
}
|
||||||
|
Response.displayName = "Response"
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user