diff options
Diffstat (limited to 'tests/units/db/routes.py')
-rwxr-xr-x | tests/units/db/routes.py | 1628 |
1 files changed, 919 insertions, 709 deletions
diff --git a/tests/units/db/routes.py b/tests/units/db/routes.py index 5908d0f..8824ca8 100755 --- a/tests/units/db/routes.py +++ b/tests/units/db/routes.py @@ -16,10 +16,11 @@ src_root = abspath(dirname(__file__)) from __init__ import tests from sugar_network import db, toolkit -from sugar_network.db.routes import _typecast_prop_value -from sugar_network.db.metadata import Property -from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, Blob, ACL -from sugar_network.toolkit import coroutine, http +from sugar_network.db import files +from sugar_network.model.user import User +from sugar_network.toolkit.router import Router, Request, Response, fallbackroute, ACL +from sugar_network.toolkit.coroutine import this +from sugar_network.toolkit import coroutine, http, i18n class RoutesTest(tests.Test): @@ -36,18 +37,19 @@ class RoutesTest(tests.Test): def wo_default(self, value): return value - @db.indexed_property(slot=1, default='not_stored_default') + @db.stored_property(default='not_stored_default') def not_stored_default(self, value): return value - self.volume = db.Volume(tests.tmpdir, [Document], lambda event: None) + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) - self.assertRaises(RuntimeError, self.call, 'POST', ['document'], content={}) + self.assertRaises(RuntimeError, this.call, method='POST', path=['document'], content={}) - guid = self.call('POST', ['document'], content={'wo_default': 'wo_default'}) - self.assertEqual('default', self.call('GET', ['document', guid, 'w_default'])) - self.assertEqual('wo_default', self.call('GET', ['document', guid, 'wo_default'])) - self.assertEqual('not_stored_default', self.call('GET', ['document', guid, 'not_stored_default'])) + guid = this.call(method='POST', path=['document'], content={'wo_default': 'wo_default'}) + self.assertEqual('default', this.call(method='GET', path=['document', guid, 'w_default'])) + self.assertEqual('wo_default', this.call(method='GET', path=['document', guid, 'wo_default'])) + self.assertEqual('not_stored_default', this.call(method='GET', path=['document', guid, 'not_stored_default'])) def test_Populate(self): self.touch( @@ -65,10 +67,10 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - with db.Volume(tests.tmpdir, [Document], lambda event: None) as volume: - for cls in volume.values(): - for __ in cls.populate(): - pass + with db.Volume(tests.tmpdir, [Document]) as volume: + router = Router(db.Routes(volume)) + for __ in volume['document'].populate(): + pass self.assertEqual( sorted(['1', '2']), sorted([i.guid for i in volume['document'].find()[0]])) @@ -78,10 +80,10 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - with db.Volume(tests.tmpdir, [Document], lambda event: None) as volume: - for cls in volume.values(): - for __ in cls.populate(): - pass + with db.Volume(tests.tmpdir, [Document]) as volume: + router = Router(db.Routes(volume)) + for __ in volume['document'].populate(): + pass self.assertEqual( sorted(['1', '2']), sorted([i.guid for i in volume['document'].find()[0]])) @@ -94,12 +96,14 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - self.volume['testdocument'].create({'guid': 'guid'}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + volume['testdocument'].create({'guid': 'guid'}) self.assertEqual({ 'total': 1, @@ -107,11 +111,11 @@ class RoutesTest(tests.Test): {'guid': 'guid', 'prop': ''}, ], }, - self.call('GET', path=['testdocument'], reply=['guid', 'prop'])) + this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])) - guid_1 = self.call('POST', path=['testdocument'], content={'prop': 'value_1'}) + guid_1 = this.call(method='POST', path=['testdocument'], content={'prop': 'value_1'}) assert guid_1 - guid_2 = self.call('POST', path=['testdocument'], content={'prop': 'value_2'}) + guid_2 = this.call(method='POST', path=['testdocument'], content={'prop': 'value_2'}) assert guid_2 self.assertEqual( @@ -120,9 +124,9 @@ class RoutesTest(tests.Test): {'guid': guid_1, 'prop': 'value_1'}, {'guid': guid_2, 'prop': 'value_2'}, ]), - sorted(self.call('GET', path=['testdocument'], reply=['guid', 'prop'])['result'])) + sorted(this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])['result'])) - self.call('PUT', path=['testdocument', guid_1], content={'prop': 'value_3'}) + this.call(method='PUT', path=['testdocument', guid_1], content={'prop': 'value_3'}) self.assertEqual( sorted([ @@ -130,240 +134,397 @@ class RoutesTest(tests.Test): {'guid': guid_1, 'prop': 'value_3'}, {'guid': guid_2, 'prop': 'value_2'}, ]), - sorted(self.call('GET', path=['testdocument'], reply=['guid', 'prop'])['result'])) + sorted(this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])['result'])) - self.call('DELETE', path=['testdocument', guid_2]) + this.call(method='DELETE', path=['testdocument', guid_2]) self.assertEqual( sorted([ {'guid': 'guid', 'prop': ''}, {'guid': guid_1, 'prop': 'value_3'}, ]), - sorted(self.call('GET', path=['testdocument'], reply=['guid', 'prop'])['result'])) + sorted(this.call(method='GET', path=['testdocument'], reply=['guid', 'prop'])['result'])) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid_2]) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid_2]) self.assertEqual( {'guid': guid_1, 'prop': 'value_3'}, - self.call('GET', path=['testdocument', guid_1], reply=['guid', 'prop'])) + this.call(method='GET', path=['testdocument', guid_1], reply=['guid', 'prop'])) self.assertEqual( 'value_3', - self.call('GET', path=['testdocument', guid_1, 'prop'])) + this.call(method='GET', path=['testdocument', guid_1, 'prop'])) def test_SetBLOBs(self): class TestDocument(db.Resource): - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.call('PUT', path=['testdocument', guid, 'blob'], content='blob1') - self.assertEqual('blob1', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read()) + guid = this.call(method='POST', path=['testdocument'], content={}) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) - self.call('PUT', path=['testdocument', guid, 'blob'], content_stream=StringIO('blob2')) - self.assertEqual('blob2', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read()) + this.call(method='PUT', path=['testdocument', guid, 'blob'], content='blob1') + self.assertEqual('blob1', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read()) - self.call('PUT', path=['testdocument', guid, 'blob'], content=None) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob']) + this.call(method='PUT', path=['testdocument', guid, 'blob'], content_stream=StringIO('blob2')) + self.assertEqual('blob2', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read()) - def test_SetBLOBsByMeta(self): + this.call(method='PUT', path=['testdocument', guid, 'blob'], content=None) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) + + def test_CreateBLOBsWithMeta(self): class TestDocument(db.Resource): - @db.blob_property(mime_type='default') + @db.stored_property(db.Blob) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={}) - self.assertRaises(RuntimeError, self.call, 'PUT', path=['testdocument', guid, 'blob'], + self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'], content={}, content_type='application/json') - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob']) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) + + self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'], + content={'url': 'foo'}, content_type='application/json') + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) + + this.call(method='PUT', path=['testdocument', guid, 'blob'], + content={'url': 'url', 'digest': 'digest', 'foo': 'bar'}, content_type='application/json') + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'url': 'url', + 'foo': 'bar', + }, + this.call(method='GET', path=['testdocument', guid, 'blob'])) + + def test_UpdateUrlBLOBsWithMeta(self): + + class TestDocument(db.Resource): + + @db.stored_property(db.Blob) + def blob(self, value): + return value + + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + guid = this.call(method='POST', path=['testdocument'], content={'blob': {'digest': 'digest', 'url': 'url'}}) + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'url': 'url', + }, + this.call(method='GET', path=['testdocument', guid, 'blob'])) + + self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'], + content={'digest': 'fake'}, content_type='application/json') + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'url': 'url', + }, + this.call(method='GET', path=['testdocument', guid, 'blob'])) + + this.call(method='PUT', path=['testdocument', guid, 'blob'], + content={'foo': 'bar'}, content_type='application/json') + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'url': 'url', + 'foo': 'bar', + }, + this.call(method='GET', path=['testdocument', guid, 'blob'])) + + def test_UpdateFileBLOBsWithMeta(self): + + class TestDocument(db.Resource): + + @db.stored_property(db.Blob) + def blob(self, value): + return value + + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob'}) + blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'}) + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'size': os.stat(blob.path).st_size, + 'mtime': int(os.stat(blob.path).st_mtime), + 'url': 'http://localhost/blobs/%s' % hash('blob'), + 'digest': str(hash('blob')), + }, + blob) + self.assertEqual('blob', file(blob.path).read()) + + self.assertRaises(http.BadRequest, this.call, method='PUT', path=['testdocument', guid, 'blob'], + content={'digest': 'fake'}, content_type='application/json') + blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'}) + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'size': os.stat(blob.path).st_size, + 'mtime': int(os.stat(blob.path).st_mtime), + 'digest': str(hash('blob')), + 'url': 'http://localhost/blobs/%s' % hash('blob'), + }, + blob) + self.assertEqual('blob', file(blob.path).read()) + + this.call(method='PUT', path=['testdocument', guid, 'blob'], + content={'foo': 'bar'}, content_type='application/json') + blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'}) + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'size': os.stat(blob.path).st_size, + 'mtime': int(os.stat(blob.path).st_mtime), + 'digest': str(hash('blob')), + 'url': 'http://localhost/blobs/%s' % hash('blob'), + 'foo': 'bar', + }, + blob) + self.assertEqual('blob', file(blob.path).read()) + + def test_SwitchBLOBsType(self): + + class TestDocument(db.Resource): + + @db.stored_property(db.Blob) + def blob(self, value): + return value + + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.call('PUT', path=['testdocument', guid, 'blob'], - content={'url': 'foo', 'bar': 'probe'}, content_type='application/json') - blob = self.call('GET', path=['testdocument', guid, 'blob']) - self.assertEqual('foo', blob['url']) + guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob'}) + this.call(method='PUT', path=['testdocument', guid, 'blob'], + content={'foo': 'bar'}, content_type='application/json') + + file_blob = this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'}) + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'size': os.stat(file_blob.path).st_size, + 'mtime': int(os.stat(file_blob.path).st_mtime), + 'digest': str(hash('blob')), + 'url': 'http://localhost/blobs/%s' % hash('blob'), + 'foo': 'bar', + }, file_blob) + self.assertEqual('blob', file(file_blob.path).read()) + + this.call(method='PUT', path=['testdocument', guid, 'blob'], + content={'url': 'url'}, content_type='application/json') + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'url': 'url', + 'foo': 'bar', + }, this.call(method='GET', path=['testdocument', guid, 'blob'])) + assert not exists(file_blob.path) + + this.call(method='PUT', path=['testdocument', guid, 'blob'], + content='blob', content_type='application/octet-stream', environ={'HTTP_HOST': 'localhost'}) + self.assertEqual({ + 'mime_type': 'application/octet-stream', + 'size': os.stat(file_blob.path).st_size, + 'mtime': int(os.stat(file_blob.path).st_mtime), + 'digest': str(hash('blob')), + 'url': 'http://localhost/blobs/%s' % hash('blob'), + }, this.call(method='GET', path=['testdocument', guid, 'blob'], environ={'HTTP_HOST': 'localhost'})) + self.assertEqual('blob', file(file_blob.path).read()) def test_RemoveBLOBs(self): class TestDocument(db.Resource): - @db.blob_property(mime_type='default') + @db.stored_property(db.Blob) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={'blob': 'blob'}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob'}) - self.assertEqual('blob', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read()) + self.assertEqual('blob', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read()) - self.call('PUT', path=['testdocument', guid, 'blob']) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob']) + this.call(method='PUT', path=['testdocument', guid, 'blob']) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) - def test_RemoveTempBLOBFilesOnFails(self): + def test_ReuploadBLOBs(self): class TestDocument(db.Resource): - @db.blob_property(mime_type='default') + @db.stored_property(db.Blob) + def blob(self, value): + return value + + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={'blob': 'blob1'}) + + blob1 = this.call(method='GET', path=['testdocument', guid, 'blob']) + self.assertEqual('blob1', file(blob1.path).read()) + + this.call(method='PUT', path=['testdocument', guid, 'blob'], content='blob2') + blob2 = this.call(method='GET', path=['testdocument', guid, 'blob']) + self.assertEqual('blob2', file(blob2.path).read()) + assert blob1.path != blob2.path + assert not exists(blob1.path) + + def test_RemoveBLOBsOnFailedSetter(self): + + class TestDocument(db.Resource): + + @db.stored_property(db.Blob) def blob(self, value): return value @blob.setter def blob(self, value): - raise RuntimeError() + if value: + raise RuntimeError() + return value + + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + guid = this.call(method='POST', path=['testdocument'], content={}) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) - self.assertRaises(RuntimeError, self.call, 'PUT', path=['testdocument', guid, 'blob'], content='probe') - self.assertEqual(0, len(os.listdir('tmp'))) + self.assertRaises(RuntimeError, this.call, method='PUT', path=['testdocument', guid, 'blob'], content='probe') + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) + assert not exists('blobs/%s' % hash('probe')) def test_SetBLOBsWithMimeType(self): class TestDocument(db.Resource): - @db.blob_property(mime_type='default') + @db.stored_property(db.Blob, mime_type='default') def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={}) - self.call('PUT', path=['testdocument', guid, 'blob'], content='blob1') - self.assertEqual('default', self.call('GET', path=['testdocument', guid, 'blob'])['mime_type']) - self.assertEqual('default', self.response.content_type) + response = Response() + this.call(response=response, + method='PUT', path=['testdocument', guid, 'blob'], content='blob1') + response = Response() + self.assertEqual('default', this.call(response=response, + method='GET', path=['testdocument', guid, 'blob'])['mime_type']) + self.assertEqual('default', response.content_type) - self.call('PUT', path=['testdocument', guid, 'blob'], content='blob1', content_type='foo') - self.assertEqual('foo', self.call('GET', path=['testdocument', guid, 'blob'])['mime_type']) - self.assertEqual('foo', self.response.content_type) + response = Response() + this.call(response=response, + method='PUT', path=['testdocument', guid, 'blob'], content='blob1', content_type='foo') + response = Response() + self.assertEqual('foo', this.call(response=response, + method='GET', path=['testdocument', guid, 'blob'])['mime_type']) + self.assertEqual('foo', response.content_type) def test_GetBLOBs(self): class TestDocument(db.Resource): - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + guid = this.call(method='POST', path=['testdocument'], content={}) blob = 'blob' - self.call('PUT', path=['testdocument', guid, 'blob'], content=blob) - - blob_path = tests.tmpdir + '/testdocument/%s/%s/blob' % (guid[:2], guid) - blob_meta = { - 'seqno': 2, - 'blob': blob_path + '.blob', - 'blob_size': len(blob), - 'digest': hashlib.sha1(blob).hexdigest(), - 'mime_type': 'application/octet-stream', - 'mtime': int(os.stat(blob_path).st_mtime), - } + this.call(method='PUT', path=['testdocument', guid, 'blob'], content=blob) + digest = str(hash(blob)) + blob_path = 'blobs/%s' % digest - self.assertEqual('blob', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read()) + self.assertEqual('blob', file(this.call(method='GET', path=['testdocument', guid, 'blob']).path).read()) self.assertEqual({ 'blob': { - 'url': 'http://localhost/testdocument/%s/blob' % guid, - 'blob_size': len(blob), - 'digest': hashlib.sha1(blob).hexdigest(), 'mime_type': u'application/octet-stream', + 'url': 'http://localhost/blobs/%s' % digest, + 'size': len(blob), + 'digest': digest, + 'mtime': int(os.stat(blob_path).st_mtime), }, }, - self.call('GET', path=['testdocument', guid], reply=['blob'], host='localhost')) + this.call(method='GET', path=['testdocument', guid], reply=['blob'], environ={'HTTP_HOST': 'localhost'})) self.assertEqual([{ 'blob': { - 'url': 'http://localhost/testdocument/%s/blob' % guid, - 'blob_size': len(blob), - 'digest': hashlib.sha1(blob).hexdigest(), 'mime_type': u'application/octet-stream', + 'url': 'http://localhost/blobs/%s' % digest, + 'size': len(blob), + 'digest': digest, + 'mtime': int(os.stat(blob_path).st_mtime), }, }], - self.call('GET', path=['testdocument'], reply=['blob'], host='localhost')['result']) + this.call(method='GET', path=['testdocument'], reply=['blob'], environ={'HTTP_HOST': 'localhost'})['result']) def test_GetBLOBsByUrls(self): class TestDocument(db.Resource): - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid1 = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid1 = this.call(method='POST', path=['testdocument'], content={}) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid1, 'blob']) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid1, 'blob']) self.assertEqual( - {'blob': {'url': 'http://127.0.0.1/testdocument/%s/blob' % guid1}}, - self.call('GET', path=['testdocument', guid1], reply=['blob'], host='127.0.0.1')) + {'blob': {}}, + this.call(method='GET', path=['testdocument', guid1], reply=['blob'], environ={'HTTP_HOST': '127.0.0.1'})) blob = 'file' - guid2 = self.call('POST', path=['testdocument'], content={'blob': blob}) - self.assertEqual('file', file(self.call('GET', path=['testdocument', guid2, 'blob'])['blob']).read()) - self.assertEqual({ - 'blob': { - 'url': 'http://127.0.0.1/testdocument/%s/blob' % guid2, - 'blob_size': len(blob), - 'digest': hashlib.sha1(blob).hexdigest(), - 'mime_type': u'application/octet-stream', - }, - }, - self.call('GET', path=['testdocument', guid2], reply=['blob'], host='127.0.0.1')) + guid2 = this.call(method='POST', path=['testdocument'], content={'blob': blob}) + self.assertEqual( + 'http://127.0.0.1/blobs/%s' % hash(blob), + this.call(method='GET', path=['testdocument', guid2], reply=['blob'], environ={'HTTP_HOST': '127.0.0.1'})['blob']['url']) - guid3 = self.call('POST', path=['testdocument'], content={'blob': {'url': 'http://foo'}}, content_type='application/json') - self.assertEqual('http://foo', self.call('GET', path=['testdocument', guid3, 'blob'])['url']) - self.assertEqual({ - 'blob': { - 'url': 'http://foo', - }, - }, - self.call('GET', path=['testdocument', guid3], reply=['blob'], host='127.0.0.1')) + guid3 = this.call(method='POST', path=['testdocument'], content={'blob': {'url': 'http://foo', 'digest': 'digest'}}, content_type='application/json') + self.assertEqual( + 'http://foo', + this.call(method='GET', path=['testdocument', guid3, 'blob'])['url']) + self.assertEqual( + 'http://foo', + this.call(method='GET', path=['testdocument', guid3], reply=['blob'], environ={'HTTP_HOST': '127.0.0.1'})['blob']['url']) self.assertEqual( sorted([ - {'blob': { - 'url': 'http://127.0.0.1/testdocument/%s/blob' % guid1, - }}, - { 'blob': { - 'url': 'http://127.0.0.1/testdocument/%s/blob' % guid2, - 'blob_size': len(blob), - 'digest': hashlib.sha1(blob).hexdigest(), - 'mime_type': u'application/octet-stream', - }}, - { 'blob': { - 'url': 'http://foo', - }}, + None, + 'http://127.0.0.1/blobs/%s' % hash(blob), + 'http://foo', ]), - sorted(self.call('GET', path=['testdocument'], reply=['blob'], host='127.0.0.1')['result'])) + sorted([i['blob'].get('url') for i in this.call(method='GET', path=['testdocument'], reply=['blob'], + environ={'HTTP_HOST': '127.0.0.1'})['result']])) def test_CommandsGetAbsentBlobs(self): class TestDocument(db.Resource): - @db.indexed_property(slot=1, default='') - def prop(self, value): - return value - - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - guid = self.call('POST', path=['testdocument'], content={'prop': 'value'}) - self.assertEqual('value', self.call('GET', path=['testdocument', guid, 'prop'])) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob']) + guid = this.call(method='POST', path=['testdocument'], content={}) + self.assertRaises(http.NotFound, this.call, method='GET', path=['testdocument', guid, 'blob']) self.assertEqual( - {'blob': {'url': 'http://localhost/testdocument/%s/blob' % guid}}, - self.call('GET', path=['testdocument', guid], reply=['blob'], host='localhost')) + {'blob': {}}, + this.call(method='GET', path=['testdocument', guid], reply=['blob'], environ={'HTTP_HOST': 'localhost'})) def test_Command_ReplyForGET(self): @@ -373,44 +534,46 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={'prop': 'value'}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={'prop': 'value'}) self.assertEqual( ['guid', 'prop'], - self.call('GET', path=['testdocument', guid], reply=['guid', 'prop']).keys()) + this.call(method='GET', path=['testdocument', guid], reply=['guid', 'prop']).keys()) self.assertEqual( ['guid'], - self.call('GET', path=['testdocument'])['result'][0].keys()) + this.call(method='GET', path=['testdocument'])['result'][0].keys()) self.assertEqual( sorted(['guid', 'prop']), - sorted(self.call('GET', path=['testdocument'], reply=['prop', 'guid'])['result'][0].keys())) + sorted(this.call(method='GET', path=['testdocument'], reply=['prop', 'guid'])['result'][0].keys())) self.assertEqual( sorted(['prop']), - sorted(self.call('GET', path=['testdocument'], reply=['prop'])['result'][0].keys())) + sorted(this.call(method='GET', path=['testdocument'], reply=['prop'])['result'][0].keys())) def test_DecodeBeforeSetting(self): class TestDocument(db.Resource): - @db.indexed_property(slot=1, typecast=int) + @db.indexed_property(db.Numeric, slot=1) def prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - guid = self.call('POST', path=['testdocument'], content={'prop': '-1'}) - self.assertEqual(-1, self.call('GET', path=['testdocument', guid, 'prop'])) + guid = this.call(method='POST', path=['testdocument'], content={'prop': '-1'}) + self.assertEqual(-1, this.call(method='GET', path=['testdocument', guid, 'prop'])) def test_LocalizedSet(self): - toolkit._default_langs = ['en'] + i18n._default_langs = ['en'] class TestDocument(db.Resource): @@ -418,32 +581,23 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - directory = self.volume['testdocument'] - - guid = directory.create({'localized_prop': 'value_raw'}) - self.assertEqual({'en': 'value_raw'}, directory.get(guid)['localized_prop']) - self.assertEqual( - [guid], - [i.guid for i in directory.find(localized_prop='value_raw')[0]]) - - directory.update(guid, {'localized_prop': 'value_raw2'}) - self.assertEqual({'en': 'value_raw2'}, directory.get(guid)['localized_prop']) - self.assertEqual( - [guid], - [i.guid for i in directory.find(localized_prop='value_raw2')[0]]) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + directory = volume['testdocument'] + guid = this.call(method='POST', path=['testdocument'], content={'localized_prop': 'value_ru'}, + environ={'HTTP_ACCEPT_LANGUAGE': 'ru'}) - guid = self.call('POST', path=['testdocument'], accept_language=['ru'], content={'localized_prop': 'value_ru'}) self.assertEqual({'ru': 'value_ru'}, directory.get(guid)['localized_prop']) self.assertEqual( [guid], [i.guid for i in directory.find(localized_prop='value_ru')[0]]) - self.call('PUT', path=['testdocument', guid], accept_language=['en'], content={'localized_prop': 'value_en'}) + this.call(method='PUT', path=['testdocument', guid], content={'localized_prop': 'value_en'}, + environ={'HTTP_ACCEPT_LANGUAGE': 'en'}) self.assertEqual({'ru': 'value_ru', 'en': 'value_en'}, directory.get(guid)['localized_prop']) self.assertEqual( [guid], @@ -460,14 +614,15 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - directory = self.volume['testdocument'] + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + directory = volume['testdocument'] - guid = self.call('POST', path=['testdocument'], content={ + guid = this.call(method='POST', path=['testdocument'], content={ 'localized_prop': { 'ru': 'value_ru', 'es': 'value_es', @@ -475,63 +630,78 @@ class RoutesTest(tests.Test): }, }) - toolkit._default_langs = ['en'] + i18n._default_langs = ['en'] self.assertEqual( {'localized_prop': 'value_en'}, - self.call('GET', path=['testdocument', guid], reply=['localized_prop'])) + this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'])) self.assertEqual( {'localized_prop': 'value_ru'}, - self.call('GET', path=['testdocument', guid], accept_language=['ru'], reply=['localized_prop'])) + this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'ru'})) self.assertEqual( 'value_ru', - self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['ru', 'es'])) + this.call(method='GET', path=['testdocument', guid, 'localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'ru,es'})) self.assertEqual( [{'localized_prop': 'value_ru'}], - self.call('GET', path=['testdocument'], accept_language=['foo', 'ru', 'es'], reply=['localized_prop'])['result']) + this.call(method='GET', path=['testdocument'], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'foo,ru,es'})['result']) self.assertEqual( {'localized_prop': 'value_ru'}, - self.call('GET', path=['testdocument', guid], accept_language=['ru-RU'], reply=['localized_prop'])) + this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'ru-RU'})) self.assertEqual( 'value_ru', - self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['ru-RU', 'es'])) + this.call(method='GET', path=['testdocument', guid, 'localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'ru-RU,es'})) self.assertEqual( [{'localized_prop': 'value_ru'}], - self.call('GET', path=['testdocument'], accept_language=['foo', 'ru-RU', 'es'], reply=['localized_prop'])['result']) + this.call(method='GET', path=['testdocument'], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'ru-RU,es'})['result']) self.assertEqual( {'localized_prop': 'value_es'}, - self.call('GET', path=['testdocument', guid], accept_language=['es'], reply=['localized_prop'])) + this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'es'})) self.assertEqual( 'value_es', - self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['es', 'ru'])) + this.call(method='GET', path=['testdocument', guid, 'localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'es,ru'})) self.assertEqual( [{'localized_prop': 'value_es'}], - self.call('GET', path=['testdocument'], accept_language=['foo', 'es', 'ru'], reply=['localized_prop'])['result']) + this.call(method='GET', path=['testdocument'], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'foo,es,ru'})['result']) self.assertEqual( {'localized_prop': 'value_en'}, - self.call('GET', path=['testdocument', guid], accept_language=['fr'], reply=['localized_prop'])) + this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'fr'})) self.assertEqual( 'value_en', - self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['fr', 'za'])) + this.call(method='GET', path=['testdocument', guid, 'localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'fr,za'})) self.assertEqual( [{'localized_prop': 'value_en'}], - self.call('GET', path=['testdocument'], accept_language=['foo', 'fr', 'za'], reply=['localized_prop'])['result']) + this.call(method='GET', path=['testdocument'], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'foo,fr,za'})['result']) - toolkit._default_langs = ['foo'] + i18n._default_langs = ['foo'] fallback_lang = sorted(['ru', 'es', 'en'])[0] self.assertEqual( {'localized_prop': 'value_%s' % fallback_lang}, - self.call('GET', path=['testdocument', guid], accept_language=['fr'], reply=['localized_prop'])) + this.call(method='GET', path=['testdocument', guid], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'fr'})) self.assertEqual( 'value_%s' % fallback_lang, - self.call('GET', path=['testdocument', guid, 'localized_prop'], accept_language=['fr', 'za'])) + this.call(method='GET', path=['testdocument', guid, 'localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'fr,za'})) self.assertEqual( [{'localized_prop': 'value_%s' % fallback_lang}], - self.call('GET', path=['testdocument'], accept_language=['foo', 'fr', 'za'], reply=['localized_prop'])['result']) + this.call(method='GET', path=['testdocument'], reply=['localized_prop'], + environ={'HTTP_ACCEPT_LANGUAGE': 'foo,fr,za'})['result']) def test_OpenByModuleName(self): self.touch( @@ -543,9 +713,9 @@ class RoutesTest(tests.Test): ) sys.path.insert(0, '.') - volume = db.Volume('.', ['foo.bar'], lambda event: None) - assert exists('bar/index') + volume = db.Volume('.', ['foo.bar']) volume['bar'].find() + assert exists('bar/index') volume.close() def test_Command_GetBlobSetByUrl(self): @@ -556,21 +726,25 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) - self.call('PUT', path=['testdocument', guid, 'blob'], url='http://sugarlabs.org') + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={}) + this.call(method='PUT', path=['testdocument', guid, 'blob'], content={ + 'digest': 'digest', + 'url': 'http://sugarlabs.org', + }, content_type='application/json') self.assertEqual( 'http://sugarlabs.org', - self.call('GET', path=['testdocument', guid, 'blob'])['url']) + this.call(method='GET', path=['testdocument', guid, 'blob'])['url']) def test_on_create(self): @@ -580,24 +754,25 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) ts = int(time.time()) - guid = self.call('POST', path=['testdocument'], content={}) - assert self.volume['testdocument'].get(guid)['ctime'] in range(ts - 1, ts + 1) - assert self.volume['testdocument'].get(guid)['mtime'] in range(ts - 1, ts + 1) + guid = this.call(method='POST', path=['testdocument'], content={}) + assert volume['testdocument'].get(guid)['ctime'] in range(ts - 1, ts + 1) + assert volume['testdocument'].get(guid)['mtime'] in range(ts - 1, ts + 1) def test_on_create_Override(self): class Routes(db.Routes): - def on_create(self, request, props, event): + def on_create(self, request, props): props['prop'] = 'overriden' - db.Routes.on_create(self, request, props, event) + db.Routes.on_create(self, request, props) class TestDocument(db.Resource): @@ -605,17 +780,18 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(Routes(volume)) - guid = self.call('POST', ['testdocument'], content={'prop': 'foo'}, routes=Routes) - self.assertEqual('overriden', self.volume['testdocument'].get(guid)['prop']) + guid = this.call(method='POST', path=['testdocument'], content={'prop': 'foo'}, routes=Routes) + self.assertEqual('overriden', volume['testdocument'].get(guid)['prop']) - self.call('PUT', ['testdocument', guid], content={'prop': 'bar'}, routes=Routes) - self.assertEqual('bar', self.volume['testdocument'].get(guid)['prop']) + this.call(method='PUT', path=['testdocument', guid], content={'prop': 'bar'}, routes=Routes) + self.assertEqual('bar', volume['testdocument'].get(guid)['prop']) def test_on_update(self): @@ -625,26 +801,28 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) - prev_mtime = self.volume['testdocument'].get(guid)['mtime'] + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + guid = this.call(method='POST', path=['testdocument'], content={}) + prev_mtime = volume['testdocument'].get(guid)['mtime'] time.sleep(1) - self.call('PUT', path=['testdocument', guid], content={'prop': 'probe'}) - assert self.volume['testdocument'].get(guid)['mtime'] - prev_mtime >= 1 + this.call(method='PUT', path=['testdocument', guid], content={'prop': 'probe'}) + assert volume['testdocument'].get(guid)['mtime'] - prev_mtime >= 1 def test_on_update_Override(self): class Routes(db.Routes): - def on_update(self, request, props, event): + def on_update(self, request, props): props['prop'] = 'overriden' - db.Routes.on_update(self, request, props, event) + db.Routes.on_update(self, request, props) class TestDocument(db.Resource): @@ -652,17 +830,18 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(Routes(volume)) - guid = self.call('POST', ['testdocument'], content={'prop': 'foo'}, routes=Routes) - self.assertEqual('foo', self.volume['testdocument'].get(guid)['prop']) + guid = this.call(method='POST', path=['testdocument'], content={'prop': 'foo'}, routes=Routes) + self.assertEqual('foo', volume['testdocument'].get(guid)['prop']) - self.call('PUT', ['testdocument', guid], content={'prop': 'bar'}, routes=Routes) - self.assertEqual('overriden', self.volume['testdocument'].get(guid)['prop']) + this.call(method='PUT', path=['testdocument', guid], content={'prop': 'bar'}, routes=Routes) + self.assertEqual('overriden', volume['testdocument'].get(guid)['prop']) def __test_DoNotPassGuidsForCreate(self): @@ -672,13 +851,15 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.indexed_property(prefix='L', localized=True, default='') + @db.indexed_property(db.Localized, prefix='L', default={}) def localized_prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - self.assertRaises(http.Forbidden, self.call, 'POST', path=['testdocument'], content={'guid': 'foo'}) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + self.assertRaises(http.Forbidden, this.call, method='POST', path=['testdocument'], content={'guid': 'foo'}) + guid = this.call(method='POST', path=['testdocument'], content={}) assert guid def test_seqno(self): @@ -689,7 +870,8 @@ class RoutesTest(tests.Test): class Document2(db.Resource): pass - volume = db.Volume(tests.tmpdir, [Document1, Document2], lambda event: None) + volume = db.Volume(tests.tmpdir, [Document1, Document2]) + router = Router(db.Routes(volume)) assert not exists('seqno') self.assertEqual(0, volume.seqno.value) @@ -706,8 +888,8 @@ class RoutesTest(tests.Test): self.assertEqual(4, volume.seqno.value) assert not exists('seqno') volume.seqno.commit() - assert exists('seqno') - volume = db.Volume(tests.tmpdir, [Document1, Document2], lambda event: None) + assert exists('db.seqno') + volume = db.Volume(tests.tmpdir, [Document1, Document2]) self.assertEqual(4, volume.seqno.value) def test_Events(self): @@ -726,7 +908,7 @@ class RoutesTest(tests.Test): def prop(self, value): pass - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, value): return value @@ -739,13 +921,15 @@ class RoutesTest(tests.Test): ) events = [] - volume = db.Volume(tests.tmpdir, [Document1, Document2], lambda event: events.append(event)) + this.broadcast = lambda x: events.append(x) + volume = db.Volume(tests.tmpdir, [Document1, Document2]) + volume['document1'] + volume['document2'] coroutine.sleep(.1) mtime = int(os.stat('document1/index/mtime').st_mtime) self.assertEqual([ {'event': 'commit', 'resource': 'document1', 'mtime': mtime}, - {'event': 'populate', 'resource': 'document1', 'mtime': mtime}, ], events) del events[:] @@ -794,43 +978,45 @@ class RoutesTest(tests.Test): def prop(self, value): pass - @db.blob_property(acl=ACL.READ) + @db.stored_property(db.Blob, acl=ACL.READ) def blob(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={}) - self.assertRaises(http.Forbidden, self.call, 'POST', path=['testdocument'], content={'prop': 'value'}) - self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid], content={'prop': 'value'}) - self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid], content={'blob': 'value'}) - self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid, 'prop'], content='value') - self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid, 'blob'], content='value') + self.assertRaises(http.Forbidden, this.call, method='POST', path=['testdocument'], content={'prop': 'value'}) + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid], content={'prop': 'value'}) + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid], content={'blob': 'value'}) + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid, 'prop'], content='value') + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid, 'blob'], content='value') def test_BlobsWritePermissions(self): class TestDocument(db.Resource): - @db.blob_property(acl=ACL.CREATE | ACL.WRITE) + @db.stored_property(db.Blob, acl=ACL.CREATE | ACL.WRITE) def blob1(self, value): return value - @db.blob_property(acl=ACL.CREATE) + @db.stored_property(db.Blob, acl=ACL.CREATE) def blob2(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - guid = self.call('POST', path=['testdocument'], content={}) - self.call('PUT', path=['testdocument', guid], content={'blob1': 'value1', 'blob2': 'value2'}) - self.call('PUT', path=['testdocument', guid], content={'blob1': 'value1'}) - self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid], content={'blob2': 'value2_'}) + guid = this.call(method='POST', path=['testdocument'], content={}) + this.call(method='PUT', path=['testdocument', guid], content={'blob1': 'value1', 'blob2': 'value2'}) + this.call(method='PUT', path=['testdocument', guid], content={'blob1': 'value1'}) + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid], content={'blob2': 'value2_'}) - guid = self.call('POST', path=['testdocument'], content={}) - self.call('PUT', path=['testdocument', guid, 'blob1'], content='value1') - self.call('PUT', path=['testdocument', guid, 'blob2'], content='value2') - self.call('PUT', path=['testdocument', guid, 'blob1'], content='value1_') - self.assertRaises(http.Forbidden, self.call, 'PUT', path=['testdocument', guid, 'blob2'], content='value2_') + guid = this.call(method='POST', path=['testdocument'], content={}) + this.call(method='PUT', path=['testdocument', guid, 'blob1'], content='value1') + this.call(method='PUT', path=['testdocument', guid, 'blob2'], content='value2') + this.call(method='PUT', path=['testdocument', guid, 'blob1'], content='value1_') + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['testdocument', guid, 'blob2'], content='value2_') def test_properties_OverrideGet(self): @@ -844,30 +1030,32 @@ class RoutesTest(tests.Test): def prop2(self, value): return -1 - @db.blob_property() + @db.stored_property(db.Blob) def blob(self, meta): meta['blob'] = 'new-blob' return meta - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + guid = this.call(method='POST', path=['testdocument'], content={}) self.touch(('new-blob', 'new-blob')) - self.call('PUT', path=['testdocument', guid, 'blob'], content='old-blob') + this.call(method='PUT', path=['testdocument', guid, 'blob'], content='old-blob') self.assertEqual( 'new-blob', - self.call('GET', path=['testdocument', guid, 'blob'])['blob']) + this.call(method='GET', path=['testdocument', guid, 'blob'])['blob']) self.assertEqual( '1', - self.call('GET', path=['testdocument', guid, 'prop1'])) + this.call(method='GET', path=['testdocument', guid, 'prop1'])) self.assertEqual( -1, - self.call('GET', path=['testdocument', guid, 'prop2'])) + this.call(method='GET', path=['testdocument', guid, 'prop2'])) self.assertEqual( {'prop1': '1', 'prop2': -1}, - self.call('GET', path=['testdocument', guid], reply=['prop1', 'prop2'])) + this.call(method='GET', path=['testdocument', guid], reply=['prop1', 'prop2'])) - def test_properties_OverrideSet(self): + def test_properties_OverrideSetter(self): class TestDocument(db.Resource): @@ -879,53 +1067,47 @@ class RoutesTest(tests.Test): def prop(self, value): return '_%s' % value - @db.blob_property() - def blob1(self, meta): - return meta + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={}) - @blob1.setter - def blob1(self, value): - return Blob({'url': file(value['blob']).read()}) + self.assertEqual('_1', this.call(method='GET', path=['testdocument', guid, 'prop'])) - @db.blob_property() - def blob2(self, meta): - return meta + this.call(method='PUT', path=['testdocument', guid, 'prop'], content='2') + self.assertEqual('_2', this.call(method='GET', path=['testdocument', guid, 'prop'])) - @blob2.setter - def blob2(self, value): - with toolkit.NamedTemporaryFile(delete=False) as f: - f.write(' %s ' % file(value['blob']).read()) - value['blob'] = f.name - return value + this.call(method='PUT', path=['testdocument', guid], content={'prop': 3}) + self.assertEqual('_3', this.call(method='GET', path=['testdocument', guid, 'prop'])) - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={}) + def test_properties_AccessToOldValuesInSetters(self): + + class TestDocument(db.Resource): - self.assertEqual('_1', self.call('GET', path=['testdocument', guid, 'prop'])) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob1']) + @db.stored_property(db.Numeric) + def prop(self, value): + return value - self.call('PUT', path=['testdocument', guid, 'prop'], content='2') - self.assertEqual('_2', self.call('GET', path=['testdocument', guid, 'prop'])) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob1']) + @prop.setter + def prop(self, value): + return value + (self['prop'] or 0) - self.call('PUT', path=['testdocument', guid], content={'prop': 3}) - self.assertEqual('_3', self.call('GET', path=['testdocument', guid, 'prop'])) - self.assertRaises(http.NotFound, self.call, 'GET', path=['testdocument', guid, 'blob1']) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.call('PUT', path=['testdocument', guid, 'blob1'], content='blob_url') - self.assertEqual('blob_url', self.call('GET', path=['testdocument', guid, 'blob1'])['url']) + guid = this.call(method='POST', path=['testdocument'], content={'prop': 1}) + self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop'])) - guid = self.call('POST', path=['testdocument'], content={'blob2': 'foo'}) - self.assertEqual(' foo ', file(self.call('GET', path=['testdocument', guid, 'blob2'])['blob']).read()) + this.call(method='PUT', path=['testdocument', guid, 'prop'], content='2') + self.assertEqual(3, this.call(method='GET', path=['testdocument', guid, 'prop'])) - self.call('PUT', path=['testdocument', guid, 'blob2'], content='bar') - self.assertEqual(' bar ', file(self.call('GET', path=['testdocument', guid, 'blob2'])['blob']).read()) + this.call(method='PUT', path=['testdocument', guid], content={'prop': 3}) + self.assertEqual(6, this.call(method='GET', path=['testdocument', guid, 'prop'])) def test_properties_CallSettersAtTheEnd(self): class TestDocument(db.Resource): - @db.indexed_property(slot=1, typecast=int) + @db.indexed_property(db.Numeric, slot=1) def prop1(self, value): return value @@ -933,7 +1115,7 @@ class RoutesTest(tests.Test): def prop1(self, value): return self['prop3'] + value - @db.indexed_property(slot=2, typecast=int) + @db.indexed_property(db.Numeric, slot=2) def prop2(self, value): return value @@ -941,107 +1123,40 @@ class RoutesTest(tests.Test): def prop2(self, value): return self['prop3'] - value - @db.indexed_property(slot=3, typecast=int) + @db.indexed_property(db.Numeric, slot=3) def prop3(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={'prop1': 1, 'prop2': 2, 'prop3': 3}) - self.assertEqual(4, self.call('GET', path=['testdocument', guid, 'prop1'])) - self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop2'])) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + + guid = this.call(method='POST', path=['testdocument'], content={'prop1': 1, 'prop2': 2, 'prop3': 3}) + self.assertEqual(4, this.call(method='GET', path=['testdocument', guid, 'prop1'])) + self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop2'])) def test_properties_PopulateRequiredPropsInSetters(self): class TestDocument(db.Resource): - @db.indexed_property(slot=1, typecast=int) + @db.indexed_property(db.Numeric, slot=1) def prop1(self, value): return value @prop1.setter def prop1(self, value): - self['prop2'] = value + 1 + self.post('prop2', value + 1) return value - @db.indexed_property(slot=2, typecast=int) + @db.indexed_property(db.Numeric, slot=2) def prop2(self, value): return value - @db.blob_property() - def prop3(self, value): - return value - - @prop3.setter - def prop3(self, value): - self['prop1'] = -1 - self['prop2'] = -2 - return value - - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={'prop1': 1}) - self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop1'])) - self.assertEqual(2, self.call('GET', path=['testdocument', guid, 'prop2'])) - - def test_properties_PopulateRequiredPropsInBlobSetter(self): - - class TestDocument(db.Resource): - - @db.blob_property() - def blob(self, value): - return value - - @blob.setter - def blob(self, value): - self['prop1'] = 1 - self['prop2'] = 2 - return value - - @db.indexed_property(slot=1, typecast=int) - def prop1(self, value): - return value - - @db.indexed_property(slot=2, typecast=int) - def prop2(self, value): - return value - - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={'blob': ''}) - self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop1'])) - self.assertEqual(2, self.call('GET', path=['testdocument', guid, 'prop2'])) - - def __test_SubCall(self): - - class TestDocument(db.Resource): - - @db.blob_property(mime_type='application/json') - def blob(self, value): - return value - - @blob.setter - def blob(self, value): - blob = file(value['blob']).read() - if '!' not in blob: - meta = self.meta('blob') - if meta: - blob = file(meta['blob']).read() + blob - with toolkit.NamedTemporaryFile(delete=False) as f: - f.write(blob) - value['blob'] = f.name - coroutine.spawn(self.post, blob) - return value - - def post(self, value): - self.request.call('PUT', path=['testdocument', self.guid, 'blob'], content=value + '!') + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - - guid = self.call('POST', path=['testdocument'], content={'blob': '0'}) - coroutine.dispatch() - self.assertEqual('0!', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read()) - - self.call('PUT', path=['testdocument', guid, 'blob'], content='1') - coroutine.dispatch() - self.assertEqual('0!1!', file(self.call('GET', path=['testdocument', guid, 'blob'])['blob']).read()) + guid = this.call(method='POST', path=['testdocument'], content={'prop1': 1}) + self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop1'])) + self.assertEqual(2, this.call(method='GET', path=['testdocument', guid, 'prop2'])) def test_Group(self): @@ -1051,15 +1166,16 @@ class RoutesTest(tests.Test): def prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.call('POST', path=['testdocument'], content={'prop': 1}) - self.call('POST', path=['testdocument'], content={'prop': 2}) - self.call('POST', path=['testdocument'], content={'prop': 1}) + this.call(method='POST', path=['testdocument'], content={'prop': 1}) + this.call(method='POST', path=['testdocument'], content={'prop': 2}) + this.call(method='POST', path=['testdocument'], content={'prop': 1}) self.assertEqual( sorted([{'prop': 1}, {'prop': 2}]), - sorted(self.call('GET', path=['testdocument'], reply='prop', group_by='prop')['result'])) + sorted(this.call(method='GET', path=['testdocument'], reply='prop', group_by='prop')['result'])) def test_CallSetterEvenIfThereIsNoCreatePermissions(self): @@ -1073,12 +1189,13 @@ class RoutesTest(tests.Test): def prop(self, value): return value + 1 - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) - self.assertRaises(http.Forbidden, self.call, 'POST', path=['testdocument'], content={'prop': 1}) + self.assertRaises(http.Forbidden, this.call, method='POST', path=['testdocument'], content={'prop': 1}) - guid = self.call('POST', path=['testdocument'], content={}) - self.assertEqual(1, self.call('GET', path=['testdocument', guid, 'prop'])) + guid = this.call(method='POST', path=['testdocument'], content={}) + self.assertEqual(1, this.call(method='GET', path=['testdocument', guid, 'prop'])) def test_ReturnDefualtsForMissedProps(self): @@ -1088,57 +1205,34 @@ class RoutesTest(tests.Test): def prop(self, value): return value - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', path=['testdocument'], content={'prop': 'set'}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content={'prop': 'set'}) self.assertEqual( [{'prop': 'set'}], - self.call('GET', path=['testdocument'], reply='prop')['result']) + this.call(method='GET', path=['testdocument'], reply='prop')['result']) self.assertEqual( {'prop': 'set'}, - self.call('GET', path=['testdocument', guid], reply='prop')) + this.call(method='GET', path=['testdocument', guid], reply='prop')) self.assertEqual( 'set', - self.call('GET', path=['testdocument', guid, 'prop'])) + this.call(method='GET', path=['testdocument', guid, 'prop'])) os.unlink('testdocument/%s/%s/prop' % (guid[:2], guid)) self.assertEqual( [{'prop': 'default'}], - self.call('GET', path=['testdocument'], reply='prop')['result']) + this.call(method='GET', path=['testdocument'], reply='prop')['result']) self.assertEqual( {'prop': 'default'}, - self.call('GET', path=['testdocument', guid], reply='prop')) + this.call(method='GET', path=['testdocument', guid], reply='prop')) self.assertEqual( 'default', - self.call('GET', path=['testdocument', guid, 'prop'])) - - def test_PopulateNonDefualtPropsInSetters(self): - - class TestDocument(db.Resource): - - @db.indexed_property(slot=1) - def prop1(self, value): - return value - - @db.indexed_property(slot=2, default='default') - def prop2(self, value): - return all - - @prop2.setter - def prop2(self, value): - if value != 'default': - self['prop1'] = value - return value - - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - - self.assertRaises(RuntimeError, self.call, 'POST', path=['testdocument'], content={}) - - guid = self.call('POST', path=['testdocument'], content={'prop2': 'value2'}) - self.assertEqual('value2', self.call('GET', path=['testdocument', guid, 'prop1'])) + this.call(method='GET', path=['testdocument', guid, 'prop'])) def test_prop_meta(self): + files.update('url', {'url': 'http://new', 'foo': 'bar', 'size': 100}) class TestDocument(db.Resource): @@ -1146,44 +1240,55 @@ class RoutesTest(tests.Test): def prop(self, value): return value - @db.blob_property() + @db.stored_property(db.Blob) def blob1(self, value): return value - @db.blob_property() + @db.stored_property(db.Blob) def blob2(self, value): return value @blob2.setter def blob2(self, value): - return {'url': 'http://new', 'foo': 'bar', 'blob_size': 100} + return 'url' - self.volume = db.Volume(tests.tmpdir, [TestDocument], lambda event: None) - guid = self.call('POST', ['testdocument'], content = {'prop': 'prop', 'blob1': 'blob', 'blob2': ''}) + volume = db.Volume(tests.tmpdir, [TestDocument]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['testdocument'], content = {'prop': 'prop', 'blob1': 'blob', 'blob2': ''}) - assert self.call('HEAD', ['testdocument', guid, 'prop']) is None - meta = self.volume['testdocument'].get(guid).meta('prop') + response = Response() + assert this.call(response=response, + method='HEAD', path=['testdocument', guid, 'prop']) is None + meta = volume['testdocument'].get(guid).meta('prop') meta.pop('value') - self.assertEqual(meta, self.response.meta) - self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified) - - assert self.call('HEAD', ['testdocument', guid, 'blob1'], host='localhost') is None - meta = self.volume['testdocument'].get(guid).meta('blob1') - meta.pop('blob') - self.assertEqual(meta, self.response.meta) - self.assertEqual(len('blob'), self.response.content_length) - self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified) - - assert self.call('HEAD', ['testdocument', guid, 'blob2']) is None - meta = self.volume['testdocument'].get(guid).meta('blob2') - self.assertEqual(meta, self.response.meta) - self.assertEqual(100, self.response.content_length) - self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified) - - assert self.call('GET', ['testdocument', guid, 'blob2']) is not None - meta = self.volume['testdocument'].get(guid).meta('blob2') - self.assertEqual(meta, self.response.meta) - self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), self.response.last_modified) + self.assertEqual(meta, response.meta) + self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified) + + response = Response() + assert this.call(response=response, + method='HEAD', path=['testdocument', guid, 'blob1'], environ={'HTTP_HOST': 'localhost'}) is None + meta = volume['testdocument'].get(guid).meta('blob1') + meta.pop('value') + self.assertEqual(meta, response.meta) + self.assertEqual(len('blob'), response.content_length) + self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified) + + response = Response() + assert this.call(response=response, + method='HEAD', path=['testdocument', guid, 'blob2']) is None + meta = volume['testdocument'].get(guid).meta('blob2') + meta.pop('value') + self.assertEqual(meta, response.meta) + self.assertEqual(100, response.content_length) + self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified) + + response = Response() + assert this.call(response=response, + method='GET', path=['testdocument', guid, 'blob2']) is not None + meta = volume['testdocument'].get(guid).meta('blob2') + meta.pop('value') + self.assertEqual(meta, response.meta) + self.assertEqual(formatdate(meta['mtime'], localtime=False, usegmt=True), response.last_modified) def test_DefaultAuthor(self): @@ -1196,25 +1301,26 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - self.volume = db.Volume('db', [User, Document]) + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) - guid = self.call('POST', ['document'], content={}, principal='user') + guid = this.call(method='POST', path=['document'], content={}, principal='user') self.assertEqual( [{'name': 'user', 'role': 2}], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual( {'user': {'role': 2, 'order': 0}}, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.volume['user'].create({'guid': 'user', 'pubkey': '', 'name': 'User'}) + volume['user'].create({'guid': 'user', 'pubkey': '', 'name': 'User'}) - guid = self.call('POST', ['document'], content={}, principal='user') + guid = this.call(method='POST', path=['document'], content={}, principal='user') self.assertEqual( [{'guid': 'user', 'name': 'User', 'role': 3}], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual( {'user': {'name': 'User', 'role': 3, 'order': 0}}, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) def test_FindByAuthor(self): @@ -1227,36 +1333,37 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - self.volume = db.Volume('db', [User, Document]) + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) - self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'UserName1'}) - self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User Name2'}) - self.volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User Name 3'}) + volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'UserName1'}) + volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User Name2'}) + volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User Name 3'}) - guid1 = self.call('POST', ['document'], content={}, principal='user1') - guid2 = self.call('POST', ['document'], content={}, principal='user2') - guid3 = self.call('POST', ['document'], content={}, principal='user3') + guid1 = this.call(method='POST', path=['document'], content={}, principal='user1') + guid2 = this.call(method='POST', path=['document'], content={}, principal='user2') + guid3 = this.call(method='POST', path=['document'], content={}, principal='user3') self.assertEqual(sorted([ {'guid': guid1}, ]), - self.call('GET', ['document'], author='UserName1')['result']) + this.call(method='GET', path=['document'], author='UserName1')['result']) self.assertEqual(sorted([ {'guid': guid1}, ]), - sorted(self.call('GET', ['document'], query='author:UserName')['result'])) + sorted(this.call(method='GET', path=['document'], query='author:UserName')['result'])) self.assertEqual(sorted([ {'guid': guid1}, {'guid': guid2}, {'guid': guid3}, ]), - sorted(self.call('GET', ['document'], query='author:User')['result'])) + sorted(this.call(method='GET', path=['document'], query='author:User')['result'])) self.assertEqual(sorted([ {'guid': guid2}, {'guid': guid3}, ]), - sorted(self.call('GET', ['document'], query='author:Name')['result'])) + sorted(this.call(method='GET', path=['document'], query='author:Name')['result'])) def test_PreserveAuthorsOrder(self): @@ -1269,99 +1376,77 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - self.volume = db.Volume('db', [User, Document]) + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) - self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) - self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) - self.volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User3'}) + volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) + volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) + volume['user'].create({'guid': 'user3', 'pubkey': '', 'name': 'User3'}) - guid = self.call('POST', ['document'], content={}, principal='user1') - self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=0) - self.call('PUT', ['document', guid], cmd='useradd', user='user3', role=0) + guid = this.call(method='POST', path=['document'], content={}, principal='user1') + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=0) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user3', role=0) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user2', 'name': 'User2', 'role': 1}, {'guid': 'user3', 'name': 'User3', 'role': 1}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user2': {'name': 'User2', 'role': 1, 'order': 1}, 'user3': {'name': 'User3', 'role': 1, 'order': 2}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='userdel', user='user2', principal='user1') - self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=0) + this.call(method='PUT', path=['document', guid], cmd='userdel', user='user2', principal='user1') + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=0) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user3', 'name': 'User3', 'role': 1}, {'guid': 'user2', 'name': 'User2', 'role': 1}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user3': {'name': 'User3', 'role': 1, 'order': 2}, 'user2': {'name': 'User2', 'role': 1, 'order': 3}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='userdel', user='user2', principal='user1') - self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=0) + this.call(method='PUT', path=['document', guid], cmd='userdel', user='user2', principal='user1') + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=0) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user3', 'name': 'User3', 'role': 1}, {'guid': 'user2', 'name': 'User2', 'role': 1}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user3': {'name': 'User3', 'role': 1, 'order': 2}, 'user2': {'name': 'User2', 'role': 1, 'order': 3}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='userdel', user='user3', principal='user1') - self.call('PUT', ['document', guid], cmd='useradd', user='user3', role=0) + this.call(method='PUT', path=['document', guid], cmd='userdel', user='user3', principal='user1') + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user3', role=0) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user2', 'name': 'User2', 'role': 1}, {'guid': 'user3', 'name': 'User3', 'role': 1}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user2': {'name': 'User2', 'role': 1, 'order': 3}, 'user3': {'name': 'User3', 'role': 1, 'order': 4}, }, - self.volume['document'].get(guid)['author']) - - def test_CopyAthors(self): - - class User(db.Resource): - - @db.indexed_property(slot=1) - def name(self, value): - return value - - class Document(db.Resource): - pass - - self.volume = db.Volume('db', [User, Document]) - self.volume['user'].create({'guid': 'user', 'pubkey': '', 'name': 'User'}) - - guid1 = self.call('POST', ['document'], content={}, principal='user') - self.assertEqual({'user': {'name': 'User', 'role': 3, 'order': 0}}, self.volume['document'].get(guid1)['author']) - author = self.call('GET', ['document', guid1, 'author']) - self.assertEqual([{'guid': 'user', 'role': 3, 'name': 'User'}], author) - - guid2 = self.volume['document'].create({'author': author}, setters=True) - author = self.call('GET', ['document', guid1, 'author']) - self.assertEqual({'user': {'name': 'User', 'role': 3, 'order': 0}}, self.volume['document'].get(guid2)['author']) + volume['document'].get(guid)['author']) def test_AddUser(self): @@ -1374,62 +1459,63 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - self.volume = db.Volume('db', [User, Document]) + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) - self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) - self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) + volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) + volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) - guid = self.call('POST', ['document'], content={}, principal='user1') + guid = this.call(method='POST', path=['document'], content={}, principal='user1') self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='useradd', user='user2', role=2) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2', role=2) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user2', 'name': 'User2', 'role': 3}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user2': {'name': 'User2', 'role': 3, 'order': 1}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='useradd', user='User3', role=3) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='User3', role=3) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user2', 'name': 'User2', 'role': 3}, {'name': 'User3', 'role': 2}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user2': {'name': 'User2', 'role': 3, 'order': 1}, 'User3': {'role': 2, 'order': 2}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='useradd', user='User4', role=4) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='User4', role=4) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user2', 'name': 'User2', 'role': 3}, {'name': 'User3', 'role': 2}, {'name': 'User4', 'role': 0}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user2': {'name': 'User2', 'role': 3, 'order': 1}, 'User3': {'role': 2, 'order': 2}, 'User4': {'role': 0, 'order': 3}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) def test_UpdateAuthor(self): @@ -1442,46 +1528,47 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - self.volume = db.Volume('db', [User, Document]) + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) - self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) - guid = self.call('POST', ['document'], content={}, principal='user1') + volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) + guid = this.call(method='POST', path=['document'], content={}, principal='user1') - self.call('PUT', ['document', guid], cmd='useradd', user='User2', role=0) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='User2', role=0) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'name': 'User2', 'role': 0}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'User2': {'role': 0, 'order': 1}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='useradd', user='user1', role=0) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user1', role=0) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 1}, {'name': 'User2', 'role': 0}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 1, 'order': 0}, 'User2': {'role': 0, 'order': 1}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='useradd', user='User2', role=2) + this.call(method='PUT', path=['document', guid], cmd='useradd', user='User2', role=2) self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 1}, {'name': 'User2', 'role': 2}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 1, 'order': 0}, 'User2': {'role': 2, 'order': 1}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) def test_DelUser(self): @@ -1494,150 +1581,73 @@ class RoutesTest(tests.Test): class Document(db.Resource): pass - self.volume = db.Volume('db', [User, Document]) + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) - self.volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) - self.volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) - guid = self.call('POST', ['document'], content={}, principal='user1') - self.call('PUT', ['document', guid], cmd='useradd', user='user2') - self.call('PUT', ['document', guid], cmd='useradd', user='User3') + volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) + volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) + guid = this.call(method='POST', path=['document'], content={}, principal='user1') + this.call(method='PUT', path=['document', guid], cmd='useradd', user='user2') + this.call(method='PUT', path=['document', guid], cmd='useradd', user='User3') self.assertEqual([ {'guid': 'user1', 'name': 'User1', 'role': 3}, {'guid': 'user2', 'name': 'User2', 'role': 1}, {'name': 'User3', 'role': 0}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user1': {'name': 'User1', 'role': 3, 'order': 0}, 'user2': {'name': 'User2', 'role': 1, 'order': 1}, 'User3': {'role': 0, 'order': 2}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) # Do not remove yourself - self.assertRaises(RuntimeError, self.call, 'PUT', ['document', guid], cmd='userdel', user='user1', principal='user1') - self.assertRaises(RuntimeError, self.call, 'PUT', ['document', guid], cmd='userdel', user='user2', principal='user2') + self.assertRaises(RuntimeError, this.call, method='PUT', path=['document', guid], cmd='userdel', user='user1', principal='user1') + self.assertRaises(RuntimeError, this.call, method='PUT', path=['document', guid], cmd='userdel', user='user2', principal='user2') - self.call('PUT', ['document', guid], cmd='userdel', user='user1', principal='user2') + this.call(method='PUT', path=['document', guid], cmd='userdel', user='user1', principal='user2') self.assertEqual([ {'guid': 'user2', 'name': 'User2', 'role': 1}, {'name': 'User3', 'role': 0}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user2': {'name': 'User2', 'role': 1, 'order': 1}, 'User3': {'role': 0, 'order': 2}, }, - self.volume['document'].get(guid)['author']) + volume['document'].get(guid)['author']) - self.call('PUT', ['document', guid], cmd='userdel', user='User3', principal='user2') + this.call(method='PUT', path=['document', guid], cmd='userdel', user='User3', principal='user2') self.assertEqual([ {'guid': 'user2', 'name': 'User2', 'role': 1}, ], - self.call('GET', ['document', guid, 'author'])) + this.call(method='GET', path=['document', guid, 'author'])) self.assertEqual({ 'user2': {'name': 'User2', 'role': 1, 'order': 1}, }, - self.volume['document'].get(guid)['author']) - - def test_typecast_prop_value(self): - prop = Property('prop', typecast=int) - self.assertEqual(1, _typecast_prop_value(prop.typecast, 1)) - self.assertEqual(1, _typecast_prop_value(prop.typecast, 1.1)) - self.assertEqual(1, _typecast_prop_value(prop.typecast, '1')) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '1.0') - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '') - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None) - - prop = Property('prop', typecast=float) - self.assertEqual(1.0, _typecast_prop_value(prop.typecast, 1)) - self.assertEqual(1.1, _typecast_prop_value(prop.typecast, 1.1)) - self.assertEqual(1.0, _typecast_prop_value(prop.typecast, '1')) - self.assertEqual(1.1, _typecast_prop_value(prop.typecast, '1.1')) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '') - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None) - - prop = Property('prop', typecast=bool) - self.assertEqual(False, _typecast_prop_value(prop.typecast, 0)) - self.assertEqual(True, _typecast_prop_value(prop.typecast, 1)) - self.assertEqual(True, _typecast_prop_value(prop.typecast, 1.1)) - self.assertEqual(True, _typecast_prop_value(prop.typecast, '1')) - self.assertEqual(True, _typecast_prop_value(prop.typecast, 'false')) - self.assertEqual(False, _typecast_prop_value(prop.typecast, '')) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None) - - prop = Property('prop', typecast=[int]) - self.assertEqual((1,), _typecast_prop_value(prop.typecast, 1)) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '') - self.assertEqual((), _typecast_prop_value(prop.typecast, [])) - self.assertEqual((123,), _typecast_prop_value(prop.typecast, '123')) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, 'a') - self.assertEqual((123, 4, 5), _typecast_prop_value(prop.typecast, ['123', 4, 5.6])) - - prop = Property('prop', typecast=[1, 2]) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, 0) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '') - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, 'A') - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '3') - self.assertEqual(1, _typecast_prop_value(prop.typecast, 1)) - self.assertEqual(2, _typecast_prop_value(prop.typecast, 2)) - self.assertEqual(1, _typecast_prop_value(prop.typecast, '1')) - - prop = Property('prop', typecast=[str]) - self.assertEqual(('',), _typecast_prop_value(prop.typecast, '')) - self.assertEqual(('',), _typecast_prop_value(prop.typecast, [''])) - self.assertEqual((), _typecast_prop_value(prop.typecast, [])) - - prop = Property('prop', typecast=[]) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, None) - self.assertEqual(('',), _typecast_prop_value(prop.typecast, '')) - self.assertEqual(('',), _typecast_prop_value(prop.typecast, [''])) - self.assertEqual((), _typecast_prop_value(prop.typecast, [])) - self.assertEqual(('0',), _typecast_prop_value(prop.typecast, 0)) - self.assertEqual(('',), _typecast_prop_value(prop.typecast, '')) - self.assertEqual(('foo',), _typecast_prop_value(prop.typecast, 'foo')) - - prop = Property('prop', typecast=[['A', 'B', 'C']]) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, '') - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, ['']) - self.assertEqual((), _typecast_prop_value(prop.typecast, [])) - self.assertEqual(('A', 'B', 'C'), _typecast_prop_value(prop.typecast, ['A', 'B', 'C'])) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, ['a']) - self.assertRaises(ValueError, _typecast_prop_value, prop.typecast, ['A', 'x']) - - prop = Property('prop', typecast=bool) - self.assertEqual(True, _typecast_prop_value(prop.typecast, True)) - self.assertEqual(False, _typecast_prop_value(prop.typecast, False)) - self.assertEqual(True, _typecast_prop_value(prop.typecast, 'False')) - self.assertEqual(True, _typecast_prop_value(prop.typecast, '0')) - - prop = Property('prop', typecast=[['A', 'B', 'C']]) - self.assertEqual(('A', 'B', 'C'), _typecast_prop_value(prop.typecast, ['A', 'B', 'C'])) - - prop = Property('prop', typecast=lambda x: x + 1) - self.assertEqual(1, _typecast_prop_value(prop.typecast, 0)) + volume['document'].get(guid)['author']) def test_DefaultOrder(self): class Document(db.Resource): pass - self.volume = db.Volume('db', [Document]) + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) - self.volume['document'].create({'guid': '3', 'ctime': 3}) - self.volume['document'].create({'guid': '2', 'ctime': 2}) - self.volume['document'].create({'guid': '1', 'ctime': 1}) + volume['document'].create({'guid': '3', 'ctime': 3}) + volume['document'].create({'guid': '2', 'ctime': 2}) + volume['document'].create({'guid': '1', 'ctime': 1}) self.assertEqual([ {'guid': '1'}, {'guid': '2'}, {'guid': '3'}, ], - self.call('GET', ['document'])['result']) + this.call(method='GET', path=['document'])['result']) - def test_SetDefaultPropsOnNoneValues(self): + def test_DefaultsOnNonePostValues(self): class Document(db.Resource): @@ -1645,10 +1655,11 @@ class RoutesTest(tests.Test): def prop(self, value): return value - self.volume = db.Volume('db', [Document]) + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) - guid = self.call('POST', ['document'], content={'prop': None}) - self.assertEqual('default', self.volume['document'].get(guid).meta('prop')['value']) + guid = this.call(method='POST', path=['document'], content={'prop': None}) + self.assertEqual('default', this.call(method='GET', path=['document', guid, 'prop'])) def test_InsertAggprops(self): @@ -1658,117 +1669,316 @@ class RoutesTest(tests.Test): def prop1(self, value): return value - @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.WRITE) - def prop2(self, value): - return value - - @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.INSERT) + @db.stored_property(db.Aggregated, acl=ACL.INSERT) def prop3(self, value): return value events = [] - self.volume = db.Volume('db', [Document], lambda event: events.append(event)) - guid = self.call('POST', ['document'], content={}) + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + this.broadcast = lambda x: events.append(x) + guid = this.call(method='POST', path=['document'], content={}) - self.assertRaises(http.NotFound, self.call, 'POST', ['document', 'foo', 'bar'], content={}) - self.assertRaises(http.NotFound, self.call, 'POST', ['document', guid, 'bar'], content={}) - self.assertRaises(http.BadRequest, self.call, 'POST', ['document', guid, 'prop1'], content={}) - self.assertRaises(http.Forbidden, self.call, 'POST', ['document', guid, 'prop2'], content={}) + self.assertRaises(http.NotFound, this.call, method='POST', path=['document', 'foo', 'bar'], content={}) + self.assertRaises(http.NotFound, this.call, method='POST', path=['document', guid, 'bar'], content={}) + self.assertRaises(http.BadRequest, this.call, method='POST', path=['document', guid, 'prop1'], content={}) del events[:] self.override(time, 'time', lambda: 0) self.override(toolkit, 'uuid', lambda: '0') - self.assertEqual('0', self.call('POST', ['document', guid, 'prop3'], content={})) + self.assertEqual('0', this.call(method='POST', path=['document', guid, 'prop3'], content=0)) self.assertEqual({ - '0': {'seqno': 2}, + '0': {'seqno': 2, 'value': 0}, }, - self.volume['document'].get(guid)['prop3']) + volume['document'].get(guid)['prop3']) self.assertEqual([ {'event': 'update', 'resource': 'document', 'guid': guid}, ], events) self.override(time, 'time', lambda: 1) - self.assertEqual('1', self.call('POST', ['document', guid, 'prop3'], content={'guid': '1', 'foo': 'bar'})) + self.override(toolkit, 'uuid', lambda: '1') + self.assertEqual('1', this.call(method='POST', path=['document', guid, 'prop3'], content={'foo': 'bar'})) self.assertEqual({ - '0': {'seqno': 2}, - '1': {'seqno': 3, 'foo': 'bar'}, + '0': {'seqno': 2, 'value': 0}, + '1': {'seqno': 3, 'value': {'foo': 'bar'}}, }, - self.volume['document'].get(guid)['prop3']) + volume['document'].get(guid)['prop3']) self.override(time, 'time', lambda: 2) self.override(toolkit, 'uuid', lambda: '2') - self.assertEqual('2', self.call('POST', ['document', guid, 'prop3'], content={'prop': 'more'})) + self.assertEqual('2', this.call(method='POST', path=['document', guid, 'prop3'], content=None)) self.assertEqual({ - '0': {'seqno': 2}, - '1': {'seqno': 3, 'foo': 'bar'}, - '2': {'seqno': 4, 'prop': 'more'}, + '0': {'seqno': 2, 'value': 0}, + '1': {'seqno': 3, 'value': {'foo': 'bar'}}, + '2': {'seqno': 4, 'value': None}, }, - self.volume['document'].get(guid)['prop3']) + volume['document'].get(guid)['prop3']) def test_RemoveAggprops(self): class Document(db.Resource): - @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.INSERT) + @db.stored_property(db.Aggregated, acl=ACL.INSERT) def prop1(self, value): return value - @db.stored_property(typecast=db.AggregatedType, default=db.AggregatedType(), acl=ACL.INSERT | ACL.REMOVE) + @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE) def prop2(self, value): return value events = [] - self.volume = db.Volume('db', [Document], lambda event: events.append(event)) - guid = self.call('POST', ['document'], content={}) + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + this.broadcast = lambda x: events.append(x) + guid = this.call(method='POST', path=['document'], content={}) - agg_guid = self.call('POST', ['document', guid, 'prop1'], content={'probe': 'value'}) + agg_guid = this.call(method='POST', path=['document', guid, 'prop1'], content=2) del events[:] self.assertEqual( - {agg_guid: {'seqno': 2, 'probe': 'value'}}, - self.volume['document'].get(guid)['prop1']) - self.assertRaises(http.Forbidden, self.call, 'DELETE', ['document', guid, 'prop1', agg_guid]) + {agg_guid: {'seqno': 2, 'value': 2}}, + volume['document'].get(guid)['prop1']) + self.assertRaises(http.Forbidden, this.call, method='DELETE', path=['document', guid, 'prop1', agg_guid]) self.assertEqual( - {agg_guid: {'seqno': 2, 'probe': 'value'}}, - self.volume['document'].get(guid)['prop1']) + {agg_guid: {'seqno': 2, 'value': 2}}, + volume['document'].get(guid)['prop1']) self.assertEqual([], events) - agg_guid = self.call('POST', ['document', guid, 'prop2'], content={'probe': 'value'}) + agg_guid = this.call(method='POST', path=['document', guid, 'prop2'], content=3) del events[:] self.assertEqual( - {agg_guid: {'seqno': 3, 'probe': 'value'}}, - self.volume['document'].get(guid)['prop2']) - self.call('DELETE', ['document', guid, 'prop2', agg_guid]) + {agg_guid: {'seqno': 3, 'value': 3}}, + volume['document'].get(guid)['prop2']) + this.call(method='DELETE', path=['document', guid, 'prop2', agg_guid]) self.assertEqual( {agg_guid: {'seqno': 4}}, - self.volume['document'].get(guid)['prop2']) + volume['document'].get(guid)['prop2']) + self.assertEqual([ + {'event': 'update', 'resource': 'document', 'guid': guid}, + ], + events) + + def test_FailOnAbsentAggprops(self): + + class Document(db.Resource): + + @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE | ACL.REPLACE) + def prop(self, value): + return value + + events = [] + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + this.broadcast = lambda x: events.append(x) + guid = this.call(method='POST', path=['document'], content={}) + del events[:] + + self.assertRaises(http.NotFound, this.call, method='DELETE', path=['document', guid, 'prop', 'absent']) + self.assertEqual([], events) + + def test_UpdateAggprops(self): + + class Document(db.Resource): + + @db.stored_property(db.Aggregated) + def prop1(self, value): + return value + + @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE | ACL.REPLACE) + def prop2(self, value): + return value + + events = [] + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + this.broadcast = lambda x: events.append(x) + guid = this.call(method='POST', path=['document'], content={}) + + agg_guid = this.call(method='POST', path=['document', guid, 'prop1'], content=1) + del events[:] + self.assertEqual( + {agg_guid: {'seqno': 2, 'value': 1}}, + volume['document'].get(guid)['prop1']) + self.assertRaises(http.Forbidden, this.call, method='PUT', path=['document', guid, 'prop1', agg_guid], content=2) + self.assertEqual( + {agg_guid: {'seqno': 2, 'value': 1}}, + volume['document'].get(guid)['prop1']) + self.assertEqual([], events) + + agg_guid = this.call(method='POST', path=['document', guid, 'prop2'], content=2) + del events[:] + self.assertEqual( + {agg_guid: {'seqno': 3, 'value': 2}}, + volume['document'].get(guid)['prop2']) + this.call(method='PUT', path=['document', guid, 'prop2', agg_guid], content=3) + self.assertEqual( + {agg_guid: {'seqno': 4, 'value': 3}}, + volume['document'].get(guid)['prop2']) + self.assertEqual([ + {'event': 'update', 'resource': 'document', 'guid': guid}, + ], + events) + + def test_PostAbsentAggpropsOnUpdate(self): + + class Document(db.Resource): + + @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE | ACL.REPLACE) + def prop(self, value): + return value + + events = [] + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + this.broadcast = lambda x: events.append(x) + guid = this.call(method='POST', path=['document'], content={}) + del events[:] + + this.call(method='PUT', path=['document', guid, 'prop', 'absent'], content='probe') + self.assertEqual( + {'absent': {'seqno': 2, 'value': 'probe'}}, + volume['document'].get(guid)['prop']) self.assertEqual([ {'event': 'update', 'resource': 'document', 'guid': guid}, ], events) - def call(self, method=None, path=None, - accept_language=None, content=None, content_stream=None, cmd=None, - content_type=None, host=None, request=None, routes=db.Routes, principal=None, - **kwargs): - if request is None: - environ = { - 'REQUEST_METHOD': method, - 'PATH_INFO': '/'.join([''] + path), - 'HTTP_ACCEPT_LANGUAGE': ','.join(accept_language or []), - 'HTTP_HOST': host, - 'wsgi.input': content_stream, - } - if content_type: - environ['CONTENT_TYPE'] = content_type - if content_stream is not None: - environ['CONTENT_LENGTH'] = str(len(content_stream.getvalue())) - request = Request(environ, cmd=cmd, content=content) - request.update(kwargs) - request.principal = principal - router = Router(routes(self.volume)) - self.response = Response() - return router._call_route(request, self.response) + def test_OriginalAggprops(self): + + class Document(db.Resource): + + @db.stored_property(db.Aggregated, acl=ACL.INSERT | ACL.REMOVE) + def prop(self, value): + return value + + volume = db.Volume(tests.tmpdir, [User, Document]) + router = Router(db.Routes(volume)) + volume['user'].create({'guid': 'user1', 'pubkey': '', 'name': 'User1'}) + volume['user'].create({'guid': 'user2', 'pubkey': '', 'name': 'User2'}) + + guid = this.call(method='POST', path=['document'], content={}, principal=tests.UID) + assert ACL.ORIGINAL & volume['document'][guid]['author'][tests.UID]['role'] + + agg_guid1 = this.call(method='POST', path=['document', guid, 'prop'], content=1, principal=tests.UID) + assert tests.UID2 not in volume['document'][guid]['prop'][agg_guid1]['author'] + assert ACL.ORIGINAL & volume['document'][guid]['prop'][agg_guid1]['author'][tests.UID]['role'] + + agg_guid2 = this.call(method='POST', path=['document', guid, 'prop'], content=1, principal=tests.UID2) + assert tests.UID not in volume['document'][guid]['prop'][agg_guid2]['author'] + assert not (ACL.ORIGINAL & volume['document'][guid]['prop'][agg_guid2]['author'][tests.UID2]['role']) + + this.call(method='DELETE', path=['document', guid, 'prop', agg_guid2], principal=tests.UID2) + assert tests.UID not in volume['document'][guid]['prop'][agg_guid2]['author'] + assert not (ACL.ORIGINAL & volume['document'][guid]['prop'][agg_guid2]['author'][tests.UID2]['role']) + + def test_AggregatedBlobs(self): + + class Document(db.Resource): + + @db.stored_property(db.Aggregated, subtype=db.Blob()) + def blobs(self, value): + return value + + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + guid = this.call(method='POST', path=['document'], content={}) + + agg1 = this.call(method='POST', path=['document', guid, 'blobs'], content='blob1') + self.assertEqual({ + agg1: {'seqno': 2, 'value': str(hash('blob1'))}, + }, + volume['document'].get(guid)['blobs']) + assert files.get(str(hash('blob1'))) + + agg2 = this.call(method='POST', path=['document', guid, 'blobs'], content='blob2') + self.assertEqual({ + agg1: {'seqno': 2, 'value': str(hash('blob1'))}, + agg2: {'seqno': 3, 'value': str(hash('blob2'))}, + }, + volume['document'].get(guid)['blobs']) + assert files.get(str(hash('blob2'))) + + this.call(method='DELETE', path=['document', guid, 'blobs', agg1]) + self.assertEqual({ + agg1: {'seqno': 4}, + agg2: {'seqno': 3, 'value': str(hash('blob2'))}, + }, + volume['document'].get(guid)['blobs']) + assert files.get(str(hash('blob1'))) is None + assert files.get(str(hash('blob2'))) + + this.call(method='DELETE', path=['document', guid, 'blobs', agg2]) + self.assertEqual({ + agg1: {'seqno': 4}, + agg2: {'seqno': 5}, + }, + volume['document'].get(guid)['blobs']) + assert files.get(str(hash('blob1'))) is None + assert files.get(str(hash('blob2'))) is None + + agg3 = this.call(method='POST', path=['document', guid, 'blobs'], content='blob3') + self.assertEqual({ + agg1: {'seqno': 4}, + agg2: {'seqno': 5}, + agg3: {'seqno': 6, 'value': str(hash('blob3'))}, + }, + volume['document'].get(guid)['blobs']) + assert files.get(str(hash('blob1'))) is None + assert files.get(str(hash('blob2'))) is None + assert files.get(str(hash('blob3'))) + + def test_AggregatedSearch(self): + + class Document(db.Resource): + + @db.stored_property(db.Aggregated, prefix='A', full_text=True) + def comments(self, value): + return value + + @db.stored_property(prefix='B', full_text=False, default='') + def prop(self, value): + return value + + volume = db.Volume(tests.tmpdir, [Document]) + router = Router(db.Routes(volume)) + + guid1 = this.call(method='POST', path=['document'], content={}) + this.call(method='POST', path=['document', guid1, 'comments'], content='a') + this.call(method='POST', path=['document', guid1, 'comments'], content='b') + this.call(method='PUT', path=['document', guid1, 'prop'], content='c') + + guid2 = this.call(method='POST', path=['document'], content={}) + this.call(method='POST', path=['document', guid2, 'comments'], content='c') + this.call(method='POST', path=['document', guid2, 'comments'], content='a') + this.call(method='PUT', path=['document', guid2, 'prop'], content='b') + + guid3 = this.call(method='POST', path=['document'], content={}) + this.call(method='POST', path=['document', guid3, 'comments'], content='a c') + this.call(method='POST', path=['document', guid3, 'comments'], content='b d') + this.call(method='PUT', path=['document', guid3, 'prop'], content='e') + + self.assertEqual( + sorted([guid1, guid2, guid3]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='a')['result']])) + self.assertEqual( + sorted([guid1, guid3]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='b')['result']])) + self.assertEqual( + sorted([guid2, guid3]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='c')['result']])) + self.assertEqual( + sorted([]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='absent')['result']])) + + self.assertEqual( + sorted([guid1, guid2, guid3]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='comments:a')['result']])) + self.assertEqual( + sorted([guid1, guid3]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='comments:b')['result']])) + self.assertEqual( + sorted([guid2, guid3]), + sorted([i['guid'] for i in this.call(method='GET', path=['document'], query='comments:c')['result']])) if __name__ == '__main__': |