From 2b159188a1ff634b3728ffcd5f6e7f2ffa8d3bad Mon Sep 17 00:00:00 2001 From: Danny Hermes Date: Tue, 6 Oct 2015 10:31:35 -0700 Subject: [PATCH] Updating django_orm.FlowField to work in Python 3. Also adding tests for this and merging the two different TestCase classes for django_orm.CredentialField. Also adding a test for the django_orm.Storage constructor. --- oauth2client/django_orm.py | 34 +++++++++---- tests/test_django_orm.py | 100 ++++++++++++++++++++++++++----------- 2 files changed, 94 insertions(+), 40 deletions(-) diff --git a/oauth2client/django_orm.py b/oauth2client/django_orm.py index 2dcebb0..e6d31a6 100644 --- a/oauth2client/django_orm.py +++ b/oauth2client/django_orm.py @@ -39,7 +39,7 @@ class CredentialsField(six.with_metaclass(models.SubfieldBase, models.Field)): super(CredentialsField, self).__init__(*args, **kwargs) def get_internal_type(self): - return "TextField" + return 'TextField' def to_python(self, value): if value is None: @@ -55,10 +55,12 @@ class CredentialsField(six.with_metaclass(models.SubfieldBase, models.Field)): def value_to_string(self, obj): """Convert the field value from the provided model to a string. + Used during model serialization. Args: obj: db.Model, model object + Returns: string, the serialized field value """ @@ -66,9 +68,7 @@ class CredentialsField(six.with_metaclass(models.SubfieldBase, models.Field)): return self.get_prep_value(value) -class FlowField(models.Field): - - __metaclass__ = models.SubfieldBase +class FlowField(six.with_metaclass(models.SubfieldBase, models.Field)): def __init__(self, *args, **kwargs): if 'null' not in kwargs: @@ -76,7 +76,7 @@ class FlowField(models.Field): super(FlowField, self).__init__(*args, **kwargs) def get_internal_type(self): - return "TextField" + return 'TextField' def to_python(self, value): if value is None: @@ -85,14 +85,28 @@ class FlowField(models.Field): return value return pickle.loads(base64.b64decode(value)) - def get_db_prep_value(self, value, connection, prepared=False): + def get_prep_value(self, value): if value is None: return None - return base64.b64encode(pickle.dumps(value)) + return smart_text(base64.b64encode(pickle.dumps(value))) + + def value_to_string(self, obj): + """Convert the field value from the provided model to a string. + + Used during model serialization. + + Args: + obj: db.Model, model object + + Returns: + string, the serialized field value + """ + value = self._get_val_from_obj(obj) + return self.get_prep_value(value) class Storage(BaseStorage): - """Store and retrieve a single credential to and from the datastore. + """Store and retrieve a single credential to and from the Django datastore. This Storage helper presumes the Credentials have been stored as a CredenialsField @@ -116,7 +130,7 @@ class Storage(BaseStorage): self.property_name = property_name def locked_get(self): - """Retrieve Credential from datastore. + """Retrieve stored credential. Returns: oauth2client.Credentials @@ -132,7 +146,7 @@ class Storage(BaseStorage): return credential def locked_put(self, credentials, overwrite=False): - """Write a Credentials to the datastore. + """Write a Credentials to the Django datastore. Args: credentials: Credentials, the credentials to store. diff --git a/tests/test_django_orm.py b/tests/test_django_orm.py index 3110c61..d0a3502 100644 --- a/tests/test_django_orm.py +++ b/tests/test_django_orm.py @@ -20,15 +20,13 @@ Unit tests for objects created from discovery documents. """ import base64 +import datetime import imp import os import pickle import sys import unittest -from oauth2client.client import Credentials -from oauth2client.client import Flow - # Mock a Django environment from django.conf import global_settings global_settings.SECRET_KEY = 'NotASecret' @@ -38,9 +36,15 @@ sys.modules['django_settings'] = django_settings = imp.new_module( django_settings.SECRET_KEY = 'xyzzy' from django.db import models +from oauth2client._helpers import _from_bytes +from oauth2client._helpers import _to_bytes +from oauth2client.client import Credentials +from oauth2client.client import Flow +from oauth2client.client import OAuth2Credentials from oauth2client.django_orm import CredentialsField from oauth2client.django_orm import FlowField -from oauth2client._helpers import _from_bytes, _to_bytes +from oauth2client.django_orm import Storage +from oauth2client import GOOGLE_TOKEN_URI __author__ = 'conleyo@google.com (Conley Owens)' @@ -48,15 +52,18 @@ __author__ = 'conleyo@google.com (Conley Owens)' class TestCredentialsField(unittest.TestCase): def setUp(self): + self.fake_model = FakeCredentialsModel() + self.fake_model_field = self.fake_model._meta.get_field('credentials') self.field = CredentialsField() self.credentials = Credentials() - self.pickle = base64.b64encode(pickle.dumps(self.credentials)) + self.pickle_str = _from_bytes( + base64.b64encode(pickle.dumps(self.credentials))) def test_field_is_text(self): self.assertEquals(self.field.get_internal_type(), 'TextField') def test_field_unpickled(self): - self.assertTrue(isinstance(self.field.to_python(self.pickle), + self.assertTrue(isinstance(self.field.to_python(self.pickle_str), Credentials)) def test_field_unpickled_none(self): @@ -65,50 +72,83 @@ class TestCredentialsField(unittest.TestCase): def test_field_pickled(self): prep_value = self.field.get_db_prep_value(self.credentials, connection=None) - self.assertEqual(_to_bytes(prep_value), self.pickle) - - -class TestCredentialsFieldViaModel(unittest.TestCase): - - class TestModel(models.Model): - credentials = CredentialsField() - - def setUp(self): - self.model = self.TestModel() - # using the meta api: - # https://docs.djangoproject.com/en/1.8/ref/models/meta/#field-access-api - self.field = self.model._meta.get_field('credentials') - self.credentials = Credentials() - self.pickle_str = _from_bytes(base64.b64encode(pickle.dumps( - self.credentials - ))) + self.assertEqual(prep_value, self.pickle_str) def test_field_value_to_string(self): - self.model.credentials = self.credentials - value_str = self.field.value_to_string(self.model) + self.fake_model.credentials = self.credentials + value_str = self.fake_model_field.value_to_string(self.fake_model) self.assertEqual(value_str, self.pickle_str) def test_field_value_to_string_none(self): - self.model.credentials = None - value_str = self.field.value_to_string(self.model) + self.fake_model.credentials = None + value_str = self.fake_model_field.value_to_string(self.fake_model) self.assertEqual(value_str, None) class TestFlowField(unittest.TestCase): + + class FakeFlowModel(models.Model): + flow = FlowField() + def setUp(self): + self.fake_model = self.FakeFlowModel() + self.fake_model_field = self.fake_model._meta.get_field('flow') self.field = FlowField() self.flow = Flow() - self.pickle = base64.b64encode(pickle.dumps(self.flow)) + self.pickle_str = _from_bytes( + base64.b64encode(pickle.dumps(self.flow))) def test_field_is_text(self): self.assertEquals(self.field.get_internal_type(), 'TextField') def test_field_unpickled(self): - self.assertTrue(isinstance(self.field.to_python(self.pickle), Flow)) + python_val = self.field.to_python(self.pickle_str) + self.assertTrue(isinstance(python_val, Flow)) def test_field_pickled(self): prep_value = self.field.get_db_prep_value(self.flow, connection=None) - self.assertEqual(prep_value, self.pickle) + self.assertEqual(prep_value, self.pickle_str) + + def test_field_value_to_string(self): + self.fake_model.flow = self.flow + value_str = self.fake_model_field.value_to_string(self.fake_model) + self.assertEqual(value_str, self.pickle_str) + + def test_field_value_to_string_none(self): + self.fake_model.flow = None + value_str = self.fake_model_field.value_to_string(self.fake_model) + self.assertEqual(value_str, None) + + +class TestStorage(unittest.TestCase): + + def setUp(self): + access_token = 'foo' + client_id = 'some_client_id' + client_secret = 'cOuDdkfjxxnv+' + refresh_token = '1/0/a.df219fjls0' + token_expiry = datetime.datetime.utcnow() + user_agent = 'refresh_checker/1.0' + self.credentials = OAuth2Credentials( + access_token, client_id, client_secret, + refresh_token, token_expiry, GOOGLE_TOKEN_URI, + user_agent) + + def test_constructor(self): + key_name = 'foo' + key_value = 'bar' + property_name = 'credentials' + storage = Storage(FakeCredentialsModel, key_name, + key_value, property_name) + + self.assertEqual(storage.model_class, FakeCredentialsModel) + self.assertEqual(storage.key_name, key_name) + self.assertEqual(storage.key_value, key_value) + self.assertEqual(storage.property_name, property_name) + + +class FakeCredentialsModel(models.Model): + credentials = CredentialsField() if __name__ == '__main__': # pragma: NO COVER