Skip to content

Commit

Permalink
Merge pull request #7 from Globegitter/to-global-id-unicode-error
Browse files Browse the repository at this point in the history
Fix utf-8 error on py 2.7
  • Loading branch information
syrusakbary committed Nov 23, 2016
2 parents c4c6533 + 148575e commit 22b2a70
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 56 deletions.
55 changes: 23 additions & 32 deletions graphql_relay/mutation/tests/test_mutation.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from collections import OrderedDict

from promise import Promise
from collections import namedtuple
from pytest import raises
from graphql import graphql
from graphql.type import (
GraphQLSchema,
Expand Down Expand Up @@ -83,22 +83,6 @@ def test_requires_an_argument():
}
}
'''
expected = {
'allObjects': [
{
'id': 'VXNlcjox'
},
{
'id': 'VXNlcjoy'
},
{
'id': 'UGhvdG86MQ=='
},
{
'id': 'UGhvdG86Mg=='
},
]
}
result = graphql(schema, query)
assert len(result.errors) == 1

Expand Down Expand Up @@ -333,96 +317,103 @@ def test_contains_correct_field():
}
}
'''

expected = {
'__schema': {
'mutationType': {
'fields': [
{
'name': 'simpleMutation',
'name': 'simplePromiseMutation',
'args': [
{
'name': 'input',
'type': {
'name': None,
'kind': 'NON_NULL',
'ofType': {
'name': 'SimpleMutationInput',
'name': 'SimplePromiseMutationInput',
'kind': 'INPUT_OBJECT'
}
},
}
],
'type': {
'name': 'SimpleMutationPayload',
'name': 'SimplePromiseMutationPayload',
'kind': 'OBJECT',
}
},
{
'name': 'simpleMutationWithThunkFields',
'name': 'simpleRootValueMutation',
'args': [
{
'name': 'input',
'type': {
'name': None,
'kind': 'NON_NULL',
'ofType': {
'name': 'SimpleMutationWithThunkFieldsInput',
'name': 'SimpleRootValueMutationInput',
'kind': 'INPUT_OBJECT'
}
},
}
],
'type': {
'name': 'SimpleMutationWithThunkFieldsPayload',
'name': 'SimpleRootValueMutationPayload',
'kind': 'OBJECT',
}
},
{
'name': 'simplePromiseMutation',
'name': 'simpleMutation',
'args': [
{
'name': 'input',
'type': {
'name': None,
'kind': 'NON_NULL',
'ofType': {
'name': 'SimplePromiseMutationInput',
'name': 'SimpleMutationInput',
'kind': 'INPUT_OBJECT'
}
},
}
],
'type': {
'name': 'SimplePromiseMutationPayload',
'name': 'SimpleMutationPayload',
'kind': 'OBJECT',
}
},
{
'name': 'simpleRootValueMutation',
'name': 'simpleMutationWithThunkFields',
'args': [
{
'name': 'input',
'type': {
'name': None,
'kind': 'NON_NULL',
'ofType': {
'name': 'SimpleRootValueMutationInput',
'name': 'SimpleMutationWithThunkFieldsInput',
'kind': 'INPUT_OBJECT'
}
},
}
],
'type': {
'name': 'SimpleRootValueMutationPayload',
'name': 'SimpleMutationWithThunkFieldsPayload',
'kind': 'OBJECT',
}
},
]
}
}

}
result = graphql(schema, query)
assert not result.errors
# ensure the ordering is correct for the assertion
expected['__schema']['mutationType']['fields'] = sorted(
expected['__schema']['mutationType']['fields'],
key=lambda k: k['name']
)
result.data['__schema']['mutationType']['fields'] = sorted(
result.data['__schema']['mutationType']['fields'],
key=lambda k: k['name']
)
assert result.data == expected
4 changes: 3 additions & 1 deletion graphql_relay/node/node.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from collections import OrderedDict
from graphql_relay.utils import base64, unbase64

from six import text_type

from graphql.type import (
GraphQLArgument,
GraphQLNonNull,
Expand Down Expand Up @@ -52,7 +54,7 @@ def to_global_id(type, id):
Takes a type name and an ID specific to that type name, and returns a
"global ID" that is unique among all types.
'''
return base64(':'.join([type, str(id)]))
return base64(':'.join([type, text_type(id)]))


def from_global_id(global_id):
Expand Down
Empty file.
5 changes: 0 additions & 5 deletions graphql_relay/node/tests/test_global.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
from collections import namedtuple
from pytest import raises
from graphql import graphql
from graphql.type import (
GraphQLSchema,
GraphQLObjectType,
GraphQLField,
GraphQLArgument,
GraphQLList,
GraphQLNonNull,
GraphQLInt,
GraphQLString,
GraphQLBoolean,
GraphQLID,
)

from graphql_relay.node.node import (
Expand Down
31 changes: 26 additions & 5 deletions graphql_relay/node/tests/test_node.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from collections import namedtuple
from pytest import raises
from graphql import graphql
from graphql.type import (
GraphQLSchema,
GraphQLObjectType,
GraphQLField,
GraphQLArgument,
GraphQLList,
GraphQLNonNull,
GraphQLInt,
GraphQLString,
GraphQLBoolean,
GraphQLID,
)

from graphql_relay.node.node import node_definitions
from ..node import node_definitions, to_global_id, from_global_id

User = namedtuple('User', ['id', 'name'])
Photo = namedtuple('Photo', ['id', 'width'])
Expand Down Expand Up @@ -332,3 +331,25 @@ def test_has_correct_node_root_field():
result = graphql(schema, query)
assert not result.errors
assert result.data == expected


def test_to_global_id_converts_unicode_strings_correctly():
my_unicode_id = u'ûñö'
g_id = to_global_id('MyType', my_unicode_id)
assert g_id == 'TXlUeXBlOsO7w7HDtg=='

my_unicode_id = u'\u06ED'
g_id = to_global_id('MyType', my_unicode_id)
assert g_id == 'TXlUeXBlOtut'


def test_from_global_id_converts_unicode_strings_correctly():
my_unicode_id = u'ûñö'
my_type, my_id = from_global_id('TXlUeXBlOsO7w7HDtg==')
assert my_type == 'MyType'
assert my_id == my_unicode_id

my_unicode_id = u'\u06ED'
my_type, my_id = from_global_id('TXlUeXBlOtut')
assert my_type == 'MyType'
assert my_id == my_unicode_id
Empty file added graphql_relay/tests/__init__.py
Empty file.
34 changes: 34 additions & 0 deletions graphql_relay/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import base64

from .. import utils


def test_base64_encode_unicode_strings_correctly():
my_unicode = u'ûñö'
my_base64 = utils.base64(my_unicode)
assert my_base64 == base64.b64encode(my_unicode.encode('utf-8')).decode('utf-8')

my_unicode = u'\u06ED'
my_base64 = utils.base64(my_unicode)
assert my_base64 == base64.b64encode(my_unicode.encode('utf-8')).decode('utf-8')


def test_base64_encode_strings_correctly():
my_string = 'abc'
my_base64 = utils.base64(my_string)
assert my_base64 == base64.b64encode(my_string.encode('utf-8')).decode('utf-8')


def test_unbase64_decodes_unicode_strings_correctly():
my_unicode = u'ûñö'
my_converted_unicode = utils.unbase64(utils.base64(my_unicode))
assert my_unicode == my_converted_unicode


def test_unbase64_decodes_strings_correctly():
my_string = 'abc'
my_converted_string = utils.unbase64(utils.base64(my_string))
assert my_string == my_converted_string
22 changes: 9 additions & 13 deletions graphql_relay/utils.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
from base64 import b64encode as _base64, b64decode as _unbase64

try:
str_type = basestring
base64 = _base64
unbase64 = _unbase64
from six import string_types

def is_str(s):
return isinstance(s, basestring)

except NameError:
def base64(s):
return _base64(bytes(s, 'utf-8')).decode('utf-8')
def base64(s):
return _base64(s.encode('utf-8')).decode('utf-8')

def unbase64(s):
return _unbase64(s).decode('utf-8')

def is_str(s):
return isinstance(s, str)
def unbase64(s):
return _unbase64(s).decode('utf-8')


def is_str(s):
return isinstance(s, string_types)


def resolve_maybe_thunk(f):
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ def run_tests(self):
packages=find_packages(exclude=['tests']),

install_requires=[
'six>=1.10.0',
'graphql-core>=0.5.0',
'promise>=0.4.0'
],
Expand Down
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ envlist = py27,py33,py34,py35,pypy
deps=
pytest>=2.7.2
django>=1.8.0,<1.9
six
flake8
singledispatch
commands=
Expand Down

0 comments on commit 22b2a70

Please sign in to comment.