Add unit tests

Add unit tests for backend and frontend.

Issue-ID: CLAMP-512
Change-Id: I713ba2dce3bd132e7e3e713f4e91e3662df7aafd
Signed-off-by: xuegao <xg353y@intl.att.com>
diff --git a/ui-react/src/LoopUI.test.js b/ui-react/src/LoopUI.test.js
new file mode 100644
index 0000000..e28096b
--- /dev/null
+++ b/ui-react/src/LoopUI.test.js
@@ -0,0 +1,171 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import LoopUI from './LoopUI';
+
+import LoopCache from './api/LoopCache';
+import LoopActionService from './api/LoopActionService';
+import LoopService from './api/LoopService';
+
+describe('Verify LoopUI', () => {
+	beforeEach(() => {
+		fetch.resetMocks();
+		fetch.mockImplementation(() => {
+			return Promise.resolve({
+				ok: true,
+				status: 200,
+				text: () => "testUser"
+
+			});
+		});
+	})
+
+	const loopCache = new LoopCache({
+		"name": "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
+		"components": {
+			"POLICY": {
+				"componentState": {
+					"stateName": "UNKNOWN",
+					"description": "The policies defined have NOT yet been created on the policy engine"
+				}
+			},
+			"DCAE": {
+				"componentState": {
+					"stateName": "BLUEPRINT_DEPLOYED",
+					"description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop"
+				}
+			}
+		}
+	});
+
+	it('Test the render method', async () => {
+		const flushPromises = () => new Promise(setImmediate);
+
+		const component = shallow(<LoopUI />)
+		component.setState({
+			loopName: "testLoopName",
+			showAlert: false 
+		});
+		await flushPromises();
+		expect(component).toMatchSnapshot();
+	});
+
+	test('Test closeLoop method', () => {
+		const historyMock = { push: jest.fn() };
+		const component = shallow(<LoopUI history={historyMock}/>)
+		const instance = component.instance();
+		instance.closeLoop();
+			
+		expect(component.state('loopName')).toEqual("Empty (NO loop loaded yet)");
+		expect(historyMock.push.mock.calls[0]).toEqual([ '/']);
+	})
+
+	test('Test logout method', async () => {
+		const flushPromises = () => new Promise(setImmediate);
+		const component = shallow(<LoopUI />)
+		const instance = component.instance();
+		instance.logout();
+		await flushPromises();
+		expect(component.state('userName')).toEqual("testUser");
+	})
+
+	test('Test loadLoop method refresh suc', async () => {
+		const historyMock = { push: jest.fn() };
+		LoopService.getLoop = jest.fn().mockImplementation(() => {
+			return Promise.resolve({
+				ok: true,
+				status: 200,
+				text: () => {}
+			});
+		});
+
+		LoopActionService.refreshStatus = jest.fn().mockImplementation(() => {
+			return Promise.resolve({name: "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca"});
+		});
+
+		const flushPromises = () => new Promise(setImmediate);
+		const component = shallow(<LoopUI history={historyMock}/>)
+		const instance = component.instance();
+		instance.loadLoop("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
+
+		await flushPromises();
+
+		const resLoopCache = instance.getLoopCache();
+			
+		expect(resLoopCache.getComponentStates()).toBeUndefined();
+		expect(component.state('loopName')).toEqual("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
+	})
+
+	test('Test loadLoop method refresh fail', async () => {
+		const historyMock = { push: jest.fn() };
+		LoopService.getLoop = jest.fn().mockImplementation(() => {
+			return Promise.resolve({
+			name: "LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca",
+			"components": {
+				"POLICY": {
+					"componentState": {
+						"stateName": "UNKNOWN",
+						"description": "The policies defined have NOT yet been created on the policy engine"
+					}
+				},
+				"DCAE": {
+					"componentState": {
+						"stateName": "BLUEPRINT_DEPLOYED",
+						"description": "The DCAE blueprint has been found in the DCAE inventory but not yet instancianted for this loop"
+					}
+				}
+			}});
+		});
+
+		LoopActionService.refreshStatus = jest.fn().mockImplementation(() => {
+			return Promise.reject({error: "whatever"});
+		});
+
+		const flushPromises = () => new Promise(setImmediate);
+		const component = shallow(<LoopUI history={historyMock}/>)
+		const instance = component.instance();
+		instance.loadLoop("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
+
+		await flushPromises();
+
+		const resLoopCache = instance.getLoopCache();
+			
+		expect(resLoopCache).toEqual(loopCache);
+		expect(component.state('loopName')).toEqual("LOOP_Jbv1z_v1_0_ResourceInstanceName1_tca");
+	})
+
+	test('Test alert methods', () => {
+		const component = shallow(<LoopUI />)
+		expect(component.state('showAlert')).toEqual(false);
+
+		const instance = component.instance();
+		instance.showAlert("testAlert");
+		expect(component.state('showAlert')).toEqual(true);
+		expect(component.state('showMessage')).toEqual("testAlert");
+
+		instance.disableAlert();
+			
+		expect(component.state('showAlert')).toEqual(false);
+	})
+});
diff --git a/ui-react/src/NotFound.test.js b/ui-react/src/NotFound.test.js
new file mode 100644
index 0000000..3a5fc10
--- /dev/null
+++ b/ui-react/src/NotFound.test.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import NotFound from './NotFound';
+
+describe('Verify OnapClamp', () => {
+
+	it('Test the render method',  () => {
+
+		const component = shallow(<NotFound />)
+
+		expect(component).toMatchSnapshot();
+	});
+
+});
diff --git a/ui-react/src/OnapClamp.test.js b/ui-react/src/OnapClamp.test.js
new file mode 100644
index 0000000..c3336a9
--- /dev/null
+++ b/ui-react/src/OnapClamp.test.js
@@ -0,0 +1,36 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP CLAMP
+ * ================================================================================
+ * Copyright (C) 2019 AT&T Intellectual Property. All rights
+ *                             reserved.
+ * ================================================================================
+ * 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.
+ * ============LICENSE_END============================================
+ * ===================================================================
+ *
+ */
+import React from 'react';
+import { shallow } from 'enzyme';
+import OnapClamp from './OnapClamp';
+
+describe('Verify OnapClamp', () => {
+
+	it('Test the render method',  () => {
+
+		const component = shallow(<OnapClamp />)
+
+		expect(component).toMatchSnapshot();
+	});
+
+});
diff --git a/ui-react/src/__snapshots__/LoopUI.test.js.snap b/ui-react/src/__snapshots__/LoopUI.test.js.snap
new file mode 100644
index 0000000..ecf439e
--- /dev/null
+++ b/ui-react/src/__snapshots__/LoopUI.test.js.snap
@@ -0,0 +1,154 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Verify LoopUI Test the render method 1`] = `
+<styled.div
+  id="main_div"
+>
+  <Route
+    path="/operationalPolicyModal"
+    render={[Function]}
+  />
+  <Route
+    path="/configurationPolicyModal/:componentName"
+    render={[Function]}
+  />
+  <Route
+    path="/openLoop"
+    render={[Function]}
+  />
+  <Route
+    path="/loopProperties"
+    render={[Function]}
+  />
+  <Route
+    path="/userInfo"
+    render={[Function]}
+  />
+  <Route
+    path="/closeLoop"
+    render={[Function]}
+  />
+  <Route
+    path="/submit"
+    render={[Function]}
+  />
+  <Route
+    path="/stop"
+    render={[Function]}
+  />
+  <Route
+    path="/restart"
+    render={[Function]}
+  />
+  <Route
+    path="/delete"
+    render={[Function]}
+  />
+  <Route
+    path="/undeploy"
+    render={[Function]}
+  />
+  <Route
+    path="/deploy"
+    render={[Function]}
+  />
+  <Route
+    path="/refreshStatus"
+    render={[Function]}
+  />
+  <Route
+    path="/logout"
+    render={[Function]}
+  />
+  <GlobalStyleComponent />
+  <Alert
+    closeLabel="Close alert"
+    dismissible={true}
+    onClose={[Function]}
+    show={false}
+    transition={
+      Object {
+        "$$typeof": Symbol(react.forward_ref),
+        "defaultProps": Object {
+          "appear": false,
+          "in": false,
+          "mountOnEnter": false,
+          "timeout": 300,
+          "unmountOnExit": false,
+        },
+        "displayName": "Fade",
+        "render": [Function],
+      }
+    }
+    variant="danger"
+  />
+  <Navbar
+    collapseOnSelect={false}
+    expand={true}
+    variant="light"
+  >
+    <NavbarBrand>
+      <img
+        alt=""
+        height="50px"
+        src={null}
+        width="234px"
+      />
+      <styled.a>
+        CLAMP
+      </styled.a>
+    </NavbarBrand>
+    <NavbarToggle
+      aria-controls="responsive-navbar-nav"
+      label="Toggle navigation"
+    />
+    <MenuBar
+      loopName="testLoopName"
+    />
+    <NavbarText>
+      <styled.a>
+        Signed in as: 
+      </styled.a>
+      <Styled(Link)
+        to="/userInfo"
+      >
+        testUser
+      </Styled(Link)>
+      <Styled(Link)
+        to="/logout/"
+      >
+         (logout)
+      </Styled(Link)>
+    </NavbarText>
+  </Navbar>
+  <styled.div>
+    <styled.div>
+      Loop Viewer - 
+      testLoopName
+    </styled.div>
+    <styled.div>
+      <withRouter(LoopViewSvg)
+        loopCache={
+          LoopCache {
+            "loopJsonCache": Object {},
+          }
+        }
+      />
+      <LoopStatus
+        loopCache={
+          LoopCache {
+            "loopJsonCache": Object {},
+          }
+        }
+      />
+      <LoopLogs
+        loopCache={
+          LoopCache {
+            "loopJsonCache": Object {},
+          }
+        }
+      />
+    </styled.div>
+  </styled.div>
+</styled.div>
+`;
diff --git a/ui-react/src/__snapshots__/NotFound.test.js.snap b/ui-react/src/__snapshots__/NotFound.test.js.snap
new file mode 100644
index 0000000..86bcfd1
--- /dev/null
+++ b/ui-react/src/__snapshots__/NotFound.test.js.snap
@@ -0,0 +1,26 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Verify OnapClamp Test the render method 1`] = `
+<div
+  id="main"
+>
+  <div
+    class="divRow"
+  >
+    <b>
+      Page Not Found!
+    </b>
+  </div>
+  <div
+    class="divRow"
+  >
+    Please cick 
+    <a
+      href="/"
+    >
+      here
+    </a>
+     to go back to the main page.
+  </div>
+</div>
+`;
diff --git a/ui-react/src/__snapshots__/OnapClamp.test.js.snap b/ui-react/src/__snapshots__/OnapClamp.test.js.snap
new file mode 100644
index 0000000..751c94b
--- /dev/null
+++ b/ui-react/src/__snapshots__/OnapClamp.test.js.snap
@@ -0,0 +1,176 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`Verify OnapClamp Test the render method 1`] = `
+<ThemeProvider
+  theme={
+    Object {
+      "backgroundColor": "#eeeeee",
+      "fontDanger": "#eb238e",
+      "fontDark": "#888888",
+      "fontFamily": "Arial, Sans-serif",
+      "fontHighlight": "#ffff00",
+      "fontLight": "#ffffff",
+      "fontNormal": "black",
+      "fontSize": "16px",
+      "fontWarning": "#eb238e",
+      "loopViewerBackgroundColor": "white",
+      "loopViewerFontColor": "yellow",
+      "loopViewerHeaderBackgroundColor": "#337ab7",
+      "loopViewerHeaderFontColor": "white",
+      "menuBackgroundColor": "white",
+      "menuFontColor": "black",
+      "menuHighlightedBackgroundColor": "#337ab7",
+      "menuHighlightedFontColor": "white",
+    }
+  }
+>
+  <styled.div
+    id="main_div"
+  >
+    <Route
+      path="/operationalPolicyModal"
+      render={[Function]}
+    />
+    <Route
+      path="/configurationPolicyModal/:componentName"
+      render={[Function]}
+    />
+    <Route
+      path="/openLoop"
+      render={[Function]}
+    />
+    <Route
+      path="/loopProperties"
+      render={[Function]}
+    />
+    <Route
+      path="/userInfo"
+      render={[Function]}
+    />
+    <Route
+      path="/closeLoop"
+      render={[Function]}
+    />
+    <Route
+      path="/submit"
+      render={[Function]}
+    />
+    <Route
+      path="/stop"
+      render={[Function]}
+    />
+    <Route
+      path="/restart"
+      render={[Function]}
+    />
+    <Route
+      path="/delete"
+      render={[Function]}
+    />
+    <Route
+      path="/undeploy"
+      render={[Function]}
+    />
+    <Route
+      path="/deploy"
+      render={[Function]}
+    />
+    <Route
+      path="/refreshStatus"
+      render={[Function]}
+    />
+    <Route
+      path="/logout"
+      render={[Function]}
+    />
+    <GlobalStyleComponent />
+    <Alert
+      closeLabel="Close alert"
+      dismissible={true}
+      onClose={[Function]}
+      show={false}
+      transition={
+        Object {
+          "$$typeof": Symbol(react.forward_ref),
+          "defaultProps": Object {
+            "appear": false,
+            "in": false,
+            "mountOnEnter": false,
+            "timeout": 300,
+            "unmountOnExit": false,
+          },
+          "displayName": "Fade",
+          "render": [Function],
+        }
+      }
+      variant="danger"
+    />
+    <Navbar
+      collapseOnSelect={false}
+      expand={true}
+      variant="light"
+    >
+      <NavbarBrand>
+        <img
+          alt=""
+          height="50px"
+          src={null}
+          width="234px"
+        />
+        <styled.a>
+          CLAMP
+        </styled.a>
+      </NavbarBrand>
+      <NavbarToggle
+        aria-controls="responsive-navbar-nav"
+        label="Toggle navigation"
+      />
+      <MenuBar
+        loopName="Empty (NO loop loaded yet)"
+      />
+      <NavbarText>
+        <styled.a>
+          Signed in as: 
+        </styled.a>
+        <Styled(Link)
+          to="/userInfo"
+        />
+        <Styled(Link)
+          to="/logout/"
+        >
+           (logout)
+        </Styled(Link)>
+      </NavbarText>
+    </Navbar>
+    <styled.div>
+      <styled.div>
+        Loop Viewer - 
+        Empty (NO loop loaded yet)
+      </styled.div>
+      <styled.div>
+        <withRouter(LoopViewSvg)
+          loopCache={
+            LoopCache {
+              "loopJsonCache": Object {},
+            }
+          }
+        />
+        <LoopStatus
+          loopCache={
+            LoopCache {
+              "loopJsonCache": Object {},
+            }
+          }
+        />
+        <LoopLogs
+          loopCache={
+            LoopCache {
+              "loopJsonCache": Object {},
+            }
+          }
+        />
+      </styled.div>
+    </styled.div>
+  </styled.div>
+</ThemeProvider>
+`;