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.
This commit is contained in:
Danny Hermes
2015-10-06 10:31:35 -07:00
parent 232e24cd57
commit 2b159188a1
2 changed files with 94 additions and 40 deletions

View File

@@ -39,7 +39,7 @@ class CredentialsField(six.with_metaclass(models.SubfieldBase, models.Field)):
super(CredentialsField, self).__init__(*args, **kwargs) super(CredentialsField, self).__init__(*args, **kwargs)
def get_internal_type(self): def get_internal_type(self):
return "TextField" return 'TextField'
def to_python(self, value): def to_python(self, value):
if value is None: if value is None:
@@ -55,10 +55,12 @@ class CredentialsField(six.with_metaclass(models.SubfieldBase, models.Field)):
def value_to_string(self, obj): def value_to_string(self, obj):
"""Convert the field value from the provided model to a string. """Convert the field value from the provided model to a string.
Used during model serialization. Used during model serialization.
Args: Args:
obj: db.Model, model object obj: db.Model, model object
Returns: Returns:
string, the serialized field value string, the serialized field value
""" """
@@ -66,9 +68,7 @@ class CredentialsField(six.with_metaclass(models.SubfieldBase, models.Field)):
return self.get_prep_value(value) return self.get_prep_value(value)
class FlowField(models.Field): class FlowField(six.with_metaclass(models.SubfieldBase, models.Field)):
__metaclass__ = models.SubfieldBase
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
if 'null' not in kwargs: if 'null' not in kwargs:
@@ -76,7 +76,7 @@ class FlowField(models.Field):
super(FlowField, self).__init__(*args, **kwargs) super(FlowField, self).__init__(*args, **kwargs)
def get_internal_type(self): def get_internal_type(self):
return "TextField" return 'TextField'
def to_python(self, value): def to_python(self, value):
if value is None: if value is None:
@@ -85,14 +85,28 @@ class FlowField(models.Field):
return value return value
return pickle.loads(base64.b64decode(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: if value is None:
return 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): 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 This Storage helper presumes the Credentials
have been stored as a CredenialsField have been stored as a CredenialsField
@@ -116,7 +130,7 @@ class Storage(BaseStorage):
self.property_name = property_name self.property_name = property_name
def locked_get(self): def locked_get(self):
"""Retrieve Credential from datastore. """Retrieve stored credential.
Returns: Returns:
oauth2client.Credentials oauth2client.Credentials
@@ -132,7 +146,7 @@ class Storage(BaseStorage):
return credential return credential
def locked_put(self, credentials, overwrite=False): def locked_put(self, credentials, overwrite=False):
"""Write a Credentials to the datastore. """Write a Credentials to the Django datastore.
Args: Args:
credentials: Credentials, the credentials to store. credentials: Credentials, the credentials to store.

View File

@@ -20,15 +20,13 @@ Unit tests for objects created from discovery documents.
""" """
import base64 import base64
import datetime
import imp import imp
import os import os
import pickle import pickle
import sys import sys
import unittest import unittest
from oauth2client.client import Credentials
from oauth2client.client import Flow
# Mock a Django environment # Mock a Django environment
from django.conf import global_settings from django.conf import global_settings
global_settings.SECRET_KEY = 'NotASecret' global_settings.SECRET_KEY = 'NotASecret'
@@ -38,9 +36,15 @@ sys.modules['django_settings'] = django_settings = imp.new_module(
django_settings.SECRET_KEY = 'xyzzy' django_settings.SECRET_KEY = 'xyzzy'
from django.db import models 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 CredentialsField
from oauth2client.django_orm import FlowField 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)' __author__ = 'conleyo@google.com (Conley Owens)'
@@ -48,15 +52,18 @@ __author__ = 'conleyo@google.com (Conley Owens)'
class TestCredentialsField(unittest.TestCase): class TestCredentialsField(unittest.TestCase):
def setUp(self): def setUp(self):
self.fake_model = FakeCredentialsModel()
self.fake_model_field = self.fake_model._meta.get_field('credentials')
self.field = CredentialsField() self.field = CredentialsField()
self.credentials = Credentials() 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): def test_field_is_text(self):
self.assertEquals(self.field.get_internal_type(), 'TextField') self.assertEquals(self.field.get_internal_type(), 'TextField')
def test_field_unpickled(self): 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)) Credentials))
def test_field_unpickled_none(self): def test_field_unpickled_none(self):
@@ -65,50 +72,83 @@ class TestCredentialsField(unittest.TestCase):
def test_field_pickled(self): def test_field_pickled(self):
prep_value = self.field.get_db_prep_value(self.credentials, prep_value = self.field.get_db_prep_value(self.credentials,
connection=None) connection=None)
self.assertEqual(_to_bytes(prep_value), self.pickle) self.assertEqual(prep_value, self.pickle_str)
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
)))
def test_field_value_to_string(self): def test_field_value_to_string(self):
self.model.credentials = self.credentials self.fake_model.credentials = self.credentials
value_str = self.field.value_to_string(self.model) value_str = self.fake_model_field.value_to_string(self.fake_model)
self.assertEqual(value_str, self.pickle_str) self.assertEqual(value_str, self.pickle_str)
def test_field_value_to_string_none(self): def test_field_value_to_string_none(self):
self.model.credentials = None self.fake_model.credentials = None
value_str = self.field.value_to_string(self.model) value_str = self.fake_model_field.value_to_string(self.fake_model)
self.assertEqual(value_str, None) self.assertEqual(value_str, None)
class TestFlowField(unittest.TestCase): class TestFlowField(unittest.TestCase):
class FakeFlowModel(models.Model):
flow = FlowField()
def setUp(self): def setUp(self):
self.fake_model = self.FakeFlowModel()
self.fake_model_field = self.fake_model._meta.get_field('flow')
self.field = FlowField() self.field = FlowField()
self.flow = Flow() 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): def test_field_is_text(self):
self.assertEquals(self.field.get_internal_type(), 'TextField') self.assertEquals(self.field.get_internal_type(), 'TextField')
def test_field_unpickled(self): 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): def test_field_pickled(self):
prep_value = self.field.get_db_prep_value(self.flow, connection=None) 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 if __name__ == '__main__': # pragma: NO COVER