diff --git a/web/src/js/__tests__/components/EventLog/EventListSpec.js b/web/src/js/__tests__/components/EventLog/EventListSpec.js new file mode 100644 index 000000000..4f14dfba7 --- /dev/null +++ b/web/src/js/__tests__/components/EventLog/EventListSpec.js @@ -0,0 +1,22 @@ +import React from 'react' +import EventLogList from '../../../components/EventLog/EventList' +import TestUtils from 'react-dom/test-utils' + +describe('EventList Component', () => { + let mockEventList = [ + { id: 1, level: 'info', message: 'foo' }, + { id: 2, level: 'error', message: 'bar' } + ], + eventLogList = TestUtils.renderIntoDocument() + + it('should render correctly', () => { + expect(eventLogList.state).toMatchSnapshot() + expect(eventLogList.props).toMatchSnapshot() + }) + + it('should handle componentWillUnmount', () => { + window.removeEventListener = jest.fn() + eventLogList.componentWillUnmount() + expect(window.removeEventListener).toBeCalledWith('resize', eventLogList.onViewportUpdate) + }) +}) diff --git a/web/src/js/__tests__/components/EventLog/__snapshots__/EventListSpec.js.snap b/web/src/js/__tests__/components/EventLog/__snapshots__/EventListSpec.js.snap new file mode 100644 index 000000000..10bcb5983 --- /dev/null +++ b/web/src/js/__tests__/components/EventLog/__snapshots__/EventListSpec.js.snap @@ -0,0 +1,30 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`EventList Component should render correctly 1`] = ` +Object { + "vScroll": Object { + "end": 1, + "paddingBottom": 18, + "paddingTop": 0, + "start": 0, + }, +} +`; + +exports[`EventList Component should render correctly 2`] = ` +Object { + "events": Array [ + Object { + "id": 1, + "level": "info", + "message": "foo", + }, + Object { + "id": 2, + "level": "error", + "message": "bar", + }, + ], + "rowHeight": 18, +} +`; diff --git a/web/src/js/__tests__/components/FlowView/DetailsSpec.js b/web/src/js/__tests__/components/FlowView/DetailsSpec.js new file mode 100644 index 000000000..1b0192cff --- /dev/null +++ b/web/src/js/__tests__/components/FlowView/DetailsSpec.js @@ -0,0 +1,50 @@ +import React from 'react' +import renderer from 'react-test-renderer' +import Details, { TimeStamp, ConnectionInfo, CertificateInfo, Timing } from '../../../components/FlowView/Details' +import { TFlow } from '../../ducks/tutils' + +let tflow = TFlow() + +describe('TimeStamp Component', () => { + it('should render correctly', () => { + let timestamp = renderer.create(), + tree = timestamp.toJSON() + expect(tree).toMatchSnapshot() + // without timestamp + timestamp = renderer.create() + tree = timestamp.toJSON() + expect(tree).toMatchSnapshot() + }) +}) + +describe('ConnectionInfo Component', () => { + it('should render correctly', () => { + let connectionInfo = renderer.create(), + tree = connectionInfo.toJSON() + expect(tree).toMatchSnapshot() + }) +}) + +describe('CertificateInfo Component', () => { + it('should render correctly', () => { + let certificateInfo = renderer.create(), + tree = certificateInfo.toJSON() + expect(tree).toMatchSnapshot() + }) +}) + +describe('Timing Component', () => { + it('should render correctly', () => { + let timing = renderer.create(), + tree = timing.toJSON() + expect(tree).toMatchSnapshot() + }) +}) + +describe('Details Component', () => { + it('should render correctly', () => { + let details = renderer.create(
), + tree = details.toJSON() + expect(tree).toMatchSnapshot() + }) +}) diff --git a/web/src/js/__tests__/components/FlowView/HeadersSpec.js b/web/src/js/__tests__/components/FlowView/HeadersSpec.js new file mode 100644 index 000000000..4ed930820 --- /dev/null +++ b/web/src/js/__tests__/components/FlowView/HeadersSpec.js @@ -0,0 +1,132 @@ +import React from 'react' +import ReactDOM from 'react-dom' +import renderer from 'react-test-renderer' +import TestUtils from 'react-dom/test-utils' +import Headers, { HeaderEditor } from '../../../components/FlowView/Headers' +import { Key } from '../../../utils' + +describe('HeaderEditor Component', () => { + + it('should render correctly', () => { + let headerEditor = renderer.create( + ), + tree = headerEditor.toJSON() + expect(tree).toMatchSnapshot() + }) + + let doneFn = jest.fn(), + removeFn = jest.fn(), + tabFn = jest.fn(), + headerEditor = TestUtils.renderIntoDocument( + ) + + 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(), + tree = headers.toJSON() + expect(tree).toMatchSnapshot() + }) + + let headers = TestUtils.renderIntoDocument(), + 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() + headers.onChange(0, 0, '') + expect(changeFn).toBeCalledWith([['Name', 'Value']]) + + }) + +}) diff --git a/web/src/js/__tests__/components/FlowView/MessagesSpec.js b/web/src/js/__tests__/components/FlowView/MessagesSpec.js new file mode 100644 index 000000000..02db77e8f --- /dev/null +++ b/web/src/js/__tests__/components/FlowView/MessagesSpec.js @@ -0,0 +1,143 @@ +jest.mock('../../../components/ContentView') +import React from 'react' +import renderer from 'react-test-renderer' +import TestUtils from 'react-dom/test-utils' +import { Request, Response, ErrorView } from '../../../components/FlowView/Messages' +import { Provider } from 'react-redux' +import { TFlow, TStore } from '../../ducks/tutils' +import { updateEdit } from '../../../ducks/ui/flow' +import { parseUrl } from '../../../flow/utils' +import ContentView from '../../../components/ContentView' +import ContentViewOptions from '../../../components/ContentView/ContentViewOptions' +import Headers from '../../../components/FlowView/Headers' +import ValueEditor from '../../../components/ValueEditor/ValueEditor' + +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( + + + + ), + tree = provider.toJSON() + expect(tree).toMatchSnapshot() + }) + + let provider = TestUtils.renderIntoDocument( + + + ), + valueEditors = TestUtils.scryRenderedComponentsWithType(provider, ValueEditor) + + it('should handle done on flow request method', () => { + let valueEditor = valueEditors[0] + valueEditor.props.onDone('foo') + expect(store.getActions()).toEqual([updateEdit({ request: { method: 'foo' }})]) + }) + + it('should handle done on flow request url', () => { + let valueEditor = valueEditors[1], + url = 'http://foo/bar' + valueEditor.props.onDone(url) + expect(store.getActions()).toEqual([updateEdit({ request: { path: '', ...parseUrl(url)}})]) + }) + + it('should handle done on flow request http version', () => { + let valueEditor = valueEditors[2] + valueEditor.props.onDone('HTTP/9.9') + expect(store.getActions()).toEqual([updateEdit({ request: { http_version: 'HTTP/9.9' }})]) + }) + + it('should handle change on flow request header', () => { + let headers = TestUtils.findRenderedComponentWithType(provider, Headers) + headers.props.onChange('foo') + expect(store.getActions()).toEqual([updateEdit({ request: { headers: 'foo' }})]) + }) + + it('should handle change on flow request contentView', () => { + let contentView = TestUtils.findRenderedComponentWithType(provider, ContentView) + contentView.props.onContentChange('foo') + expect(store.getActions()).toEqual([updateEdit({ request: { content: 'foo' }})]) + }) + + it('should handle uploadContent on flow request ContentViewOptions', () => { + let contentViewOptions = TestUtils.findRenderedComponentWithType(provider, ContentViewOptions) + contentViewOptions.props.uploadContent('foo') + expect(fetch).toBeCalled() + fetch.mockClear() + }) +}) + +describe('Response Component', () => { + afterEach(() => {store.clearActions()}) + + it('should render correctly', () => { + let provider = renderer.create( + + + + ), + tree = provider.toJSON() + expect(tree).toMatchSnapshot() + }) + + let provider = TestUtils.renderIntoDocument( + + + ), + valueEditors = TestUtils.scryRenderedComponentsWithType(provider, ValueEditor) + + it('should handle done on flow response http version', () => { + let valueEditor = valueEditors[0] + valueEditor.props.onDone('HTTP/9.9') + expect(store.getActions()).toEqual([updateEdit({ response: { http_version: 'HTTP/9.9' }})]) + }) + + it('should handle done on flow response status code', () => { + let valueEditor = valueEditors[1] + valueEditor.props.onDone('404') + expect(store.getActions()).toEqual([updateEdit({ response: { code: parseInt('404') }})]) + }) + + it('should handle done on flow response reason', () => { + let valueEdiotr = valueEditors[2] + valueEdiotr.props.onDone('foo') + expect(store.getActions()).toEqual([updateEdit( { response: { msg: 'foo' }})]) + }) + + it('should handle change on flow response headers', () => { + let headers = TestUtils.findRenderedComponentWithType(provider, Headers) + headers.props.onChange('foo') + expect(store.getActions()).toEqual([updateEdit( { response: { headers: 'foo' }})]) + }) + + it('should handle change on flow response ContentView', () => { + let contentView = TestUtils.findRenderedComponentWithType(provider, ContentView) + contentView.props.onContentChange('foo') + expect(store.getActions()).toEqual([updateEdit( { response: { content: 'foo' }})]) + }) + + it('should handle updateContent on flow response ContentViewOptions', () => { + let contentViewOptions = TestUtils.findRenderedComponentWithType(provider, ContentViewOptions) + contentViewOptions.props.uploadContent('foo') + expect(fetch).toBeCalled() + fetch.mockClear() + }) +}) + +describe('Error Component', () => { + it('should render correctly', () => { + let errorView = renderer.create(), + tree = errorView.toJSON() + expect(tree).toMatchSnapshot() + }) +}) diff --git a/web/src/js/__tests__/components/FlowView/NavSpec.js b/web/src/js/__tests__/components/FlowView/NavSpec.js new file mode 100644 index 000000000..867e6f2c4 --- /dev/null +++ b/web/src/js/__tests__/components/FlowView/NavSpec.js @@ -0,0 +1,38 @@ +import 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(