diff --git a/browser/app/js/actions/__tests__/alert.test.js b/browser/app/js/actions/__tests__/alert.test.js
index ca5b3e240..2602930cf 100644
--- a/browser/app/js/actions/__tests__/alert.test.js
+++ b/browser/app/js/actions/__tests__/alert.test.js
@@ -54,4 +54,16 @@ describe("Alert actions", () => {
const actions = store.getActions()
expect(actions).toEqual(expectedActions)
})
+
+ it("creates alert/CLEAR action directly", () => {
+ const store = mockStore()
+ const expectedActions = [
+ {
+ type: "alert/CLEAR"
+ }
+ ]
+ store.dispatch(actionsAlert.clear())
+ const actions = store.getActions()
+ expect(actions).toEqual(expectedActions)
+ })
})
diff --git a/browser/app/js/actions/__tests__/buckets.test.js b/browser/app/js/actions/__tests__/buckets.test.js
index 36bb6ba9f..ac7fee43f 100644
--- a/browser/app/js/actions/__tests__/buckets.test.js
+++ b/browser/app/js/actions/__tests__/buckets.test.js
@@ -40,6 +40,26 @@ describe("Buckets actions", () => {
})
})
+ it("creates buckets/SET_LIST directly", () => {
+ const store = mockStore()
+ const expectedActions = [
+ { type: "buckets/SET_LIST", buckets: ["test1", "test2"] }
+ ]
+ store.dispatch(actionsBuckets.setList(["test1", "test2"]))
+ const actions = store.getActions()
+ expect(actions).toEqual(expectedActions)
+ })
+
+ it("creates buckets/SET_FILTER directly", () => {
+ const store = mockStore()
+ const expectedActions = [
+ { type: "buckets/SET_FILTER", filter: "test" }
+ ]
+ store.dispatch(actionsBuckets.setFilter("test"))
+ const actions = store.getActions()
+ expect(actions).toEqual(expectedActions)
+ })
+
it("should update browser url and creates buckets/SET_CURRENT_BUCKET action when selectBucket is called", () => {
const store = mockStore()
const expectedActions = [
diff --git a/browser/app/js/components/Login.js b/browser/app/js/components/Login.js
index e74375942..3bc6aa7a2 100644
--- a/browser/app/js/components/Login.js
+++ b/browser/app/js/components/Login.js
@@ -28,21 +28,16 @@ import { Redirect } from "react-router-dom"
export class Login extends React.Component {
handleSubmit(event) {
event.preventDefault()
- const { dispatch, history } = this.props
+ const { showAlert, history } = this.props
let message = ""
if (!document.getElementById("accessKey").value) {
- message = "Secret Key cannot be empty"
- }
- if (!document.getElementById("secretKey").value) {
message = "Access Key cannot be empty"
}
+ if (!document.getElementById("secretKey").value) {
+ message = "Secret Key cannot be empty"
+ }
if (message) {
- dispatch(
- actionsAlert.set({
- type: "danger",
- message
- })
- )
+ showAlert("danger", message)
return
}
web
@@ -54,19 +49,14 @@ export class Login extends React.Component {
history.push(minioBrowserPrefix)
})
.catch(e => {
- dispatch(
- actionsAlert.set({
- type: "danger",
- message: e.message
- })
- )
+ showAlert("danger", e.message)
})
}
componentWillMount() {
- const { dispatch } = this.props
+ const { clearAlert } = this.props
// Clear out any stale message in the alert of previous page
- dispatch(actionsAlert.clear())
+ clearAlert()
document.body.classList.add("is-guest")
}
@@ -74,17 +64,12 @@ export class Login extends React.Component {
document.body.classList.remove("is-guest")
}
- clearAlert() {
- const { dispatch } = this.props
- dispatch(actionsAlert.clear())
- }
-
render() {
- const { alert } = this.props
+ const { clearAlert, alert } = this.props
if (web.LoggedIn()) {
return
}
- let alertBox =
+ let alertBox =
// Make sure you don't show a fading out alert box on the initial web-page load.
if (!alert.message) alertBox = ""
return (
@@ -128,4 +113,11 @@ export class Login extends React.Component {
}
}
-export default connect(state => state)(Login)
+const mapDispatchToProps = dispatch => {
+ return {
+ showAlert: (type, message) => dispatch(actionsAlert.set({type: type, message: message})),
+ clearAlert: () => dispatch(actionsAlert.clear())
+ }
+}
+
+export default connect(state => state, mapDispatchToProps)(Login)
diff --git a/browser/app/js/components/__tests__/Alert.test.js b/browser/app/js/components/__tests__/Alert.test.js
new file mode 100644
index 000000000..5b8e3a492
--- /dev/null
+++ b/browser/app/js/components/__tests__/Alert.test.js
@@ -0,0 +1,34 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow, mount } from "enzyme"
+import Alert from "../Alert"
+
+describe("Alert", () => {
+ it("should render without crashing", () => {
+ shallow()
+ })
+
+ it("should call onDismiss when close button is clicked", () => {
+ const onDismiss = jest.fn()
+ const wrapper = mount(
+
+ )
+ wrapper.find("button").simulate("click", { preventDefault: jest.fn() })
+ expect(onDismiss).toHaveBeenCalled()
+ })
+})
diff --git a/browser/app/js/components/__tests__/App.test.js b/browser/app/js/components/__tests__/App.test.js
new file mode 100644
index 000000000..7548cbacd
--- /dev/null
+++ b/browser/app/js/components/__tests__/App.test.js
@@ -0,0 +1,25 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow } from "enzyme"
+import App from "../App"
+
+describe("App", () => {
+ it("should render without crashing", () => {
+ shallow()
+ })
+})
diff --git a/browser/app/js/components/__tests__/Browser.test.js b/browser/app/js/components/__tests__/Browser.test.js
new file mode 100644
index 000000000..3bb5a0e45
--- /dev/null
+++ b/browser/app/js/components/__tests__/Browser.test.js
@@ -0,0 +1,29 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow } from "enzyme"
+import Browser from "../Browser"
+import configureStore from "redux-mock-store"
+
+const mockStore = configureStore()
+
+describe("Browser", () => {
+ it("should render without crashing", () => {
+ const store = mockStore()
+ shallow()
+ })
+})
diff --git a/browser/app/js/components/__tests__/BucketContainer.test.js b/browser/app/js/components/__tests__/BucketContainer.test.js
new file mode 100644
index 000000000..2c3807d8a
--- /dev/null
+++ b/browser/app/js/components/__tests__/BucketContainer.test.js
@@ -0,0 +1,52 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow } from "enzyme"
+import BucketContainer from "../BucketContainer"
+import configureStore from "redux-mock-store"
+
+const mockStore = configureStore()
+
+describe("BucketContainer", () => {
+ let store
+ beforeEach(() => {
+ store = mockStore({
+ buckets: {
+ currentBucket: "Test"
+ }
+ })
+ store.dispatch = jest.fn()
+ })
+
+ it("should render without crashing", () => {
+ shallow()
+ })
+
+ it('maps state and dispatch to props', () => {
+ const wrapper = shallow()
+ expect(wrapper.props()).toEqual(expect.objectContaining({
+ isActive: expect.any(Boolean),
+ selectBucket: expect.any(Function)
+ }))
+ })
+
+ it('maps selectBucket to dispatch action', () => {
+ const wrapper = shallow()
+ wrapper.props().selectBucket()
+ expect(store.dispatch).toHaveBeenCalled()
+ })
+})
diff --git a/browser/app/js/components/__tests__/BucketList.test.js b/browser/app/js/components/__tests__/BucketList.test.js
index cda8bf5ad..b64d29192 100644
--- a/browser/app/js/components/__tests__/BucketList.test.js
+++ b/browser/app/js/components/__tests__/BucketList.test.js
@@ -18,7 +18,12 @@ import React from "react"
import { shallow } from "enzyme"
import { BucketList } from "../BucketList"
-describe("Bucket", () => {
+describe("BucketList", () => {
+ it("should render without crashing", () => {
+ const fetchBuckets = jest.fn()
+ shallow()
+ })
+
it("should call fetchBuckets before component is mounted", () => {
const fetchBuckets = jest.fn()
const wrapper = shallow(
diff --git a/browser/app/js/components/__tests__/Host.test.js b/browser/app/js/components/__tests__/Host.test.js
new file mode 100644
index 000000000..6fcea1026
--- /dev/null
+++ b/browser/app/js/components/__tests__/Host.test.js
@@ -0,0 +1,25 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow } from "enzyme"
+import Host from "../Host"
+
+describe("Host", () => {
+ it("should render without crashing", () => {
+ shallow()
+ })
+})
diff --git a/browser/app/js/components/__tests__/Login.test.js b/browser/app/js/components/__tests__/Login.test.js
new file mode 100644
index 000000000..f8e5f8775
--- /dev/null
+++ b/browser/app/js/components/__tests__/Login.test.js
@@ -0,0 +1,99 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow, mount } from "enzyme"
+import { Login } from "../Login"
+import web from "../../web"
+
+jest.mock('../../web', () => ({
+ Login: jest.fn(() => {
+ return Promise.resolve({ token: "test", uiVersion: "2018-02-01T01:17:47Z" })
+ }),
+ LoggedIn: jest.fn()
+}))
+
+describe("Login", () => {
+ const dispatchMock = jest.fn()
+ const showAlertMock = jest.fn()
+ const clearAlertMock = jest.fn()
+
+ it("should render without crashing", () => {
+ shallow()
+ })
+
+ it("should initially have the is-guest class", () => {
+ const wrapper = shallow(
+ ,
+ { attachTo: document.body }
+ )
+ expect(document.body.classList.contains("is-guest")).toBeTruthy()
+ })
+
+ it("should throw an alert if the keys are empty in login form", () => {
+ const wrapper = mount(
+ ,
+ { attachTo: document.body }
+ )
+ // case where both keys are empty - displays the second warning
+ wrapper.find("form").simulate("submit")
+ expect(showAlertMock).toHaveBeenCalledWith("danger", "Secret Key cannot be empty")
+
+ // case where access key is empty
+ document.getElementById("secretKey").value = "secretKey"
+ wrapper.find("form").simulate("submit")
+ expect(showAlertMock).toHaveBeenCalledWith("danger", "Access Key cannot be empty")
+
+ // case where secret key is empty
+ document.getElementById("accessKey").value = "accessKey"
+ wrapper.find("form").simulate("submit")
+ expect(showAlertMock).toHaveBeenCalledWith("danger", "Secret Key cannot be empty")
+ })
+
+ it("should call web.Login with correct arguments if both keys are entered", () => {
+ const wrapper = mount(
+ ,
+ { attachTo: document.body }
+ )
+ document.getElementById("accessKey").value = "accessKey"
+ document.getElementById("secretKey").value = "secretKey"
+ wrapper.find("form").simulate("submit")
+ expect(web.Login).toHaveBeenCalledWith({
+ "username": "accessKey",
+ "password": "secretKey"
+ })
+ })
+})
diff --git a/browser/app/js/components/__tests__/SideBar.test.js b/browser/app/js/components/__tests__/SideBar.test.js
new file mode 100644
index 000000000..f1020de29
--- /dev/null
+++ b/browser/app/js/components/__tests__/SideBar.test.js
@@ -0,0 +1,27 @@
+/*
+ * Minio Cloud Storage (C) 2018 Minio, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import React from "react"
+import { shallow } from "enzyme"
+import { SideBar } from "../SideBar"
+
+describe("SideBar", () => {
+ it("should render without crashing", () => {
+ shallow()
+ })
+
+ // ClickOutHandler test to be added when corresponding function is added
+})
diff --git a/browser/app/js/jest/__mocks__/fileMock.js b/browser/app/js/jest/__mocks__/fileMock.js
new file mode 100644
index 000000000..84c1da6fd
--- /dev/null
+++ b/browser/app/js/jest/__mocks__/fileMock.js
@@ -0,0 +1 @@
+module.exports = 'test-file-stub';
\ No newline at end of file
diff --git a/browser/app/js/reducers/__tests__/buckets.test.js b/browser/app/js/reducers/__tests__/buckets.test.js
index e27e36cb3..38b68515e 100644
--- a/browser/app/js/reducers/__tests__/buckets.test.js
+++ b/browser/app/js/reducers/__tests__/buckets.test.js
@@ -27,7 +27,7 @@ describe("buckets reducer", () => {
})
})
- it("should handle SET_BUCKETS", () => {
+ it("should handle SET_LIST", () => {
const newState = reducer(undefined, {
type: actions.SET_LIST,
buckets: ["bk1", "bk2"]
@@ -35,7 +35,7 @@ describe("buckets reducer", () => {
expect(newState.list).toEqual(["bk1", "bk2"])
})
- it("should handle SET_BUCKETS_FILTER", () => {
+ it("should handle SET_FILTER", () => {
const newState = reducer(undefined, {
type: actions.SET_FILTER,
filter: "test"
@@ -43,7 +43,7 @@ describe("buckets reducer", () => {
expect(newState.filter).toEqual("test")
})
- it("should handle SELECT_BUCKET", () => {
+ it("should handle SET_CURRENT_BUCKET", () => {
const newState = reducer(undefined, {
type: actions.SET_CURRENT_BUCKET,
bucket: "test"
diff --git a/browser/package.json b/browser/package.json
index 3860e2d49..9a265d4f8 100644
--- a/browser/package.json
+++ b/browser/package.json
@@ -13,7 +13,9 @@
"setupTestFrameworkScriptFile": "./app/js/jest/setup.js",
"testURL": "https://localhost:8080",
"moduleNameMapper": {
- "\\.(css|scss|svg)$": "identity-obj-proxy"
+ "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$":
+ "/app/js/jest/__mocks__/fileMock.js",
+ "\\.(css|scss)$": "identity-obj-proxy"
}
},
"repository": {