fix: fix expiry for `to_json()` (#589)
* This patch for </issues/501> includes the following fixes:
- The access token is always set to `None`, so the fix involves using (the access) `token` from the saved JSON credentials file.
- For refresh needs, `expiry` also needs to be saved via `to_json()`.
- DUMP: As `expiry` is a `datetime.datetime` object, serialize to `datetime.isoformat()` in the same [`oauth2client` format](https://github.com/googleapis/oauth2client/blob/master/oauth2client/client.py#L55) for consistency.
- LOAD: Add code to restore `expiry` back to `datetime.datetime` object when imported.
- LOAD: If `expiry` was unsaved, automatically set it as expired so refresh takes place.
- Minor `scopes` updates
- DUMP: Add property for `scopes` so `to_json()` can grab it
- LOAD: `scopes` may be saved as a string instead of a JSON array (Python list), so ensure it is Sequence[str] when imported.
diff --git a/tests/oauth2/test_credentials.py b/tests/oauth2/test_credentials.py
index ceb8cdf..ee8b8a2 100644
--- a/tests/oauth2/test_credentials.py
+++ b/tests/oauth2/test_credentials.py
@@ -359,6 +359,20 @@
assert creds.token_uri == credentials._GOOGLE_OAUTH2_TOKEN_ENDPOINT
assert creds.scopes == scopes
+ info["scopes"] = "email" # single non-array scope from file
+ creds = credentials.Credentials.from_authorized_user_info(info)
+ assert creds.scopes == [info["scopes"]]
+
+ info["scopes"] = ["email", "profile"] # array scope from file
+ creds = credentials.Credentials.from_authorized_user_info(info)
+ assert creds.scopes == info["scopes"]
+
+ expiry = datetime.datetime(2020, 8, 14, 15, 54, 1)
+ info["expiry"] = expiry.isoformat() + "Z"
+ creds = credentials.Credentials.from_authorized_user_info(info)
+ assert creds.expiry == expiry
+ assert creds.expired
+
def test_from_authorized_user_file(self):
info = AUTH_USER_INFO.copy()
@@ -381,7 +395,10 @@
def test_to_json(self):
info = AUTH_USER_INFO.copy()
+ expiry = datetime.datetime(2020, 8, 14, 15, 54, 1)
+ info["expiry"] = expiry.isoformat() + "Z"
creds = credentials.Credentials.from_authorized_user_info(info)
+ assert creds.expiry == expiry
# Test with no `strip` arg
json_output = creds.to_json()
@@ -392,6 +409,7 @@
assert json_asdict.get("client_id") == creds.client_id
assert json_asdict.get("scopes") == creds.scopes
assert json_asdict.get("client_secret") == creds.client_secret
+ assert json_asdict.get("expiry") == info["expiry"]
# Test with a `strip` arg
json_output = creds.to_json(strip=["client_secret"])
@@ -403,6 +421,12 @@
assert json_asdict.get("scopes") == creds.scopes
assert json_asdict.get("client_secret") is None
+ # Test with no expiry
+ creds.expiry = None
+ json_output = creds.to_json()
+ json_asdict = json.loads(json_output)
+ assert json_asdict.get("expiry") is None
+
def test_pickle_and_unpickle(self):
creds = self.make_credentials()
unpickled = pickle.loads(pickle.dumps(creds))