# HG changeset patch # User Denis Laxalde # Date 1476263230 -7200 # Node ID 760d5c0ae08f6cfe0fb0b926877fb6af2b9006aa # Parent 73201a210007dec36d19cb6b2fbbf5a6331f969c [utils] Encode Binary value in base64 for JSON export In unittest_utils.py, use unittest2's TestCase instead of lgc.testlib one to benefit from subTest API. Closes #15409885. diff -r 73201a210007 -r 760d5c0ae08f cubicweb/test/unittest_utils.py --- a/cubicweb/test/unittest_utils.py Wed Oct 12 11:09:08 2016 +0200 +++ b/cubicweb/test/unittest_utils.py Wed Oct 12 11:07:10 2016 +0200 @@ -17,15 +17,19 @@ # with CubicWeb. If not, see . """unit tests for module cubicweb.utils""" +import base64 import datetime import decimal import doctest import re +try: + from unittest2 import TestCase +except ImportError: # Python3 + from unittest import TestCase from six.moves import range -from logilab.common.testlib import TestCase, unittest_main - +from cubicweb import Binary from cubicweb.devtools.testlib import CubicWebTC from cubicweb.utils import (make_uid, UStringIO, RepeatList, HTMLHead, QueryCache, parse_repo_uri) @@ -200,6 +204,12 @@ self.assertEqual(json.loads(self.encode([e])), [{'pouet': 'hop', 'eid': 2}]) + def test_encoding_binary(self): + for content in (b'he he', b'h\xe9 hxe9'): + with self.subTest(content=content): + encoded = self.encode(Binary(content)) + self.assertEqual(base64.b64decode(encoded), content) + def test_encoding_unknown_stuff(self): self.assertEqual(self.encode(TestCase), 'null') @@ -322,4 +332,5 @@ if __name__ == '__main__': - unittest_main() + import unittest + unittest.main() diff -r 73201a210007 -r 760d5c0ae08f cubicweb/utils.py --- a/cubicweb/utils.py Wed Oct 12 11:09:08 2016 +0200 +++ b/cubicweb/utils.py Wed Oct 12 11:07:10 2016 +0200 @@ -21,6 +21,7 @@ __docformat__ = "restructuredtext en" +import base64 import decimal import datetime import random @@ -42,6 +43,9 @@ from logilab.common.deprecation import deprecated from logilab.common.date import ustrftime +from cubicweb import Binary + + _MARKER = object() # initialize random seed from current time @@ -507,6 +511,8 @@ return (obj.days * 24 * 60 * 60) + obj.seconds elif isinstance(obj, decimal.Decimal): return float(obj) + elif isinstance(obj, Binary): + return base64.b64encode(obj.getvalue()).decode('ascii') try: return json.JSONEncoder.default(self, obj) except TypeError: