Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAleksey Lim <alsroot@sugarlabs.org>2012-09-25 04:01:07 (GMT)
committer Aleksey Lim <alsroot@sugarlabs.org>2012-09-25 04:01:07 (GMT)
commit40b9b03232f665d93e42bb72b9c93048413ea075 (patch)
tree02a843223781418070488f9a7e9e262841f16587
parent5262575cb4acdfb931a5f658f9a047a14b176a47 (diff)
Decode json blobs before setting
-rw-r--r--active_document/volume.py10
-rwxr-xr-xtests/units/volume.py88
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):