From 4679a4c1933da0b94efb5d3d453d119801289a97 Mon Sep 17 00:00:00 2001
From: Rui Chen <chenrui.momo@gmail.com>
Date: Thu, 9 Feb 2017 17:25:36 +0800
Subject: [PATCH] Fix --parents and --children options in project show

Options "--parents" and "--children" don't work in "project show"
command, fix the issue and add related unit and functional tests.

Change-Id: Id9965267a037442f1077f8e1929d0527981f643d
Closes-Bug: #1499657
---
 openstackclient/identity/v3/project.py        | 13 ++++--
 .../functional/identity/v3/test_project.py    | 13 ++++++
 .../tests/unit/identity/v3/test_project.py    | 46 ++++++++-----------
 .../notes/bug-1499657-eeb260849febacf3.yaml   |  6 +++
 4 files changed, 46 insertions(+), 32 deletions(-)
 create mode 100644 releasenotes/notes/bug-1499657-eeb260849febacf3.yaml

diff --git a/openstackclient/identity/v3/project.py b/openstackclient/identity/v3/project.py
index 12197cdde1..43eca2b525 100644
--- a/openstackclient/identity/v3/project.py
+++ b/openstackclient/identity/v3/project.py
@@ -336,13 +336,18 @@ class ShowProject(command.ShowOne):
             project = utils.find_resource(
                 identity_client.projects,
                 project_str,
-                domain_id=domain.id,
-                parents_as_list=parsed_args.parents,
-                subtree_as_list=parsed_args.children)
+                domain_id=domain.id)
         else:
             project = utils.find_resource(
                 identity_client.projects,
-                project_str,
+                project_str)
+
+        if parsed_args.parents or parsed_args.children:
+            # NOTE(RuiChen): utils.find_resource() can't pass kwargs,
+            #                if id query hit the result at first, so call
+            #                identity manager.get() with kwargs directly.
+            project = identity_client.projects.get(
+                project.id,
                 parents_as_list=parsed_args.parents,
                 subtree_as_list=parsed_args.children)
 
diff --git a/openstackclient/tests/functional/identity/v3/test_project.py b/openstackclient/tests/functional/identity/v3/test_project.py
index 5639dc167c..96d41c3a14 100644
--- a/openstackclient/tests/functional/identity/v3/test_project.py
+++ b/openstackclient/tests/functional/identity/v3/test_project.py
@@ -10,6 +10,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import json
+
 from tempest.lib.common.utils import data_utils
 
 from openstackclient.tests.functional.identity.v3 import common
@@ -111,3 +113,14 @@ class ProjectTests(common.IdentityTests):
                           'name': self.project_name})
         items = self.parse_show(raw_output)
         self.assert_show_fields(items, self.PROJECT_FIELDS)
+
+    def test_project_show_with_parents_children(self):
+        json_output = json.loads(self.openstack(
+            'project show '
+            '--parents --children -f json '
+            '--domain %(domain)s '
+            '%(name)s' % {'domain': self.domain_name,
+                          'name': self.project_name}))
+        for attr_name in (self.PROJECT_FIELDS + ['parents', 'subtree']):
+            self.assertIn(attr_name, json_output)
+        self.assertEqual(self.project_name, json_output.get('name'))
diff --git a/openstackclient/tests/unit/identity/v3/test_project.py b/openstackclient/tests/unit/identity/v3/test_project.py
index 2b89809004..b99eaf8506 100644
--- a/openstackclient/tests/unit/identity/v3/test_project.py
+++ b/openstackclient/tests/unit/identity/v3/test_project.py
@@ -14,6 +14,7 @@
 #
 
 import mock
+from mock import call
 
 from osc_lib import exceptions
 from osc_lib import utils
@@ -763,8 +764,6 @@ class TestProjectShow(TestProject):
 
     def test_project_show(self):
 
-        self.projects_mock.get.side_effect = [Exception("Not found"),
-                                              self.project]
         self.projects_mock.get.return_value = self.project
 
         arglist = [
@@ -790,11 +789,7 @@ class TestProjectShow(TestProject):
         # data to be shown.
         columns, data = self.cmd.take_action(parsed_args)
 
-        self.projects_mock.get.assert_called_with(
-            self.project.id,
-            parents_as_list=False,
-            subtree_as_list=False,
-        )
+        self.projects_mock.get.assert_called_once_with(self.project.id)
 
         collist = (
             'description',
@@ -824,8 +819,6 @@ class TestProjectShow(TestProject):
                 'parents': [{'project': {'id': self.project.parent_id}}]
             }
         )
-        self.projects_mock.get.side_effect = [Exception("Not found"),
-                                              self.project]
         self.projects_mock.get.return_value = self.project
 
         arglist = [
@@ -849,11 +842,12 @@ class TestProjectShow(TestProject):
              }
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.projects_mock.get.assert_called_with(
-            self.project.id,
-            parents_as_list=True,
-            subtree_as_list=False,
-        )
+
+        self.projects_mock.get.assert_has_calls([call(self.project.id),
+                                                 call(self.project.id,
+                                                      parents_as_list=True,
+                                                      subtree_as_list=False,
+                                                      )])
 
         collist = (
             'description',
@@ -885,8 +879,6 @@ class TestProjectShow(TestProject):
                 'subtree': [{'project': {'id': 'children-id'}}]
             }
         )
-        self.projects_mock.get.side_effect = [Exception("Not found"),
-                                              self.project]
         self.projects_mock.get.return_value = self.project
 
         arglist = [
@@ -910,11 +902,11 @@ class TestProjectShow(TestProject):
              }
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.projects_mock.get.assert_called_with(
-            self.project.id,
-            parents_as_list=False,
-            subtree_as_list=True,
-        )
+        self.projects_mock.get.assert_has_calls([call(self.project.id),
+                                                 call(self.project.id,
+                                                      parents_as_list=False,
+                                                      subtree_as_list=True,
+                                                      )])
 
         collist = (
             'description',
@@ -947,8 +939,6 @@ class TestProjectShow(TestProject):
                 'subtree': [{'project': {'id': 'children-id'}}]
             }
         )
-        self.projects_mock.get.side_effect = [Exception("Not found"),
-                                              self.project]
         self.projects_mock.get.return_value = self.project
 
         arglist = [
@@ -973,11 +963,11 @@ class TestProjectShow(TestProject):
              }
 
         columns, data = self.cmd.take_action(parsed_args)
-        self.projects_mock.get.assert_called_with(
-            self.project.id,
-            parents_as_list=True,
-            subtree_as_list=True,
-        )
+        self.projects_mock.get.assert_has_calls([call(self.project.id),
+                                                 call(self.project.id,
+                                                      parents_as_list=True,
+                                                      subtree_as_list=True,
+                                                      )])
 
         collist = (
             'description',
diff --git a/releasenotes/notes/bug-1499657-eeb260849febacf3.yaml b/releasenotes/notes/bug-1499657-eeb260849febacf3.yaml
new file mode 100644
index 0000000000..73af129b10
--- /dev/null
+++ b/releasenotes/notes/bug-1499657-eeb260849febacf3.yaml
@@ -0,0 +1,6 @@
+---
+fixes:
+  - |
+    Options ``--parents`` and ``--children`` don't work in ``project show``
+    command, fix the issue.
+    [Bug `1499657 <https://bugs.launchpad.net/python-openstackclient/+bug/1499657>`_]