!1 Merge back to master

Merge pull request !1 from dev branch
This commit is contained in:
hekk 2018-05-27 21:32:55 +08:00
parent 30c963a5f0
commit 61a1c93f0f
89 changed files with 15859 additions and 2 deletions

View file

@ -0,0 +1,32 @@
import React from "react";
import { AuthPane, classLogin, classLogout } from "../auth_pane";
describe("AuthPane", () => {
test("AuthPane should show login pane if isLogin === true, or show logout pane", () => {
const tests = [
{
input: {
onLogin: jest.fn,
onLogout: jest.fn,
isLogin: false,
serverAddr: ""
},
output: classLogin
},
{
input: {
onLogin: jest.fn,
onLogout: jest.fn,
isLogin: true,
serverAddr: ""
},
output: classLogout
}
];
tests.forEach(testCase => {
const pane = new AuthPane(testCase.input);
expect(pane.render().props.className).toBe(testCase.output);
});
});
});

View file

@ -0,0 +1,297 @@
jest.mock("../../../libs/api_share");
import React from "react";
import { mount } from "enzyme";
import { FileBoxDetail, classDelYes, classDelNo } from "../file_box_detail";
import { execFuncs, getDesc, verifyCalls } from "../../../tests/test_helper";
import valueEqual from "value-equal";
import {
del,
publishId,
shadowId,
setDownLimit
} from "../../../libs/api_share";
describe("FileBoxDetail", () => {
test("FileBoxDetail should show delete button by default, toggle using onComfirmDel and onCancelDel", () => {
const box = mount(<FileBoxDetail />);
expect(box.instance().state.showDelComfirm).toBe(false);
box.instance().onComfirmDel();
expect(box.instance().state.showDelComfirm).toBe(true);
box.instance().onCancelDel();
expect(box.instance().state.showDelComfirm).toBe(false);
});
});
describe("FileBoxDetail", () => {
const tests = [
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onSetDownLimit",
args: [3]
}
],
state: {
downLimit: 3,
showDelComfirm: false
}
},
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onComfirmDel",
args: []
}
],
state: {
downLimit: -1,
showDelComfirm: true
}
},
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onComfirmDel",
args: []
},
{
func: "onCancelDel",
args: []
}
],
state: {
downLimit: -1,
showDelComfirm: false
}
},
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onResetLink",
args: []
}
],
state: {
downLimit: -1,
showDelComfirm: false
},
calls: [
{
func: "onPublishId",
count: 1
},
{
func: "onOk",
count: 1
},
{
func: "onRefresh",
count: 1
}
]
},
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onShadowLink",
args: []
}
],
state: {
downLimit: -1,
showDelComfirm: false
},
calls: [
{
func: "onShadowId",
count: 1
},
{
func: "onOk",
count: 1
},
{
func: "onRefresh",
count: 1
}
]
},
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onUpdateDownLimit",
args: []
}
],
state: {
downLimit: -1,
showDelComfirm: false
},
calls: [
{
func: "onSetDownLimit",
count: 1
},
{
func: "onOk",
count: 1
},
{
func: "onRefresh",
count: 1
}
]
},
{
init: {
id: "0",
name: "filename",
size: "1B",
modTime: 0,
href: "href",
downLimit: -1
},
execs: [
{
func: "onDelete",
args: []
}
],
state: {
downLimit: -1,
showDelComfirm: false
},
calls: [
{
func: "onDel",
count: 1
},
{
func: "onOk",
count: 1
},
{
func: "onRefresh",
count: 1
}
]
}
];
tests.forEach(testCase => {
test(getDesc("FileBoxDetail", testCase), () => {
const stubs = {
onOk: jest.fn(),
onError: jest.fn(),
onRefresh: jest.fn(),
onDel: jest.fn(),
onPublishId: jest.fn(),
onShadowId: jest.fn(),
onSetDownLimit: jest.fn()
};
const stubWraps = {
onDel: () => {
stubs.onDel();
return del();
},
onPublishId: () => {
stubs.onPublishId();
return publishId();
},
onShadowId: () => {
stubs.onShadowId();
return shadowId();
},
onSetDownLimit: () => {
stubs.onSetDownLimit();
return setDownLimit();
}
};
return new Promise((resolve, reject) => {
const pane = mount(
<FileBoxDetail
id={testCase.init.id}
name={testCase.init.name}
size={testCase.init.size}
modTime={testCase.init.modTime}
href={testCase.init.href}
downLimit={testCase.init.downLimit}
onRefresh={stubs.onRefresh}
onOk={stubs.onOk}
onError={stubs.onError}
onDel={stubWraps.onDel}
onPublishId={stubWraps.onPublishId}
onShadowId={stubWraps.onShadowId}
onSetDownLimit={stubWraps.onSetDownLimit}
/>
);
execFuncs(pane.instance(), testCase.execs).then(() => {
pane.update();
if (!valueEqual(pane.instance().state, testCase.state)) {
return reject("FileBoxDetail: state not identical");
}
if (testCase.calls != null) {
const err = verifyCalls(testCase.calls, stubs);
if (err != null) {
return reject("FileBoxDetail: state not identical");
}
}
resolve();
});
});
});
});
});

View file

@ -0,0 +1,144 @@
jest.mock("../../../libs/api_share");
import React from "react";
import { FilePane } from "../file_pane";
import { mount } from "enzyme";
import * as mockApiShare from "../../../libs/api_share";
import { execFuncs, getDesc, verifyCalls } from "../../../tests/test_helper";
import valueEqual from "value-equal";
describe("FilePane", () => {
const tests = [
{
init: {
list: [{ Id: 0, PathLocal: "" }]
},
execs: [
{
func: "componentWillMount",
args: []
}
],
state: {
infos: [{ Id: 0, PathLocal: "" }],
showDetailId: -1
},
calls: [
{
func: "onList",
count: 2 // because componentWillMount will be callled twice
},
{
func: "onOk",
count: 2 // because componentWillMount will be callled twice
}
]
},
{
init: {
list: [{ Id: 0, PathLocal: "" }, { Id: 1, PathLocal: "" }]
},
execs: [
{
func: "componentWillMount",
args: []
},
{
func: "onUpdateProgressImp",
args: [0, "100%"]
}
],
state: {
infos: [
{ Id: 0, PathLocal: "", progress: "100%" },
{ Id: 1, PathLocal: "" }
],
showDetailId: -1
}
},
{
init: {
list: []
},
execs: [
{
func: "componentWillMount",
args: []
},
{
func: "onToggleDetail",
args: [0]
}
],
state: {
infos: [],
showDetailId: 0
}
},
{
init: {
list: []
},
execs: [
{
func: "onToggleDetail",
args: [0]
},
{
func: "onToggleDetail",
args: [0]
}
],
state: {
infos: [],
showDetailId: -1
}
}
];
tests.forEach(testCase => {
test(getDesc("FilePane", testCase), () => {
// mock list()
mockApiShare.__truncInfos();
mockApiShare.__addInfos(testCase.init.list);
const stubs = {
onList: jest.fn(),
onOk: jest.fn(),
onError: jest.fn()
};
const stubWraps = {
onListWrap: () => {
stubs.onList();
return mockApiShare.list();
}
};
return new Promise((resolve, reject) => {
const pane = mount(
<FilePane
onList={stubWraps.onListWrap}
onOk={stubs.onOk}
onError={stubs.onError}
/>
);
execFuncs(pane.instance(), testCase.execs).then(() => {
pane.update();
if (!valueEqual(pane.instance().state, testCase.state)) {
return reject("FilePane: state not identical");
}
if (testCase.calls != null) {
const err = verifyCalls(testCase.calls, stubs);
if (err != null) {
return reject(err);
}
}
resolve();
});
});
});
});
});

View file

@ -0,0 +1,136 @@
jest.mock("../../../libs/api_share");
jest.mock("../../../libs/api_auth");
import React from "react";
import { InfoBar } from "../info_bar";
import { mount } from "enzyme";
import * as mockApiShare from "../../../libs/api_share";
import { execFuncs, getDesc, verifyCalls } from "../../../tests/test_helper";
import valueEqual from "value-equal";
describe("InfoBar", () => {
const tests = [
{
execs: [
{
func: "onSearch",
args: ["searchFileName"]
}
],
state: {
filterFileName: "searchFileName",
fold: false
},
calls: [
{
func: "onSearch",
count: 1
}
]
},
{
execs: [
{
func: "onLogin",
args: ["serverAddr", "adminId", "adminPwd"]
}
],
state: {
filterFileName: "",
fold: false
},
calls: [
{
func: "onLogin",
count: 1
}
]
},
{
execs: [
{
func: "onLogout",
args: ["serverAddr"]
}
],
state: {
filterFileName: "",
fold: false
},
calls: [
{
func: "onLogout",
count: 1
}
]
},
{
execs: [
{
func: "onAddLocalFiles",
args: []
}
],
state: {
filterFileName: "",
fold: false
},
calls: [
{
func: "onAddLocalFiles",
count: 1
}
]
}
];
tests.forEach(testCase => {
test(getDesc("InfoBar", testCase), () => {
const stubs = {
onLogin: jest.fn(),
onLogout: jest.fn(),
onAddLocalFiles: jest.fn(),
onSearch: jest.fn(),
onOk: jest.fn(),
onError: jest.fn()
};
const onAddLocalFilesWrap = () => {
stubs.onAddLocalFiles();
return Promise.resolve(true);
};
return new Promise((resolve, reject) => {
const infoBar = mount(
<InfoBar
width="100%"
isLogin={false}
serverAddr=""
onLogin={stubs.onLogin}
onLogout={stubs.onLogout}
onAddLocalFiles={onAddLocalFilesWrap}
onSearch={stubs.onSearch}
onOk={stubs.onOk}
onError={stubs.onError}
/>
);
execFuncs(infoBar.instance(), testCase.execs)
.then(() => {
infoBar.update();
if (!valueEqual(infoBar.instance().state, testCase.state)) {
return reject("state not identical");
}
if (testCase.calls != null) {
const err = verifyCalls(testCase.calls, stubs);
if (err !== null) {
return reject(err);
}
}
resolve();
})
.catch(err => console.error(err));
});
});
});
});

View file

@ -0,0 +1,51 @@
import React from "react";
import { mount } from "enzyme";
import { checkQueueCycle, Uploader } from "../uploader";
const testTimeout = 4000;
describe("Uploader", () => {
test(
"Uploader will upload files in uploadQueue by interval",
() => {
// TODO: could be refactored using timer mocks
// https://facebook.github.io/jest/docs/en/timer-mocks.html
const tests = [
{
input: { target: { files: ["task1", "task2", "task3"] } },
uploadCalled: 3
}
];
let promises = [];
const uploader = mount(<Uploader />);
tests.forEach(testCase => {
// mock
const uploadSpy = jest.fn();
const uploadStub = () => {
uploadSpy();
return Promise.resolve();
};
uploader.instance().upload = uploadStub;
uploader.update();
// upload and verify
uploader.instance().onUpload(testCase.input);
const wait = testCase.input.target.files.length * 1000 + 100;
const promise = new Promise(resolve => {
setTimeout(() => {
expect(uploader.instance().state.uploadQueue.length).toBe(0);
expect(uploadSpy.mock.calls.length).toBe(testCase.uploadCalled);
resolve();
}, wait);
});
promises = [...promises, promise];
});
return Promise.all(promises);
},
testTimeout
);
});