Add testcases CRUD in testapiclient 71/53471/4
authorthuva4 <tharma.thuva@gmail.com>
Fri, 16 Mar 2018 05:21:29 +0000 (10:51 +0530)
committerSerenaFeng <feng.xiaowei@zte.com.cn>
Wed, 21 Mar 2018 08:55:06 +0000 (16:55 +0800)
implement interface to do CRUD operations
for testcases in testapiclient + tests

Change-Id: I59a810b6ba496d672fdf04be465ca5581dc58a3f
Signed-off-by: thuva4 <tharma.thuva@gmail.com>
testapi/testapi-client/setup.cfg
testapi/testapi-client/testapiclient/cli/testcases.py [new file with mode: 0644]
testapi/testapi-client/testapiclient/tests/unit/test_testcases.py [new file with mode: 0644]
testapi/testapi-client/testapiclient/utils/urlparse.py

index a0d5e0d..f085f59 100644 (file)
@@ -26,12 +26,17 @@ testapi =
     project delete = testapiclient.cli.projects:ProjectDelete
     project put = testapiclient.cli.projects:ProjectPut
 
+    testcase create = testapiclient.cli.testcases:TestcaseCreate
+    testcase get = testapiclient.cli.testcases:TestcaseGet
+    testcase getone = testapiclient.cli.testcases:TestcaseGetOne
+    testcase delete = testapiclient.cli.testcases:TestcaseDelete
+    testcase put = testapiclient.cli.testcases:TestcasePut
+
     scenario create = testapiclient.cli.scenarios:ScenarioCreate
     scenario get = testapiclient.cli.scenarios:ScenarioGet
     scenario getone = testapiclient.cli.scenarios:ScenarioGetOne
     scenario delete = testapiclient.cli.scenarios:ScenarioDelete
     scenario put = testapiclient.cli.scenarios:ScenarioPut
-
 [egg_info]
 tag_build =
 tag_date = 0
diff --git a/testapi/testapi-client/testapiclient/cli/testcases.py b/testapi/testapi-client/testapiclient/cli/testcases.py
new file mode 100644 (file)
index 0000000..6c97edb
--- /dev/null
@@ -0,0 +1,119 @@
+import json
+
+from testapiclient.utils import command
+from testapiclient.utils import urlparse
+
+
+def testcases_url(name):
+    return urlparse.resource_join('projects', name, 'cases')
+
+
+def testcase_url(parsed_args):
+    return urlparse.path_join(
+        testcases_url(parsed_args.project_name), parsed_args.name)
+
+
+class TestcaseGet(command.Lister):
+
+    def get_parser(self, prog_name):
+        parser = super(TestcaseGet, self).get_parser(prog_name)
+        parser.add_argument('--project-name',
+                            required=True,
+                            help='Search testcases by project name')
+        return parser
+
+    def take_action(self, parsed_args):
+        columns = (
+            'name',
+            '_id',
+            'creator',
+            'creation_date'
+        )
+        data = self.app.client_manager.get(
+            testcases_url(parsed_args.project_name))
+        return self.format_output(columns, data.get('testcases', []))
+
+
+class TestcaseGetOne(command.ShowOne):
+
+    def get_parser(self, prog_name):
+        parser = super(TestcaseGetOne, self).get_parser(prog_name)
+        parser.add_argument('--project-name',
+                            required=True,
+                            help='Search testcase by project name')
+        parser.add_argument('name',
+                            help='Search testcase by name')
+        return parser
+
+    def take_action(self, parsed_args):
+        return self.format_output(
+            self.app.client_manager.get(testcase_url(parsed_args)))
+
+
+class TestcaseCreate(command.ShowOne):
+
+    def get_parser(self, prog_name):
+        parser = super(TestcaseCreate, self).get_parser(prog_name)
+        parser.add_argument('--project-name',
+                            required=True,
+                            help='Create testcase under project name')
+        parser.add_argument('testcase',
+                            type=json.loads,
+                            help='Testcase create request format:\n'
+                                 '\'{"run": "", "name": "", "ci_loop": "",'
+                                 '"tags": "",\n "url": "", "blocking": "",'
+                                 '"domains": "", "dependencies": "",\n '
+                                 '"version": "", "criteria": "", "tier": "",'
+                                 '"trust": "",\n "catalog_description": "",'
+                                 '"description": ""}\'')
+        return parser
+
+    def take_action(self, parsed_args):
+        return self.format_output(
+            self.app.client_manager.post(
+                testcases_url(parsed_args.project_name), parsed_args.testcase))
+
+
+class TestcaseDelete(command.Command):
+
+    def get_parser(self, prog_name):
+        parser = super(TestcaseDelete, self).get_parser(prog_name)
+        parser.add_argument('--project-name',
+                            required=True,
+                            type=str,
+                            help='Delete testcase by project name')
+        parser.add_argument('name',
+                            type=str,
+                            help='Delete testcase by name')
+        return parser
+
+    def take_action(self, parsed_args):
+        return self.app.client_manager.delete(testcase_url(parsed_args))
+
+
+class TestcasePut(command.ShowOne):
+
+    def get_parser(self, prog_name):
+        parser = super(TestcasePut, self).get_parser(prog_name)
+        parser.add_argument('--project-name',
+                            type=str,
+                            required=True,
+                            help='Update testcase by project name')
+        parser.add_argument('name',
+                            type=str,
+                            help='Update testcase by name')
+        parser.add_argument('testcase',
+                            type=json.loads,
+                            help='Testcase Update request format:\n'
+                                 '\'{"run": "", "name": "", "ci_loop": "",'
+                                 '"tags": "",\n "url": "", "blocking": "",'
+                                 '"domains": "", "dependencies": "",\n '
+                                 '"version": "", "criteria": "", "tier": "",'
+                                 '"trust": "",\n "catalog_description": "",'
+                                 '"description": ""}\'')
+        return parser
+
+    def take_action(self, parsed_args):
+        return self.format_output(
+            self.app.client_manager.put(
+                testcase_url(parsed_args), parsed_args.testcase))
diff --git a/testapi/testapi-client/testapiclient/tests/unit/test_testcases.py b/testapi/testapi-client/testapiclient/tests/unit/test_testcases.py
new file mode 100644 (file)
index 0000000..6fd2120
--- /dev/null
@@ -0,0 +1,155 @@
+import json
+
+from mock import mock
+from six.moves.urllib import parse
+import testtools
+
+from testapiclient.cli import testcases
+from testapiclient.tests.unit import fakes
+from testapiclient.tests.unit import utils
+from testapiclient.utils import clientmanager
+
+
+class TestcaseTest(utils.TestCommand):
+    def setUp(self):
+        super(TestcaseTest, self).setUp()
+        self.base_url = parse.urljoin(self.api_url, 'projects/{}/cases')
+        self.project_name = 'functest'
+        self.testcase_json = {
+            'run': '',
+            'name': 'test-case',
+            'ci_loop': '',
+            'tags': '',
+            'url': '',
+            'blocking': '',
+            'domains': '',
+            'dependencies': '',
+            'version': '',
+            'criteria': '',
+            'tier': '',
+            'trust': '',
+            'catalog_description': '',
+            'description': ''
+        }
+        self.testcase_string = json.dumps(self.testcase_json)
+
+
+class TestcaseGetTest(TestcaseTest):
+
+    def setUp(self):
+        super(TestcaseGetTest, self).setUp()
+        self.testcases_rsp = {'testcases': [self.testcase_json]}
+
+    def test_get(self):
+        self.get_mock.return_value = fakes.FakeResponse(
+            data=self.testcases_rsp)
+        testcase_get = testcases.TestcaseGet(self.app, mock.Mock())
+        args = ['--project-name', 'dfs']
+        verifies = [('project_name', 'dfs')]
+        parsed_args = self.check_parser(testcase_get, args, verifies)
+        testcase_get.take_action(parsed_args)
+        self.get_mock.assert_called_once_with(
+            self.base_url.format(parsed_args.project_name),
+            headers=clientmanager.ClientManager.headers)
+
+    def test_get_one(self):
+        self.get_mock.return_value = fakes.FakeResponse(
+            data=self.testcase_json)
+        testcase_get_one = testcases.TestcaseGetOne(self.app, mock.Mock())
+        args = ['--project-name', 'functest', 'def']
+        verifies = [('project_name', 'functest'), ('name', 'def')]
+        parsed_args = self.check_parser(testcase_get_one, args, verifies)
+        testcase_get_one.take_action(parsed_args)
+        self.get_mock.assert_called_once_with(
+            self.base_url.format(parsed_args.project_name) + '/def',
+            headers=clientmanager.ClientManager.headers)
+
+
+class TestcaseCreateTest(TestcaseTest):
+
+    def setUp(self):
+        super(TestcaseCreateTest, self).setUp()
+
+    def test_create_success(self):
+        succ_rsp = {
+            'href': '{}/{}'.format(self.base_url.format(self.project_name),
+                                   self.testcase_json.get('name'))
+        }
+        self.post_mock.return_value = fakes.FakeResponse(data=succ_rsp)
+        testcase_create = testcases.TestcaseCreate(self.app, mock.Mock())
+        args = ['--project-name', 'functest', self.testcase_string]
+        verifies = [
+            ('project_name', 'functest'),
+            ('testcase', self.testcase_json)]
+        parsed_args = self.check_parser(testcase_create, args, verifies)
+        testcase_create.take_action(parsed_args)
+        self.post_mock.assert_called_once()
+
+    def test_create_failure(self):
+        with testtools.ExpectedException(Exception, 'Create failed: Error'):
+            self.post_mock.return_value = utils.FAKE_FAILURE
+            testcase_create = testcases.TestcaseCreate(self.app, mock.Mock())
+            args = ['--project-name', 'functest', self.testcase_string]
+            verifies = [
+                ('project_name', 'functest'),
+                ('testcase', self.testcase_json)]
+            parsed_args = self.check_parser(testcase_create, args, verifies)
+            testcase_create.take_action(parsed_args)
+
+
+class TestcaseDeleteTest(TestcaseTest):
+
+    def setUp(self):
+        super(TestcaseDeleteTest, self).setUp()
+
+    def test_delete_success(self):
+        self.delete_mock.return_value = fakes.FakeResponse()
+        testcase_delete = testcases.TestcaseDelete(self.app, mock.Mock())
+        args = ['--project-name', 'functest', 'def']
+        verifies = [('project_name', 'functest'), ('name', 'def')]
+        parsed_args = self.check_parser(testcase_delete, args, verifies)
+        testcase_delete.take_action(parsed_args)
+        self.delete_mock.assert_called_once_with(
+            self.base_url.format(parsed_args.project_name) + '/def',
+            data=None,
+            headers=clientmanager.ClientManager.headers)
+
+    def test_delete_failure(self):
+        with testtools.ExpectedException(Exception, 'Delete failed: Error'):
+            self.delete_mock.return_value = utils.FAKE_FAILURE
+            testcase_delete = testcases.TestcaseDelete(self.app, mock.Mock())
+            args = ['--project-name', 'functest', 'def']
+            verifies = [('project_name', 'functest'), ('name', 'def')]
+            parsed_args = self.check_parser(testcase_delete, args, verifies)
+            testcase_delete.take_action(parsed_args)
+
+
+class TestcasePutTest(TestcaseTest):
+
+    def setUp(self):
+        super(TestcasePutTest, self).setUp()
+
+    def test_put_success(self):
+        self.put_mock.return_value = fakes.FakeResponse(
+            data=self.testcase_json)
+        testcase_put = testcases.TestcasePut(self.app, mock.Mock())
+        args = ['--project-name', 'functest', 'def', self.testcase_string]
+        verifies = [
+            ('project_name', 'functest'),
+            ('name', 'def'),
+            ('testcase', self.testcase_json)]
+        parsed_args = self.check_parser(testcase_put, args, verifies)
+        testcase_put.take_action(parsed_args)
+        self.put_mock.assert_called_once()
+
+    def test_put_failure(self):
+        with testtools.ExpectedException(Exception, 'Update failed: Error'):
+            self.put_mock.return_value = utils.FAKE_FAILURE
+            testcase_put = testcases.TestcasePut(self.app, mock.Mock())
+            args = ['--project-name', 'functest', 'def', self.testcase_string]
+            verifies = [
+                ('project_name', 'functest'),
+                ('name', 'def'),
+                ('testcase', self.testcase_json)]
+            parsed_args = self.check_parser(testcase_put, args, verifies)
+            testcase_put.take_action(parsed_args)
index 9f99a46..47d40d5 100644 (file)
@@ -17,9 +17,9 @@ def query_join(base, **queries):
     return base + '?' + parse.urlencode(queries)
 
 
-def resource_join(url):
+def resource_join(*url):
     testapi_url = os.environ.get('testapi_url')
-    return path_join(testapi_url, url)
+    return path_join(testapi_url, *url)
 
 
 def get_queries(queries, parsed_args):