Repository: canonical/operator

Issue:
uncaught error in `Secret.get_info()`
the following error appears while running the `owner` charm in [this demo bundle](https://github.com/PietroPasotti/secrets-demo-charms/tree/main)

![image](https://user-images.githubusercontent.com/6230162/216614436-164e80c9-0649-4d68-af38-a2ec516b83af.png)


Discussion:

Patch:
diff --git a/ops/framework.py b/ops/framework.py
index 0ba99e1..c9da35e 100755
--- a/ops/framework.py
+++ b/ops/framework.py
@@ -549,7 +549,7 @@ _event_regex = r'^(|.*/)on/[a-zA-Z_]+\[\d+\]$'
 
 
 class Framework(Object):
-    """Main interface to from the Charm to the Operator Framework internals."""
+    """Main interface from the Charm to the Operator Framework internals."""
 
     on = FrameworkEvents()
 
diff --git a/ops/model.py b/ops/model.py
index 7bf5576..141bd4f 100644
--- a/ops/model.py
+++ b/ops/model.py
@@ -2926,7 +2926,7 @@ class _ModelBackend:
         args = []  # type: List[str]
         if id is not None:
             args.append(id)
-        if label is not None:
+        elif label is not None:  # elif because Juju secret-info-get doesn't allow id and label
             args.extend(['--label', label])
         result = self._run_for_secret('secret-info-get', *args, return_output=True, use_json=True)
         info_dicts = typing.cast(Dict[str, 'JsonObject'], result)


Test patch:
diff --git a/ops/testing.py b/ops/testing.py
index 7082976..cf8912a 100755
--- a/ops/testing.py
+++ b/ops/testing.py
@@ -1116,7 +1116,7 @@ class Harness(Generic[CharmType]):
             self._charm.on.leader_elected.emit()
 
     def set_planned_units(self, num_units: int) -> None:
-        """Set the number of "planned" units  that "Application.planned_units" should return.
+        """Set the number of "planned" units that "Application.planned_units" should return.
 
         In real world circumstances, this number will be the number of units in the
         application. E.g., this number will be the number of peers this unit has, plus one, as we
diff --git a/test/test_model.py b/test/test_model.py
index 7859feb..976fb77 100755
--- a/test/test_model.py
+++ b/test/test_model.py
@@ -2993,14 +2993,34 @@ class TestSecretClass(unittest.TestCase):
     def test_get_info(self):
         fake_script(self, 'secret-info-get', """echo '{"x": {"label": "y", "revision": 7}}'""")
 
+        # Secret with ID only
+        secret = self.make_secret(id='x')
+        info = secret.get_info()
+        self.assertEqual(info.id, 'secret:x')
+        self.assertEqual(info.label, 'y')
+        self.assertEqual(info.revision, 7)
+
+        # Secret with label only
+        secret = self.make_secret(label='y')
+        info = secret.get_info()
+        self.assertEqual(info.id, 'secret:x')
+        self.assertEqual(info.label, 'y')
+        self.assertEqual(info.revision, 7)
+
+        # Secret with ID and label
         secret = self.make_secret(id='x', label='y')
         info = secret.get_info()
         self.assertEqual(info.id, 'secret:x')
         self.assertEqual(info.label, 'y')
         self.assertEqual(info.revision, 7)
 
-        self.assertEqual(fake_script_calls(self, clear=True),
-                         [['secret-info-get', 'secret:x', '--label', 'y', '--format=json']])
+        self.assertEqual(
+            fake_script_calls(self, clear=True),
+            [
+                ['secret-info-get', 'secret:x', '--format=json'],
+                ['secret-info-get', '--label', 'y', '--format=json'],
+                ['secret-info-get', 'secret:x', '--format=json'],
+            ])
 
     def test_set_content(self):
         fake_script(self, 'secret-set', """exit 0""")