aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthew Shao <me@matshao.com>2017-05-10 03:11:27 -0500
committerGitHub <noreply@github.com>2017-05-10 03:11:27 -0500
commitcafa094f75732bd803972aecb71e2d1032ee2390 (patch)
treec4d56a69bea9daecab4a6d6dcf64ea40d22eb48e
parent3e85dfd24227b65762a7f7ca4758dc72ed7e3d91 (diff)
parent537d5fa229966a215e0bf6824f49dffde179c103 (diff)
downloadmitmproxy-cafa094f75732bd803972aecb71e2d1032ee2390.tar.gz
mitmproxy-cafa094f75732bd803972aecb71e2d1032ee2390.tar.bz2
mitmproxy-cafa094f75732bd803972aecb71e2d1032ee2390.zip
Merge pull request #2322 from MatthewShao/jest-dev
[web] Coverage improve
-rw-r--r--web/package.json3
-rw-r--r--web/src/js/__tests__/ducks/eventLogSpec.js2
-rw-r--r--web/src/js/__tests__/ducks/flowsSpec.js7
-rw-r--r--web/src/js/__tests__/ducks/indexSpec.js12
-rw-r--r--web/src/js/__tests__/ducks/settingsSpec.js1
-rw-r--r--web/src/js/__tests__/ducks/tutils.js3
-rw-r--r--web/src/js/__tests__/ducks/ui/flowSpec.js4
-rw-r--r--web/src/js/__tests__/ducks/ui/headerSpec.js3
-rw-r--r--web/src/js/__tests__/ducks/ui/indexSpec.js9
-rw-r--r--web/src/js/__tests__/ducks/ui/keyboardSpec.js157
-rw-r--r--web/src/js/__tests__/ducks/utils/storeSpec.js2
11 files changed, 182 insertions, 21 deletions
diff --git a/web/package.json b/web/package.json
index c9f1ae40..ca170a54 100644
--- a/web/package.json
+++ b/web/package.json
@@ -2,7 +2,7 @@
"name": "mitmproxy",
"private": true,
"scripts": {
- "test": "jest",
+ "test": "jest --coverage",
"build": "gulp prod",
"start": "gulp"
},
@@ -15,7 +15,6 @@
"react"
],
"coverageDirectory": "./coverage",
- "collectCoverage": true,
"coveragePathIgnorePatterns": [
"<rootDir>/src/js/filt/filt.js"
],
diff --git a/web/src/js/__tests__/ducks/eventLogSpec.js b/web/src/js/__tests__/ducks/eventLogSpec.js
index d4d4f37a..1c993734 100644
--- a/web/src/js/__tests__/ducks/eventLogSpec.js
+++ b/web/src/js/__tests__/ducks/eventLogSpec.js
@@ -1,5 +1,3 @@
-jest.unmock('../../ducks/eventLog')
-
import reduceEventLog, * as eventLogActions from '../../ducks/eventLog'
import reduceStore from '../../ducks/utils/store'
diff --git a/web/src/js/__tests__/ducks/flowsSpec.js b/web/src/js/__tests__/ducks/flowsSpec.js
index 2dfe046f..5bd866f2 100644
--- a/web/src/js/__tests__/ducks/flowsSpec.js
+++ b/web/src/js/__tests__/ducks/flowsSpec.js
@@ -1,11 +1,10 @@
-jest.unmock('../../ducks/flows');
jest.mock('../../utils')
import reduceFlows from "../../ducks/flows"
import * as flowActions from "../../ducks/flows"
import reduceStore from "../../ducks/utils/store"
-import {fetchApi} from "../../utils"
-import {createStore} from "./tutils"
+import { fetchApi } from "../../utils"
+import { createStore } from "./tutils"
describe('flow reducer', () => {
let state = undefined
@@ -104,7 +103,7 @@ describe('flow reducer', () => {
describe('flows actions', () => {
- let store = createStore({reduceFlows})
+ let store = createStore({ reduceFlows })
let tflow = { id: 1 }
it('should handle resume action', () => {
diff --git a/web/src/js/__tests__/ducks/indexSpec.js b/web/src/js/__tests__/ducks/indexSpec.js
new file mode 100644
index 00000000..c5c4d525
--- /dev/null
+++ b/web/src/js/__tests__/ducks/indexSpec.js
@@ -0,0 +1,12 @@
+import reduceState from '../../ducks/index'
+
+describe('reduceState in js/ducks/index.js', () => {
+ it('should combine flow and header', () => {
+ let state = reduceState(undefined, {})
+ expect(state.hasOwnProperty('eventLog')).toBeTruthy()
+ expect(state.hasOwnProperty('flows')).toBeTruthy()
+ expect(state.hasOwnProperty('settings')).toBeTruthy()
+ expect(state.hasOwnProperty('connection')).toBeTruthy()
+ expect(state.hasOwnProperty('ui')).toBeTruthy()
+ })
+})
diff --git a/web/src/js/__tests__/ducks/settingsSpec.js b/web/src/js/__tests__/ducks/settingsSpec.js
index cb9df918..46d56ec7 100644
--- a/web/src/js/__tests__/ducks/settingsSpec.js
+++ b/web/src/js/__tests__/ducks/settingsSpec.js
@@ -1,4 +1,3 @@
-jest.unmock('../../ducks/settings')
jest.mock('../../utils')
import reduceSettings, * as SettingsActions from '../../ducks/settings'
diff --git a/web/src/js/__tests__/ducks/tutils.js b/web/src/js/__tests__/ducks/tutils.js
index 90a21b78..6ae7f080 100644
--- a/web/src/js/__tests__/ducks/tutils.js
+++ b/web/src/js/__tests__/ducks/tutils.js
@@ -1,6 +1,3 @@
-jest.unmock('redux')
-jest.unmock('redux-thunk')
-
import { combineReducers, applyMiddleware, createStore as createReduxStore } from 'redux'
import thunk from 'redux-thunk'
diff --git a/web/src/js/__tests__/ducks/ui/flowSpec.js b/web/src/js/__tests__/ducks/ui/flowSpec.js
index e994624d..cd6ffa2f 100644
--- a/web/src/js/__tests__/ducks/ui/flowSpec.js
+++ b/web/src/js/__tests__/ducks/ui/flowSpec.js
@@ -1,7 +1,3 @@
-jest.unmock('../../../ducks/ui/flow')
-jest.unmock('../../../ducks/flows')
-jest.unmock('lodash')
-
import _ from 'lodash'
import reducer, {
startEdit,
diff --git a/web/src/js/__tests__/ducks/ui/headerSpec.js b/web/src/js/__tests__/ducks/ui/headerSpec.js
index 8968e636..98822fd8 100644
--- a/web/src/js/__tests__/ducks/ui/headerSpec.js
+++ b/web/src/js/__tests__/ducks/ui/headerSpec.js
@@ -1,6 +1,3 @@
-jest.unmock('../../../ducks/ui/header')
-jest.unmock('../../../ducks/flows')
-
import reducer, { setActiveMenu } from '../../../ducks/ui/header'
import * as flowActions from '../../../ducks/flows'
diff --git a/web/src/js/__tests__/ducks/ui/indexSpec.js b/web/src/js/__tests__/ducks/ui/indexSpec.js
new file mode 100644
index 00000000..3c136bff
--- /dev/null
+++ b/web/src/js/__tests__/ducks/ui/indexSpec.js
@@ -0,0 +1,9 @@
+import reduceUI from '../../../ducks/ui/index'
+
+describe('reduceUI in js/ducks/ui/index.js', () => {
+ it('should combine flow and header', () => {
+ let state = reduceUI(undefined, {})
+ expect(state.hasOwnProperty('flow')).toBeTruthy()
+ expect(state.hasOwnProperty('header')).toBeTruthy()
+ })
+})
diff --git a/web/src/js/__tests__/ducks/ui/keyboardSpec.js b/web/src/js/__tests__/ducks/ui/keyboardSpec.js
new file mode 100644
index 00000000..500733cb
--- /dev/null
+++ b/web/src/js/__tests__/ducks/ui/keyboardSpec.js
@@ -0,0 +1,157 @@
+jest.mock('../../../utils')
+
+import { Key } from '../../../utils'
+import { onKeyDown } from '../../../ducks/ui/keyboard'
+import reduceFlows from '../../../ducks/flows'
+import reduceUI from '../../../ducks/ui/index'
+import * as flowsActions from '../../../ducks/flows'
+import * as UIActions from '../../../ducks/ui/flow'
+import configureStore from 'redux-mock-store'
+import thunk from 'redux-thunk'
+import { fetchApi } from '../../../utils'
+
+const mockStore = configureStore([ thunk ])
+console.debug = jest.fn()
+
+describe('onKeyDown', () => {
+ let flows = undefined
+ for( let i=1; i <= 12; i++ ) {
+ flows = reduceFlows(flows, {type: flowsActions.ADD, data: {id: i, request: true, response: true}, cmd: 'add'})
+ }
+ let store = mockStore({ flows, ui: reduceUI(undefined, {}) })
+ let createKeyEvent = (keyCode, shiftKey = undefined, ctrlKey = undefined) => {
+ return onKeyDown({ keyCode, shiftKey, ctrlKey, preventDefault: jest.fn() })
+ }
+
+ afterEach(() => {
+ store.clearActions()
+ fetchApi.mockClear()
+ });
+
+ it('should handle cursor up', () => {
+ store.getState().flows = reduceFlows(flows, flowsActions.select(2))
+ store.dispatch(createKeyEvent(Key.K))
+ expect(store.getActions()).toEqual([{ flowIds: [1], type: flowsActions.SELECT }])
+
+ store.clearActions()
+ store.dispatch(createKeyEvent(Key.UP))
+ expect(store.getActions()).toEqual([{ flowIds: [1], type: flowsActions.SELECT }])
+ })
+
+ it('should handle cursor down', () => {
+ store.dispatch(createKeyEvent(Key.J))
+ expect(store.getActions()).toEqual([{ flowIds: [3], type: flowsActions.SELECT }])
+
+ store.clearActions()
+ store.dispatch(createKeyEvent(Key.DOWN))
+ expect(store.getActions()).toEqual([{ flowIds: [3], type: flowsActions.SELECT }])
+ })
+
+ it('should handle page down', () => {
+ store.dispatch(createKeyEvent(Key.SPACE))
+ expect(store.getActions()).toEqual([{ flowIds: [12], type: flowsActions.SELECT }])
+
+ store.getState().flows = reduceFlows(flows, flowsActions.select(1))
+ store.clearActions()
+ store.dispatch(createKeyEvent(Key.PAGE_DOWN))
+ expect(store.getActions()).toEqual([{ flowIds: [11], type: flowsActions.SELECT }])
+ })
+
+ it('should handle page up', () => {
+ store.getState().flows = reduceFlows(flows, flowsActions.select(11))
+ store.dispatch(createKeyEvent(Key.PAGE_UP))
+ expect(store.getActions()).toEqual([{ flowIds: [1], type: flowsActions.SELECT }])
+ })
+
+ it('should handle select first', () => {
+ store.dispatch(createKeyEvent(Key.HOME))
+ expect(store.getActions()).toEqual([{ flowIds: [1], type: flowsActions.SELECT }])
+ })
+
+ it('should handle select last', () => {
+ store.getState().flows = reduceFlows(flows, flowsActions.select(1))
+ store.dispatch(createKeyEvent(Key.END))
+ expect(store.getActions()).toEqual([{ flowIds: [12], type: flowsActions.SELECT }])
+ })
+
+ it('should handle deselect', () => {
+ store.dispatch(createKeyEvent(Key.ESC))
+ expect(store.getActions()).toEqual([{ flowIds: [], type: flowsActions.SELECT }])
+ })
+
+ it('should handle switch to left tab', () => {
+ store.dispatch(createKeyEvent(Key.LEFT))
+ expect(store.getActions()).toEqual([{ tab: 'details', type: UIActions.SET_TAB }])
+ })
+
+ it('should handle switch to right tab', () => {
+ store.dispatch(createKeyEvent(Key.TAB))
+ expect(store.getActions()).toEqual([{ tab: 'response', type: UIActions.SET_TAB }])
+
+ store.clearActions()
+ store.dispatch(createKeyEvent(Key.RIGHT))
+ expect(store.getActions()).toEqual([{ tab: 'response', type: UIActions.SET_TAB }])
+ })
+
+ it('should handle delete action', () => {
+ store.dispatch(createKeyEvent(Key.D))
+ expect(fetchApi).toBeCalledWith('/flows/1', { method: 'DELETE' })
+
+ })
+
+ it('should handle duplicate action', () => {
+ store.dispatch(createKeyEvent(Key.D, true))
+ expect(fetchApi).toBeCalledWith('/flows/1/duplicate', { method: 'POST' })
+ })
+
+ it('should handle resume action', () => {
+ // resume all
+ store.dispatch(createKeyEvent(Key.A, true))
+ expect(fetchApi).toBeCalledWith('/flows/resume', { method: 'POST' })
+ // resume
+ store.getState().flows.byId[store.getState().flows.selected[0]].intercepted = true
+ store.dispatch(createKeyEvent(Key.A))
+ expect(fetchApi).toBeCalledWith('/flows/1/resume', { method: 'POST' })
+ })
+
+ it('should handle replay action', () => {
+ store.dispatch(createKeyEvent(Key.R))
+ expect(fetchApi).toBeCalledWith('/flows/1/replay', { method: 'POST' })
+ })
+
+ it('should handle revert action', () => {
+ store.getState().flows.byId[store.getState().flows.selected[0]].modified = true
+ store.dispatch(createKeyEvent(Key.V))
+ expect(fetchApi).toBeCalledWith('/flows/1/revert', { method: 'POST' })
+ })
+
+ it('should handle kill action', () => {
+ // kill all
+ store.dispatch(createKeyEvent(Key.X, true))
+ expect(fetchApi).toBeCalledWith('/flows/kill', { method: 'POST' })
+ // kill
+ store.dispatch(createKeyEvent(Key.X))
+ expect(fetchApi).toBeCalledWith('/flows/1/kill', { method: 'POST' })
+ })
+
+ it('should handle clear action', () => {
+ store.dispatch(createKeyEvent(Key.Z))
+ expect(fetchApi).toBeCalledWith('/clear', { method: 'POST' })
+ })
+
+ it('should stop on some action with no flow is selected', () => {
+ store.getState().flows = reduceFlows(undefined, {})
+ store.dispatch(createKeyEvent(Key.LEFT))
+ store.dispatch(createKeyEvent(Key.TAB))
+ store.dispatch(createKeyEvent(Key.RIGHT))
+ store.dispatch(createKeyEvent(Key.D))
+ expect(fetchApi).not.toBeCalled()
+ })
+
+ it('should do nothing when Ctrl and undefined key is pressed ', () => {
+ store.dispatch(createKeyEvent(Key.BACKSPACE, false, true))
+ store.dispatch(createKeyEvent(0))
+ expect(fetchApi).not.toBeCalled()
+ })
+
+})
diff --git a/web/src/js/__tests__/ducks/utils/storeSpec.js b/web/src/js/__tests__/ducks/utils/storeSpec.js
index e4742490..11a8fe23 100644
--- a/web/src/js/__tests__/ducks/utils/storeSpec.js
+++ b/web/src/js/__tests__/ducks/utils/storeSpec.js
@@ -1,5 +1,3 @@
-jest.unmock('../../../ducks/utils/store')
-
import reduceStore, * as storeActions from '../../../ducks/utils/store'
describe('store reducer', () => {