diff options
author | Aleksey Lim <alsroot@sugarlabs.org> | 2012-09-25 04:01:07 (GMT) |
---|---|---|
committer | Aleksey Lim <alsroot@sugarlabs.org> | 2012-09-25 04:01:07 (GMT) |
commit | 40b9b03232f665d93e42bb72b9c93048413ea075 (patch) | |
tree | 02a843223781418070488f9a7e9e262841f16587 | |
parent | 5262575cb4acdfb931a5f658f9a047a14b176a47 (diff) |
Decode json blobs before setting
-rw-r--r-- | active_document/volume.py | 10 | ||||
-rwxr-xr-x | tests/units/volume.py | 88 |
2 files changed, 88 insertions, 10 deletions
diff --git a/active_document/volume.py b/active_document/volume.py index a09e42b..ebd6775 100644 --- a/active_document/volume.py +++ b/active_document/volume.py @@ -15,6 +15,7 @@ import os import time +import json import logging from contextlib import contextmanager from os.path import exists, join, abspath, isdir @@ -167,9 +168,12 @@ class VolumeCommands(CommandsProcessor): permissions=env.ACCESS_AUTH | env.ACCESS_AUTHOR) def update_prop(self, request, prop, url=None): if url: - request.content = {prop: PropertyMeta(url=url)} + value = PropertyMeta(url=url) + elif request.content is None: + value = request.content_stream else: - request.content = {prop: request.content or request.content_stream} + value = request.content + request.content = {prop: value} return self.update(request) @document_command(method='DELETE', @@ -244,6 +248,8 @@ class VolumeCommands(CommandsProcessor): prop.assert_access(access) value = prop.on_set(doc, value) if isinstance(prop, BlobProperty): + if prop.mime_type == 'application/json': + value = json.dumps(value) enforce(PropertyMeta.is_blob(value), 'Invalid BLOB value') blobs.append((name, value)) else: diff --git a/tests/units/volume.py b/tests/units/volume.py index 14a5744..be706f9 100755 --- a/tests/units/volume.py +++ b/tests/units/volume.py @@ -5,6 +5,7 @@ import os import sys import time import shutil +import hashlib from cStringIO import StringIO from email.message import Message from os.path import dirname, join, abspath, exists @@ -153,6 +154,64 @@ class VolumeTest(tests.Test): self.call('PUT', document='testdocument', guid=guid, prop='blob', content=None) self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob') + def test_GetBLOBs(self): + + class TestDocument(Document): + + @active_property(BlobProperty) + def blob(self, value): + return value + + self.volume = SingleVolume(tests.tmpdir, [TestDocument]) + guid = self.call('POST', document='testdocument', content={}) + self.call('PUT', document='testdocument', guid=guid, prop='blob', content='blob') + + blob_path = tests.tmpdir + '/testdocument/%s/%s/blob' % (guid[:2], guid) + blob_meta = { + 'seqno': 3, + 'path': blob_path + '.blob', + 'digest': hashlib.sha1('blob').hexdigest(), + 'mime_type': 'application/octet-stream', + 'mtime': os.stat(blob_path).st_mtime, + } + + stream = self.call('GET', document='testdocument', guid=guid, prop='blob') + self.assertEqual('blob', ''.join([i for i in stream])) + + self.assertEqual( + {'guid': guid, 'blob': blob_meta}, + self.call('GET', document='testdocument', guid=guid, reply=['guid', 'blob'])) + + self.assertEqual([ + {'guid': guid, 'blob': blob_meta}, + ], + self.call('GET', document='testdocument', reply=['guid', 'blob'])['result']) + + def test_JsonBLOB(self): + + class TestDocument(Document): + + @active_property(BlobProperty, mime_type='application/json') + def blob(self, value): + return value + + self.volume = SingleVolume(tests.tmpdir, [TestDocument]) + guid = self.call('POST', document='testdocument', content={'blob': {'foo': None, 'bar': -1}}) + + self.assertEqual( + '{"foo": null, "bar": -1}', + ''.join([i for i in self.call('GET', document='testdocument', guid=guid, prop='blob')])) + + self.call('PUT', document='testdocument', guid=guid, prop='blob', content=0) + self.assertEqual( + '0', + ''.join([i for i in self.call('GET', document='testdocument', guid=guid, prop='blob')])) + + self.call('PUT', document='testdocument', guid=guid, prop='blob', content=None) + self.assertEqual( + 'null', + ''.join([i for i in self.call('GET', document='testdocument', guid=guid, prop='blob')])) + def test_CommandsGetBlobDirectory(self): class TestDocument(Document): @@ -850,34 +909,47 @@ class VolumeTest(tests.Test): return '_%s' % value @active_property(BlobProperty) - def blob(self, meta): + def blob1(self, meta): return meta - @blob.setter - def blob(self, value): + @blob1.setter + def blob1(self, value): return ad.PropertyMeta(url=value) + @active_property(BlobProperty) + def blob2(self, meta): + return meta + + @blob2.setter + def blob2(self, value): + return ' %s ' % value + self.volume = SingleVolume(tests.tmpdir, [TestDocument]) guid = self.call('POST', document='testdocument', content={}) self.assertEqual('1', self.call('GET', document='testdocument', guid=guid, prop='prop')) - self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob') + self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob1') self.call('PUT', document='testdocument', guid=guid, prop='prop', content='2') self.assertEqual('_2', self.call('GET', document='testdocument', guid=guid, prop='prop')) - self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob') + self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob1') self.call('PUT', document='testdocument', guid=guid, content={'prop': 3}) self.assertEqual('_3', self.call('GET', document='testdocument', guid=guid, prop='prop')) - self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob') + self.assertRaises(NotFound, self.call, 'GET', document='testdocument', guid=guid, prop='blob1') - self.call('PUT', document='testdocument', guid=guid, prop='blob', content='blob2') + self.call('PUT', document='testdocument', guid=guid, prop='blob1', content='blob2') try: - self.call('GET', document='testdocument', guid=guid, prop='blob') + self.call('GET', document='testdocument', guid=guid, prop='blob1') assert False except Redirect, redirect: self.assertEqual('blob2', redirect.location) + guid = self.call('POST', document='testdocument', content={'blob2': 'foo'}) + self.assertEqual(' foo ', ''.join(self.call('GET', document='testdocument', guid=guid, prop='blob2'))) + self.call('PUT', document='testdocument', guid=guid, prop='blob2', content='bar') + self.assertEqual(' bar ', ''.join(self.call('GET', document='testdocument', guid=guid, prop='blob2'))) + def call(self, method, document=None, guid=None, prop=None, accept_language=None, **kwargs): |