Implement the CRUD operations for Test cases 67/49567/5
authorthuva4 <tharma.thuva@gmail.com>
Sat, 23 Dec 2017 03:56:12 +0000 (09:26 +0530)
committerthuva4 <tharma.thuva@gmail.com>
Sat, 23 Dec 2017 10:37:53 +0000 (16:07 +0530)
Created the testcases, testcase pages
Remove update, delete buttons in project page.
add protractor tests for testcases page.
change tabs to spaces

Change-Id: Id7d381b13dca4f228bda24fa1abad7c465b5cef7
Signed-off-by: thuva4 <tharma.thuva@gmail.com>
14 files changed:
testapi/opnfv_testapi/common/check.py
testapi/opnfv_testapi/tests/UI/e2e/testCasesControllerSpec.js [new file with mode: 0644]
testapi/opnfv_testapi/tests/unit/handlers/test_result.py
testapi/opnfv_testapi/tests/unit/handlers/test_testcase.py
testapi/opnfv_testapi/ui/Gruntfile.js
testapi/opnfv_testapi/ui/app.js
testapi/opnfv_testapi/ui/components/projects/project/project.html
testapi/opnfv_testapi/ui/components/projects/project/projectController.js
testapi/opnfv_testapi/ui/components/projects/project/testCases/modals/testCaseModal.html [new file with mode: 0644]
testapi/opnfv_testapi/ui/components/projects/project/testCases/testCase/testCase.html [new file with mode: 0644]
testapi/opnfv_testapi/ui/components/projects/project/testCases/testCase/testCaseController.js [new file with mode: 0644]
testapi/opnfv_testapi/ui/components/projects/project/testCases/testCases.html [new file with mode: 0644]
testapi/opnfv_testapi/ui/components/projects/project/testCases/testCasesController.js [new file with mode: 0644]
testapi/opnfv_testapi/ui/index.html

index db28e44..08b620d 100644 (file)
@@ -21,7 +21,7 @@ from opnfv_testapi.db import api as dbapi
 def is_authorized(method):
     @functools.wraps(method)
     def wrapper(self, *args, **kwargs):
-        if CONF.api_authenticate and self.table in ['pods', 'projects']:
+        if CONF.api_authenticate and self.table in ['pods', 'projects', 'testcases']:
             testapi_id = self.get_secure_cookie(constants.TESTAPI_ID)
             if not testapi_id:
                 raises.Unauthorized(message.not_login())
diff --git a/testapi/opnfv_testapi/tests/UI/e2e/testCasesControllerSpec.js b/testapi/opnfv_testapi/tests/UI/e2e/testCasesControllerSpec.js
new file mode 100644 (file)
index 0000000..d6b5b9f
--- /dev/null
@@ -0,0 +1,658 @@
+'use strict';
+
+var mock = require('protractor-http-mock');
+var baseURL = "http://localhost:8000/"
+
+describe('testing the testCases page for anonymous user', function () {
+    beforeEach(function(){
+        mock([
+            {
+                request: {
+                    path: '/api/v1/projects',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "projects": [
+                            {
+                                "owner": "thuva4",
+                                "_id": "5a0c022f9a07c846d3c2cc94",
+                                "creation_date": "2017-11-15 14:30:31.200259",
+                                "description": "dsfsd",
+                                "name": "testproject"
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "owner": "thuva4",
+                        "_id": "5a0c022f9a07c846d3c2cc94",
+                        "creation_date": "2017-11-15 14:30:31.200259",
+                        "description": "dsfsd",
+                        "name": "testproject"
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "testcases": [
+                            {
+                                "project_name": "testproject",
+                                "run": null,
+                                "description": null,
+                                "tags": null,
+                                "creation_date": "2017-12-20 18:47:04.025544",
+                                "dependencies": null,
+                                "tier": null,
+                                "trust": null,
+                                "blocking": null,
+                                "name": "testCase",
+                                "ci_loop": null,
+                                "url": null,
+                                "version": null,
+                                "criteria": null,
+                                "domains": null,
+                                "_id": "5a3a62d09a07c836e06858fb",
+                                "catalog_description": null
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases/testCase',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                            "project_name": "testproject",
+                            "run": null,
+                            "description": null,
+                            "tags": null,
+                            "creation_date": "2017-12-20 18:47:04.025544",
+                            "dependencies": null,
+                            "tier": null,
+                            "trust": null,
+                            "blocking": null,
+                            "name": "testCase",
+                            "ci_loop": null,
+                            "url": null,
+                            "version": null,
+                            "criteria": null,
+                            "domains": null,
+                            "_id": "5a3a62d09a07c836e06858fb",
+                            "catalog_description": null
+                    }
+                }
+            }
+        ]);
+    });
+
+    afterEach(function(){
+        mock.teardown();
+    });
+
+    it( 'should show the testCases for anonymous user', function() {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var row = element.all(by.repeater('(index, testcase) in testCasesCtrl.data.testcases')).first();
+        var cells = row.all(by.tagName('td'));
+        expect(cells.get(1).getText()).toContain("testCase");
+    });
+
+    it( 'navigate anonymous user to testCase page', function() {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var testCase = element(by.linkText('testCase'));
+        testCase.click();
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.urlContains(baseURL+ '#/projects/testproject/testCase'), 10000);
+    });
+
+    it('create button is not visible for anonymous user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var buttonCreate = element(by.buttonText('Create'));
+        expect(buttonCreate.isDisplayed()).toBeFalsy();
+    });
+
+    it('Delete button is not visible for anonymous user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var buttonDelete = element(by.buttonText('Delete'));
+        expect(buttonDelete.isDisplayed()).toBeFalsy();
+    });
+
+    it('delete Operation is not visible for anonymous user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var deleteOperation = element(by.css('a[title=Delete]'));
+        expect(deleteOperation.isDisplayed()).toBeFalsy();
+    });
+
+    it('Edit Operation is not visible for anonymous user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var editOperation = element(by.css('a[title=Edit]'));
+        expect(editOperation.isDisplayed()).toBeFalsy();
+    });
+});
+
+describe('testing the testcaese page for user who is not in submitter group', function () {
+        beforeEach(function(){
+            mock([
+                {
+                    request: {
+                    path: '/api/v1/profile',
+                    method: 'GET'
+                    },
+                    response: {
+                        data: {
+                            "fullname": "Test User", "_id": "79f82eey9a00c84bfhc7aed",
+                            "user": "testUser", "groups": ["opnfv-testapi-users"],
+                            "email": "testuser@test.com"
+                        }
+                    }
+                },
+                {
+                    request: {
+                        path: '/api/v1/projects',
+                        method: 'GET'
+                    },
+                    response: {
+                        data: {
+                            "projects": [
+                                {
+                                    "owner": "thuva4",
+                                    "_id": "5a0c022f9a07c846d3c2cc94",
+                                    "creation_date": "2017-11-15 14:30:31.200259",
+                                    "description": "dsfsd",
+                                    "name": "testproject"
+                                }
+                            ]
+                        }
+                    }
+                },
+                {
+                    request: {
+                        path: '/api/v1/projects/testproject',
+                        method: 'GET'
+                    },
+                    response: {
+                        data: {
+                            "owner": "thuva4",
+                            "_id": "5a0c022f9a07c846d3c2cc94",
+                            "creation_date": "2017-11-15 14:30:31.200259",
+                            "description": "dsfsd",
+                            "name": "testproject"
+                        }
+                    }
+                },
+                {
+                    request: {
+                        path: '/api/v1/projects/testproject/cases',
+                        method: 'GET'
+                    },
+                    response: {
+                        data: {
+                            "testcases": [
+                                {
+                                    "project_name": "testproject",
+                                    "run": null,
+                                    "description": null,
+                                    "tags": null,
+                                    "creation_date": "2017-12-20 18:47:04.025544",
+                                    "dependencies": null,
+                                    "tier": null,
+                                    "trust": null,
+                                    "blocking": null,
+                                    "name": "testCase",
+                                    "ci_loop": null,
+                                    "url": null,
+                                    "version": null,
+                                    "criteria": null,
+                                    "domains": null,
+                                    "_id": "5a3a62d09a07c836e06858fb",
+                                    "catalog_description": null
+                                }
+                            ]
+                        }
+                    }
+                },
+                {
+                    request: {
+                        path: '/api/v1/projects/testproject/cases/testCase',
+                        method: 'GET'
+                    },
+                    response: {
+                        data: {
+                                "project_name": "testproject",
+                                "run": null,
+                                "description": null,
+                                "tags": null,
+                                "creation_date": "2017-12-20 18:47:04.025544",
+                                "dependencies": null,
+                                "tier": null,
+                                "trust": null,
+                                "blocking": null,
+                                "name": "testCase",
+                                "ci_loop": null,
+                                "url": null,
+                                "version": null,
+                                "criteria": null,
+                                "domains": null,
+                                "_id": "5a3a62d09a07c836e06858fb",
+                                "catalog_description": null
+                        }
+                    }
+                }
+            ]);
+        });
+
+        afterEach(function(){
+            mock.teardown();
+        });
+
+        it( 'should show the testCases for  user', function() {
+            browser.get(baseURL+"#/projects/testproject");
+            var testCases = element(by.linkText('Test Cases'));
+            testCases.click();
+            var row = element.all(by.repeater('(index, testcase) in testCasesCtrl.data.testcases')).first();
+            var cells = row.all(by.tagName('td'));
+            expect(cells.get(1).getText()).toContain("testCase");
+        });
+
+        it( 'navigate  user to testCase page', function() {
+            browser.get(baseURL+"#/projects/testproject");
+            var testCases = element(by.linkText('Test Cases'));
+            testCases.click();
+            var testCase = element(by.linkText('testCase'));
+            testCase.click();
+            var EC = browser.ExpectedConditions;
+            browser.wait(EC.urlContains(baseURL+ '#/projects/testproject/testCase'), 10000);
+        });
+
+        it('create button is not visible for  user ', function () {
+            browser.get(baseURL+"#/projects/testproject");
+            var testCases = element(by.linkText('Test Cases'));
+            testCases.click();
+            var buttonCreate = element(by.buttonText('Create'));
+            expect(buttonCreate.isDisplayed()).toBeFalsy();
+        });
+
+        it('Delete button is not visible for  user ', function () {
+            browser.get(baseURL+"#/projects/testproject");
+            var testCases = element(by.linkText('Test Cases'));
+            testCases.click();
+            var buttonDelete = element(by.buttonText('Delete'));
+            expect(buttonDelete.isDisplayed()).toBeFalsy();
+        });
+
+        it('delete Operation is not visible for  user ', function () {
+            browser.get(baseURL+"#/projects/testproject");
+            var testCases = element(by.linkText('Test Cases'));
+            testCases.click();
+            var deleteOperation = element(by.css('a[title=Delete]'));
+            expect(deleteOperation.isDisplayed()).toBeFalsy();
+        });
+
+        it('Edit Operation is not visible for  user ', function () {
+            browser.get(baseURL+"#/projects/testproject");
+            var testCases = element(by.linkText('Test Cases'));
+            testCases.click();
+            var editOperation = element(by.css('a[title=Edit]'));
+            expect(editOperation.isDisplayed()).toBeFalsy();
+        });
+})
+
+describe('testing the test cases page for user who is in submitter group', function () {
+    beforeEach(function(){
+        mock([
+            {
+                request: {
+                    path: '/api/v1/profile',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "fullname": "Test User", "_id": "79f82eey9a00c84bfhc7aed",
+                        "user": "testUser", "groups": ["opnfv-testapi-users",
+                        "opnfv-gerrit-testProject-submitters"],
+                        "email": "testuser@test.com"
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases',
+                    method: 'POST'
+                },
+                response: {
+                    data: {
+                        href: baseURL+"/api/v1/projects/testProject/cases/testCase"
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases/testCase',
+                    method: 'PUT'
+                },
+                response: {
+                    data: {
+                        href: baseURL+"/api/v1/projects/testProject/cases/testCase"
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases/testCase',
+                    method: 'DELETE'
+                },
+                response: {
+                    data: {
+                        href: baseURL+"/api/v1/projects/testProject/cases/testCase"
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testProject3/cases',
+                    method: 'POST',
+                    data: {
+                        name: 'testCase2',
+                        description : 'demoDescription',
+                    }
+                },
+                response: {
+                    status : 403,
+                    data : 'You do not have permission to perform this action'
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "projects": [
+                            {
+                                "owner": "thuva4",
+                                "_id": "5a0c022f9a07c846d3c2cc94",
+                                "creation_date": "2017-11-15 14:30:31.200259",
+                                "description": "dsfsd",
+                                "name": "testproject"
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "owner": "thuva4",
+                        "_id": "5a0c022f9a07c846d3c2cc94",
+                        "creation_date": "2017-11-15 14:30:31.200259",
+                        "description": "dsfsd",
+                        "name": "testproject"
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                        "testcases": [
+                            {
+                                "project_name": "testproject",
+                                "run": null,
+                                "description": null,
+                                "tags": null,
+                                "creation_date": "2017-12-20 18:47:04.025544",
+                                "dependencies": null,
+                                "tier": null,
+                                "trust": null,
+                                "blocking": null,
+                                "name": "testCase",
+                                "ci_loop": null,
+                                "url": null,
+                                "version": null,
+                                "criteria": null,
+                                "domains": null,
+                                "_id": "5a3a62d09a07c836e06858fb",
+                                "catalog_description": null
+                            }
+                        ]
+                    }
+                }
+            },
+            {
+                request: {
+                    path: '/api/v1/projects/testproject/cases/testCase',
+                    method: 'GET'
+                },
+                response: {
+                    data: {
+                            "project_name": "testproject",
+                            "run": null,
+                            "description": null,
+                            "tags": null,
+                            "creation_date": "2017-12-20 18:47:04.025544",
+                            "dependencies": null,
+                            "tier": null,
+                            "trust": null,
+                            "blocking": null,
+                            "name": "testCase",
+                            "ci_loop": null,
+                            "url": null,
+                            "version": null,
+                            "criteria": null,
+                            "domains": null,
+                            "_id": "5a3a62d09a07c836e06858fb",
+                            "catalog_description": null
+                    }
+                }
+            }
+        ]);
+    });
+
+    afterEach(function(){
+        mock.teardown();
+    });
+
+    it( 'should show the testCases for  user', function() {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var row = element.all(by.repeater('(index, testcase) in testCasesCtrl.data.testcases')).first();
+        var cells = row.all(by.tagName('td'));
+        expect(cells.get(1).getText()).toContain("testCase");
+    });
+
+    it( 'navigate user to testCase page', function() {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var testCase = element(by.linkText('testCase'));
+        testCase.click();
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.urlContains(baseURL+ '#/projects/testproject/testCase'), 10000);
+    });
+
+    it('create button is visible for  user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var buttonCreate = element(by.buttonText('Create'));
+        expect(buttonCreate.isDisplayed()).toBe(true);
+    });
+
+    it('Delete button is visible for  user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var buttonDelete = element(by.buttonText('Delete'));
+        expect(buttonDelete.isDisplayed()).toBe(true);
+    });
+
+    it('delete Operation is visible for  user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var deleteOperation = element(by.css('a[title=Delete]'));
+        expect(deleteOperation.isDisplayed()).toBe(true);
+    });
+
+    it('Edit Operation is visible for  user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var editOperation = element(by.css('a[title=Edit]'));
+        expect(editOperation.isDisplayed()).toBe(true);
+    });
+
+    it('View Operation is visible for  user ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var viewOperation = element(by.css('a[class=text-info]'));
+        expect(viewOperation.isDisplayed()).toBe(true);
+    });
+
+    it('Create the test case', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var buttonCreate = element(by.buttonText('Create'));
+        buttonCreate.click();
+        var name = element(by.model('TestCaseModalCtrl.testcase.name'));
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.visibilityOf(name), 5000);
+        name.sendKeys('test');
+        var buttonOK = element(by.buttonText('Ok'));
+        buttonOK.click();
+        expect(element(by.cssContainingText(".alert","Testcase is successfully created."))
+        .isDisplayed()).toBe(true);
+    });
+
+    it('Showing error when creating with a empty name ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var buttonCreate = element(by.buttonText('Create'));
+        buttonCreate.click();
+        var name = element(by.model('TestCaseModalCtrl.testcase.name'));
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.visibilityOf(name), 5000);
+        var buttonOK = element(by.buttonText('Ok'));
+        buttonOK.click();
+        expect(element(by.cssContainingText(".alert","Name is missing."))
+        .isDisplayed()).toBe(true);
+    });
+
+    it('cancel the delete confimation modal of the test case ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var deleteOperation = element(by.css('a[title=Delete]'));
+        deleteOperation.click();
+        var buttonCancel = element(by.buttonText('Cancel'));
+        buttonCancel.click();
+        expect(buttonCancel.isPresent()).toBe(false);
+    });
+
+    it('Delete the test case ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var deleteOperation = element(by.css('a[title=Delete]'));
+        deleteOperation.click();
+        var buttonOK = element(by.buttonText('Ok'));
+        buttonOK.click();
+        expect(element(by.cssContainingText(".alert","Test case is successfully deleted"))
+        .isDisplayed()).toBe(true);
+    });
+
+    it('cancel the Edit modal of the test case ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var editOperation = element(by.css('a[title=Edit]'));
+        editOperation.click();
+        var name = element(by.model('TestCaseModalCtrl.testcase.name'));
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.visibilityOf(name), 5000);
+        name.sendKeys('test1');
+        var buttonCancel = element(by.buttonText('Cancel'));
+        buttonCancel.click();
+        expect(name.isPresent()).toBe(false);
+    });
+
+    it('Edit the test case ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var editOperation = element(by.css('a[title=Edit]'));
+        editOperation.click();
+        var name = element(by.model('TestCaseModalCtrl.testcase.name'));
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.visibilityOf(name), 5000);
+        name.sendKeys('test1');
+        var buttonOK = element(by.buttonText('Ok'));
+        buttonOK.click();
+        expect(element(by.cssContainingText(".alert","Test case is successfully updated"))
+        .isDisplayed()).toBe(true);
+    });
+
+    it('view the test case ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var viewOperation = element(by.css('a[class=text-info]'));
+        viewOperation.click();
+        var name = element(by.model('TestCaseModalCtrl.testcase.name'));
+        var EC = browser.ExpectedConditions;
+        browser.wait(EC.urlContains(baseURL+ '#/projects/testproject/testCase'), 10000);
+    });
+
+    it('Batch Delete the test Cases ', function () {
+        browser.get(baseURL+"#/projects/testproject");
+        var testCases = element(by.linkText('Test Cases'));
+        testCases.click();
+        var checkBox = element(by.model('testCasesCtrl.checkBox[index]'));
+        checkBox.click();
+        var buttonDelete = element(by.buttonText('Delete'));;
+        buttonDelete.click();
+        var buttonOK = element(by.buttonText('Ok'));
+        buttonOK.click();
+        expect(element(by.cssContainingText(".alert","Test case is successfully deleted"))
+        .isDisplayed()).toBe(true);
+    });
+})
index bd482a6..ac74741 100644 (file)
@@ -52,6 +52,7 @@ class Details(object):
 
 
 class TestResultBase(base.TestBase):
+    @executor.mock_valid_lfid()
     def setUp(self):
         super(TestResultBase, self).setUp()
         self.pod = self.pod_d.name
index d5e32e3..643057c 100644 (file)
@@ -57,21 +57,26 @@ class TestCaseBase(base.TestBase):
         self.assertIsNotNone(new._id)
         self.assertIsNotNone(new.creation_date)
 
+    @executor.mock_valid_lfid()
     def create_d(self):
         return super(TestCaseBase, self).create_d(self.project)
 
+    @executor.mock_valid_lfid()
     def create_e(self):
         return super(TestCaseBase, self).create_e(self.project)
 
     def get(self, case=None):
         return super(TestCaseBase, self).get(self.project, case)
 
+    @executor.mock_valid_lfid()
     def create(self, req=None, *args):
         return super(TestCaseBase, self).create(req, self.project)
 
+    @executor.mock_valid_lfid()
     def update(self, new=None, case=None):
         return super(TestCaseBase, self).update(new, self.project, case)
 
+    @executor.mock_valid_lfid()
     def delete(self, case):
         return super(TestCaseBase, self).delete(self.project, case)
 
index dd116a0..56aaa6e 100644 (file)
@@ -14,9 +14,11 @@ module.exports = function (grunt) {
                                        base: './',
                                        middleware: function(connect, options, middlewares) {
                                                middlewares.unshift(function(req, res, next) {
-                                                       if (req.method.toUpperCase() == 'POST' || req.method.toUpperCase() == "PUT"){
-                                                               req.method='GET';
-                                                       }
+                                                       if (req.method.toUpperCase() == 'POST' || req.method.toUpperCase() == "PUT" ||
+                                                               req.method.toUpperCase() == "DELETE")
+                                                               {
+                                                                       req.method='GET';
+                                                               }
                                                        return next();
                                                });
                                                return middlewares;
@@ -113,9 +115,7 @@ module.exports = function (grunt) {
                        noColor: false,
                        coverageDir: '../tests/UI/coverage',
                        args: {
-                                       specs: ['../tests/UI/e2e/podsControllerSpec.js',
-                                                       '../tests/UI/e2e/projectsControllerSpec.js',
-                                                       '../tests/UI/e2e/projectControllerSpec.js']
+                                       specs: ['../tests/UI/e2e/testCasesControllerSpec.js']
                        }
                    },
                    local: {
index 8c85686..2a34838 100644 (file)
                 templateUrl: 'testapi-ui/components/projects/project/project.html',
                 controller: 'ProjectController as ctrl'
             }).
+            state('testCase', {
+                url: '/projects/:project_name/:name',
+                templateUrl: 'testapi-ui/components/projects/project/testCases/testCase/testCase.html',
+                controller: 'TestCaseController as ctrl'
+            }).
             state('results', {
                 url: '/results',
                 templateUrl: 'testapi-ui/components/results/results.html',
index 82dc0ec..2921bd9 100644 (file)
@@ -1,37 +1,49 @@
 <legend>Project</legend>
-<div style="padding-right:0px">
-    <div class="table-responsive">
-        <table class="table"  ng-data="ctrl.data.pods">
-            <tbody>
-                <tr style="padding:9px">
-                    <td class="podsTableTd">Id&nbsp;:</td>
-                    <td class="podsTableLeftTd">{{ctrl.data._id}}</td>
-                </tr>
-                <tr style="padding:9px">
-                    <td class="podsTableTd">Name&nbsp;:</td>
-                    <td width="90%" class="podsTableLeftTd">{{ctrl.data.name}}</td>
-                </tr>
-                <tr style="padding:9px">
-                    <td class="podsTableTd">Owner&nbsp;:</td>
-                    <td width="90%" class="podsTableLeftTd">{{ctrl.data.owner}}</td>
-                </tr>
-                <tr style="padding:9px">
-                    <td class="podsTableTd">Created&nbsp;at&nbsp;:</td>
-                    <td width="90%" class="podsTableLeftTd">{{ctrl.data['creation_date']}}</td>
-                </tr>
-                <tr style="padding:9px">
-                    <td class="podsTableTd">Description&nbsp;:</td>
-                    <td  width="90%" class="podsTableLeftTd">{{ctrl.data.description}}</td>
-                </tr>
-            </tbody>
-        </table>
-    </div>
-</div>
 <div class="row" style="margin-bottom:24px;"></div>
-<div class="project-create col-md-3" style="margin-top:10px" ng-class="{ 'hidden': ! ((auth.projectNames.length>0) &&
-    auth.isAuthenticated) }">
-        <button type="submit" class="btn btn-primary" ng-click="ctrl.openDeleteModal()">Delete Project</button>
-        <button type="submit" class="btn btn-primary" ng-click="ctrl.openUpdateModal()">Update Project</button>
+
+<div class="tabbable tabs-below" ng-init="selectedTab = 1;">
+    <ul class="nav nav-tabs nav-justified" style="width:30%">
+        <li ng-class="{active: selectedTab == 1}">
+            <a ng-click="selectedTab = 1;">Overview</a>
+        </li>
+        <li ng-class="{active: selectedTab == 2}">
+            <a ng-click="selectedTab = 2;">Test Cases</a>
+        </li>
+    </ul>
+
+    <div class="tab-content" ng-show="selectedTab == 1">
+            <div style="padding-right:0px; margin-top:20px" >
+                    <div class="table-responsive">
+                        <table class="table"  ng-data="ctrl.data.pods">
+                            <tbody>
+                                <tr style="padding:9px">
+                                    <td class="podsTableTd">Id&nbsp;:</td>
+                                    <td class="podsTableLeftTd">{{ctrl.data._id}}</td>
+                                </tr>
+                                <tr style="padding:9px">
+                                    <td class="podsTableTd">Name&nbsp;:</td>
+                                    <td width="90%" class="podsTableLeftTd">{{ctrl.data.name}}</td>
+                                </tr>
+                                <tr style="padding:9px">
+                                    <td class="podsTableTd">Owner&nbsp;:</td>
+                                    <td width="90%" class="podsTableLeftTd">{{ctrl.data.owner}}</td>
+                                </tr>
+                                <tr style="padding:9px">
+                                    <td class="podsTableTd">Created&nbsp;at&nbsp;:</td>
+                                    <td width="90%" class="podsTableLeftTd">{{ctrl.data['creation_date']}}</td>
+                                </tr>
+                                <tr style="padding:9px">
+                                    <td class="podsTableTd">Description&nbsp;:</td>
+                                    <td  width="90%" class="podsTableLeftTd">{{ctrl.data.description}}</td>
+                                </tr>
+                            </tbody>
+                        </table>
+                    </div>
+                </div>
+    </div>
+    <div class="tab-content" ng-show="selectedTab == 2">
+            <div ng-include src="'testapi-ui/components/projects/project/testCases/testCases.html'"></div>
+    </div>
 </div>
 <div ng-show="ctrl.showError" class="alert alert-danger col-md-9" role="alert" style="margin-top:0px">
         <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
@@ -41,4 +53,4 @@
 <div ng-show="ctrl.showSuccess" class="alert alert-success col-md-9" role="alert" style="margin-top:0px">
     <span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
     Update Success
-</div>
\ No newline at end of file
+</div>
index e8d7bd6..78b805d 100644 (file)
         ctrl.url = testapiApiUrl + '/projects/' + ctrl.name;
 
         ctrl.loadDetails = loadDetails;
-        ctrl.deleteProject = deleteProject;
-        ctrl.openDeleteModal = openDeleteModal;
-        ctrl.openUpdateModal = openUpdateModal;
-        ctrl.updateProject = updateProject;
-
-        /**
-         * This will contact the TestAPI to update an existing project.
-         */
-        function updateProject(name,project) {
-            ctrl.showError = false;
-            ctrl.showSuccess = false;
-            var projects_url = ctrl.url;
-            var body = {
-                name: project.name,
-                description: project.description
-            };
-            ctrl.projectsRequest =
-                $http.put(projects_url, body).success(function (data){
-                    ctrl.showSuccess = true ;
-                    ctrl.name = body.name;
-                    $state.go('project', {'name':ctrl.name}, {reload: true});
-                })
-                .catch(function (error) {
-                    ctrl.showError = true;
-                    ctrl.error = error.statusText
-                });
-
-
-        }
-
-        /**
-         * This will contact the TestAPI to delete an existing project.
-        */
-        function deleteProject() {
-            ctrl.showError = false;
-            ctrl.showSuccess = false;
-            ctrl.projectsRequest =
-            $http.delete(ctrl.url).success(function (data) {
-                $state.go('projects', {'name':ctrl.name}, {reload: true});
-                ctrl.showSuccess = true ;
-            }).catch(function (error) {
-                ctrl.showError = true;
-                ctrl.error = error.statusText
-            });
-        }
-
-        /**
-         * This will open the modal that will show the delete confirm
-         * message
-         */
-        function openDeleteModal() {
-            confirmModal("Delete",ctrl.deleteProject);
-        }
-
-        /**
-         * This will open the modal that will show the update
-         * view
-         */
-        function openUpdateModal(){
-                $uibModal.open({
-                    templateUrl: 'testapi-ui/components/projects/modals/projectModal.html',
-                    controller: 'ProjectModalCtrl as ProjectModalCtrl',
-                    size: 'md',
-                    resolve: {
-                        data: function () {
-                            return {
-                                text: "Update Project",
-                                successHandler: ctrl.updateProject,
-                                project : ctrl.data
-                            };
-                        }
-                    }
-                });
-        }
 
         /**
          * This will contact the TestAPI to get a listing of declared projects.
diff --git a/testapi/opnfv_testapi/ui/components/projects/project/testCases/modals/testCaseModal.html b/testapi/opnfv_testapi/ui/components/projects/project/testCases/modals/testCaseModal.html
new file mode 100644 (file)
index 0000000..d1c9cb5
--- /dev/null
@@ -0,0 +1,39 @@
+<div class="ball" style="padding:5px;">
+    <div class="modal-body">
+        <div class="form-horizontal">
+            <fieldset>
+                <div class="form-group">
+                    <legend>{{TestCaseModalCtrl.data.text}}</legend>
+                    <div class="row">
+                        <div ng-repeat="require in TestCaseModalCtrl.createRequirements" style="margin-left:15px">
+                            <div class="update-project">
+                                <label for="cpid" class="control-label col-sm-3">{{require.label.replace("_","&nbsp;")|capitalize}}: </label>
+                                <div class="col-sm-8">
+                                    <a ng-if="require.type == 'select'">
+                                            <select class="form-control" dynamic-model="'TestCaseModalCtrl.testcase.' + require.label" ng-options="option for option in require.selects"></select>
+                                    </a>
+                                    <a ng-if="require.type == 'text'">
+                                        <input type="text" class="form-control" dynamic-model="'TestCaseModalCtrl.testcase.' + require.label"/>
+                                    </a>
+                                    <a ng-if="require.type == 'textarea'">
+                                        <textarea rows="2" class="form-control" cols="50" dynamic-model="'TestCaseModalCtrl.testcase.' + require.label">
+                                        </textarea>
+                                    </a>
+                                    <p class="help-block"></p>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </fieldset>
+        </div>
+    </div>
+    <div class="modal-footer">
+        <div ng-show="TestCaseModalCtrl.showCreateError" style="padding:0px;" class="col-md-6 alert alert-danger" role="alert">
+                <span class="pull-right">&nbsp;{{TestCaseModalCtrl.error}}</span>
+                <span class="glyphicon glyphicon-exclamation-sign pull-right" aria-hidden="true" >Error:</span>
+        </div>
+        <button class="btn btn-primary" ng-click="TestCaseModalCtrl.confirm()">Ok</button>
+        <button class="btn btn-default" ng-click="TestCaseModalCtrl.cancel()">Cancel</button>
+    </div>
+</div>
\ No newline at end of file
diff --git a/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCase/testCase.html b/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCase/testCase.html
new file mode 100644 (file)
index 0000000..70c026a
--- /dev/null
@@ -0,0 +1,80 @@
+<legend>Test Case</legend>
+<div style="padding-right:0px">
+    <div class="table-responsive">
+        <table class="table"  ng-data="ctrl.data">
+            <tbody>
+                <tr style="padding:9px">
+                    <td class="podsTableTd">Id&nbsp;:</td>
+                    <td class="podsTableLeftTd">{{ctrl.data._id}}</td>
+                </tr>
+                <tr style="padding:9px">
+                    <td class="podsTableTd">Name&nbsp;:</td>
+                    <td width="90%" class="podsTableLeftTd">{{ctrl.data.name}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Project&nbsp;:</td>
+                        <td width="90%" class="podsTableLeftTd">{{ctrl.data.project_name}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Tier&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.tier}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Blocking&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.blocking}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">CI&nbsp;Loop&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.ci_loop}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Tags&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.tags}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Version&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.version}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Created&nbsp;at&nbsp;:</td>
+                        <td width="90%" class="podsTableLeftTd">{{ctrl.data['creation_date']}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Dependencies&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.dependencies}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Trust&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.trust}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Criteria&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.criteria}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Catalog&nbsp;Description&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.catalog_description}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">URL&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.url}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Run&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.run}}</td>
+                </tr>
+                <tr style="padding:9px">
+                        <td class="podsTableTd">Description&nbsp;:</td>
+                        <td  width="90%" class="podsTableLeftTd">{{ctrl.data.description}}</td>
+                </tr>
+            </tbody>
+        </table>
+    </div>
+</div>
+<div class="row" style="margin-bottom:24px;"></div>
+<div ng-show="ctrl.showError"  class="alert alert-danger col-md-8" role="alert" style="margin-top:0px">
+        <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
+        <span class="sr-only">Error:</span>
+        {{ctrl.error}}
+</div>
+<div class="row" style="margin-bottom:24px;"></div>
\ No newline at end of file
diff --git a/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCase/testCaseController.js b/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCase/testCaseController.js
new file mode 100644 (file)
index 0000000..a38b633
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    angular
+        .module('testapiApp')
+        .controller('TestCaseController', TestCaseController);
+
+        TestCaseController.$inject = [
+        '$scope', '$http', '$filter', '$state', '$window', '$uibModal', 'testapiApiUrl','raiseAlert',
+        'confirmModal'
+    ];
+
+    /**
+     * TestAPI Project Controller
+     * This controller is for the '/projects' page where a user can browse
+     * through projects declared in TestAPI.
+     */
+    function TestCaseController($scope, $http, $filter, $state, $window, $uibModal, testapiApiUrl,
+        raiseAlert, confirmModal) {
+        var ctrl = this;
+        ctrl.name = $state.params['name'];
+        ctrl.projectName = $state.params['project_name'];
+        ctrl.url = testapiApiUrl + '/projects/' + ctrl.projectName + "/cases/" + ctrl.name;
+
+        ctrl.loadDetails = loadDetails;
+
+        /**
+         * This will contact the TestAPI to get a listing of declared projects.
+         */
+        function loadDetails() {
+            ctrl.showError = false;
+            ctrl.projectsRequest =
+                $http.get(ctrl.url).success(function (data) {
+                    ctrl.data = data;
+                }).catch(function (error) {
+                    ctrl.data = null;
+                    ctrl.showError = true;
+                    ctrl.error = error.statusText
+                });
+        }
+        ctrl.loadDetails();
+    }
+})();
diff --git a/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCases.html b/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCases.html
new file mode 100644 (file)
index 0000000..34656f3
--- /dev/null
@@ -0,0 +1,71 @@
+<div ng-controller="TestCasesController as testCasesCtrl" class="col-md-12">
+<div class="row podsTable" style="vertical-align:middle">
+    <div class="col-sm-1 pull-right" ng-class="{ 'hidden': ! ((auth.projectNames.length>0) &&
+        auth.isAuthenticated) }" >
+            <button type="button" class="btn btn-danger" ng-click="testCasesCtrl.openBatchDeleteModal()">
+              <i class="fa fa-minus"></i> Delete</button>
+    </div>
+    <div class="col-sm-1 pull-right"  ng-class="{ 'hidden': ! ((auth.projectNames.length>0) &&
+        auth.isAuthenticated) }">
+        <button type="button" class="btn btn-success" ng-click="testCasesCtrl.openCreateModal()">
+          <i class="fa fa-plus"></i> Create</button>
+    </div>
+</div>
+<div class='clo-md-12'>
+    <div ng-show="testCasesCtrl.showError" class="alert alert-danger" role="alert">
+        <span class="pull-right">&nbsp;{{testCasesCtrl.error}}</span>
+        <span class="glyphicon glyphicon-exclamation-sign pull-right" aria-hidden="true" >Error:</span>
+    </div>
+    <div ng-show="testCasesCtrl.showSuccess" class="alert alert-success" role="alert">
+        <span class="pull-right">&nbsp;{{testCasesCtrl.successMessage}}</span>
+        <span class="glyphicon glyphicon-ok pull-right" aria-hidden="true"></span>
+    </div>
+</div>
+<div class='clo-md-12' style="padding-right:0px">
+    <div class="table-responsive">
+        <table class="table table-bordered table-hover"  ng-data="testCasesCtrl.data.testcases">
+        <thead>
+        <tr style="
+        text-align: center;">
+            <th style="width: 1%;">Bulk Select</th>
+            <th style="width: 19%;">Name</th>
+            <th style="width: 20%;">Tier</th>
+            <th style="width: 20%;">Blocking</th>
+            <th style="width: 20%;">CI&nbsp;Loop</th>
+            <th style="width: 20%;">Operations</th>
+        </tr>
+        </thead>
+        <tbody>
+        <tr ng-repeat-start="(index, testcase) in testCasesCtrl.data.testcases" style="padding:9px">
+            <td>
+            <div class="text-center">
+                    <input type="checkbox" value="{{project.name}}"  ng-model="testCasesCtrl.checkBox[index]" >
+                </div>
+            </td>
+            <td>
+                <a class="text-info" ng-click="testCasesCtrl.viewTestCase(testcase.name, testcase.project_name)">
+                    {{testcase.name}}
+                </a>
+            </td>
+            <td>{{ ctrl.data.tier}}</td>
+            <td>{{ctrl.data.blocking}}</td>
+            <td>{{ctrl.data.ci_loop}}</td>
+            <td>
+                <span class="podsTable-col">
+                    <a class="text-warning" ng-click="testCasesCtrl.openUpdateTestModal(testcase.name)" title="Edit" ng-class="{'hidden': ! ((auth.projectNames.length>0) &&
+                        auth.isAuthenticated)}" >
+                        <i class="fa fa-pencil-square-o"></i></a>
+                    <a class="text-danger"  ng-click="testCasesCtrl.openDeleteTestModal(testcase.name)" title="Delete" ng-class="{'hidden': ! ((auth.projectNames.length>0) &&
+                        auth.isAuthenticated)}">
+                        <i class="fa fa-trash-o"></i></a>
+                    <a class="text-info" ng-click="testCasesCtrl.viewTestCase(testcase.name, testcase.project_name)"><i class="fa fa-eye"></i></a>
+                </span>
+            </td>
+        </tr>
+        <tr ng-repeat-end=>
+        </tr>
+        </tbody>
+        </table>
+    </div>
+</div>
+</div>
diff --git a/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCasesController.js b/testapi/opnfv_testapi/ui/components/projects/project/testCases/testCasesController.js
new file mode 100644 (file)
index 0000000..0045284
--- /dev/null
@@ -0,0 +1,278 @@
+/*
+ * 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.
+ */
+
+(function () {
+    'use strict';
+
+    angular
+        .module('testapiApp')
+        .controller('TestCasesController', TestCasesController);
+
+        TestCasesController.$inject = [
+        '$scope', '$http', '$filter', '$state', '$window', '$uibModal', 'testapiApiUrl','raiseAlert',
+        'confirmModal'
+    ];
+
+    /**
+     * TestAPI Test cases Controller
+     * This controller is for the tescases page where a user can browse
+     * through testcases declared in TestAPI and perform the CRUD operations
+     * in them.
+     */
+    function TestCasesController($scope, $http, $filter, $state, $window, $uibModal, testapiApiUrl,
+        raiseAlert, confirmModal) {
+        var ctrl = this;
+        ctrl.loadDetails = loadDetails;
+        ctrl.name = $state.params['name'];
+        ctrl.requestUrl = testapiApiUrl + '/projects/' + ctrl.name +'/cases';
+
+        ctrl.createTestCase = createTestCase;
+        ctrl.openCreateModal = openCreateModal;
+        ctrl.deleteTestCase = deleteTestCase;
+        ctrl.openDeleteTestModal = openDeleteTestModal;
+        ctrl.updateTestCase = updateTestCase;
+        ctrl.openUpdateTestModal = openUpdateTestModal;
+        ctrl.batchDelete = batchDelete;
+        ctrl.openBatchDeleteModal = openBatchDeleteModal;
+        ctrl.viewTestCase = viewTestCase;
+
+        ctrl.checkBox = [];
+        ctrl.checkBoxList = [];
+
+        /**
+         * This will contact the TestAPI to create a new test case.
+         */
+        function createTestCase(name, testcase) {
+            ctrl.showError = false;
+            ctrl.showSuccess = false;
+            if(testcase.name != "" && testcase.name!=null){
+                var testCase_url = ctrl.requestUrl;
+                ctrl.testCasesRequest =
+                    $http.post(testCase_url, testcase).success(function (data){
+                        ctrl.showSuccess = true ;
+                        ctrl.successMessage = "Testcase is successfully created."
+                        loadDetails();
+                    })
+                    .catch(function (data) {
+                        ctrl.showError = true;
+                        ctrl.error = data.statusText;
+                    });
+            }
+            else{
+                ctrl.showError = true;
+                ctrl.error = 'Name is missing.'
+            }
+        }
+
+        function viewTestCase(name, project_name){
+            $state.go('testCase', {'name':name, 'project_name':project_name}, {reload: true});
+        }
+
+        /**
+         * This will open the modal that will show the batch delete confirm
+         * message
+         */
+        function openBatchDeleteModal() {
+            confirmModal("Delete",ctrl.batchDelete);
+        }
+
+        /**
+         * This will  delete list of test cases.
+         */
+        function batchDelete(){
+            var index;
+            var checkedBox = [];
+            ctrl.checkBox.forEach(function(testcase, index){
+                if(!ctrl.showError){
+                    if(testcase){
+                        ctrl.deleteTestCase(ctrl.data.testcases[index].name);
+                    }
+                }
+              });
+            ctrl.checkBox = []
+        }
+        /**
+         * This will contact the TestAPI to update an existing test case.
+         */
+        function updateTestCase(name, testCase) {
+            ctrl.showError = false;
+            ctrl.showSuccess = false;
+            if(testCase.name != ""){
+                var testCase_url = ctrl.requestUrl + '/' + name;
+                ctrl.testCasesRequest =
+                    $http.put(testCase_url, testCase).success(function (data){
+                        ctrl.showSuccess = true ;
+                        ctrl.successMessage = "Test case is successfully updated"
+                        loadDetails();
+                    })
+                    .catch(function (data) {
+                        ctrl.showError = true;
+                        ctrl.error = data.statusText;
+                    });
+            }
+            else{
+                ctrl.showError = true;
+                ctrl.error = 'Name is missing.'
+            }
+        }
+
+        /**
+         * This will contact the TestAPI to delete an existing test case.
+        */
+        function deleteTestCase(name) {
+            ctrl.showError = false;
+            ctrl.showSuccess = false;
+            ctrl.testCasesRequest =
+            $http.delete(ctrl.requestUrl+"/"+name).success(function (data) {
+                loadDetails();
+                ctrl.showSuccess = true ;
+                ctrl.successMessage = "Test case is successfully deleted"
+            }).catch(function (error) {
+                ctrl.showError = true;
+                ctrl.error = data.statusText;
+            });
+        }
+
+        /**
+         * This will open the modal that will show the delete confirm
+         * message
+         */
+        function openDeleteTestModal(name) {
+            confirmModal("Delete", ctrl.deleteTestCase, name);
+        }
+
+        /**
+         * This will open the modal that will show the Create
+         * view
+         */
+        function openCreateModal(name){
+                $uibModal.open({
+                    templateUrl: 'testapi-ui/components/projects/project/testCases/modals/testCaseModal.html',
+                    controller: 'TestCaseModalCtrl as TestCaseModalCtrl',
+                    size: 'md',
+                    resolve: {
+                        data: function () {
+                            return {
+                                text: "Create",
+                                successHandler: ctrl.createTestCase
+                            };
+                        }
+                    }
+                });
+        }
+
+        /**
+         * This will open the modal that will show the update
+         * view
+         */
+        function openUpdateTestModal(name){
+            var testcase;
+            var index;
+            for(index in ctrl.data.testcases){
+                if(ctrl.data.testcases[index].name==name){
+                    testcase = ctrl.data.testcases[index]
+                    continue
+                }
+            }
+            $uibModal.open({
+                templateUrl: 'testapi-ui/components/projects/project/testCases/modals/testCaseModal.html',
+                controller: 'TestCaseModalCtrl as TestCaseModalCtrl',
+                size: 'md',
+                resolve: {
+                    data: function () {
+                        return {
+                            text: "Update",
+                            successHandler: ctrl.updateTestCase,
+                            testCase: testcase
+                        };
+                    }
+                }
+            });
+        }
+
+        /**
+         * This will contact the TestAPI to get a listing of declared test cases.
+         */
+        function loadDetails() {
+            ctrl.testCasesReguest =
+                $http.get(ctrl.requestUrl).success(function (data) {
+                    ctrl.data = data;
+                }).catch(function (error) {
+                    ctrl.data = null;
+                    ctrl.showError = true;
+                    ctrl.error = error.statusText;
+                });
+        }
+        ctrl.loadDetails();
+    }
+
+
+    /**
+     * TestAPI Modal instance Controller
+     * This controller is for the modal where a user can create
+     * test case or update the test case information.
+     */
+    angular.module('testapiApp').controller('TestCaseModalCtrl', TestCaseModalCtrl);
+    TestCaseModalCtrl.$inject = ['$scope', '$uibModalInstance', 'data'];
+    function TestCaseModalCtrl($scope, $uibModalInstance, data) {
+        var ctrl = this;
+        ctrl.confirm = confirm;
+        ctrl.cancel = cancel;
+        ctrl.data = angular.copy(data);
+
+        ctrl.createRequirements = [
+            {label: 'name', type: 'text', required: true},
+            {label: 'description', type: 'textarea', required: false},
+            {label: 'version', type: 'text', required: false},
+            {label: 'tier', type: 'text', required: false},
+            {label: 'tags', type: 'text', required: false},
+            {label: 'run', type: 'text', required: false},
+            {label: 'dependencies', type: 'text', required: false},
+            {label: 'trust', type: 'text', required: false},
+            {label: 'url', type: 'text', required: false},
+            {label: 'blocking', type: 'text', required: false},
+            {label: 'criteria', type: 'text', required: false},
+            {label: 'domains', type: 'text', required: false},
+            {label: 'catalog_description', type: 'text', required: false}
+        ];
+
+        ctrl.testcase = {name : null, description : null,version : null, tier : null, tags : null,
+                     run : null, dependencies : null, trust : null, url : null, blocking : null,
+                 criteria : null, domains : null, catalog_description : null};
+
+        if(ctrl.data.text=="Update"){
+            ctrl.testcase = ctrl.data.testCase
+            delete ctrl.testcase._id;
+            ctrl.name = ctrl.data.testCase.name
+        }
+
+        /**
+         * Initiate confirmation and call the success handler with the
+         * inputs.
+         */
+        function confirm() {
+            $uibModalInstance.close();
+            if (angular.isDefined(ctrl.data.successHandler)) {
+                ctrl.data.successHandler(ctrl.name, ctrl.testcase);
+            }
+        }
+
+        /**
+         * Close the confirm modal without initiating changes.
+         */
+        function cancel() {
+            $uibModalInstance.dismiss('cancel');
+        }
+    }
+})();
index 3191858..98f1ed8 100644 (file)
@@ -51,6 +51,8 @@
         <script src="testapi-ui/components/profile/profileController.js"></script>
         <script src="testapi-ui/components/auth-failure/authFailureController.js"></script>
         <script src="testapi-ui/components/logout/logoutController.js"></script>
+        <script src="testapi-ui/components/projects/project/testCases/testCasesController.js"></script>
+        <script src="testapi-ui/components/projects/project/testCases/testCase/testCaseController.js"></script>
 
         <!-- Filters -->
         <script src="testapi-ui/shared/filters.js"></script>