def createObject(self, session, about): """ Pretend to create an object. If an about value is passed, check with our query resolver to see if the about value is known. If not (or if no about value was passed) return a random new object id. If we get an about value that the query resolver doesn't know about, we adjust our query resolver and tags client so that next time they do. This is to simulate PUT correctly, which creates the object with the about value in the case it doesn't already exist. @param session: a L{FakeSession} instance. @param about: A C{str} value for the about tag. @return: A C{Deferred} that fires with the object id of the new object. """ if about: results = yield self.resolveQuery( None, '%s = "%s"' % (_aboutPath, about)) if results: objectId = results.pop() else: objectId = util.generateObjectId() # Make sure the query resolver now knows how to correctly # resolve this about value. self.fakeQueryResolver.updateResults([objectId]) # And add an instance of the about tag to the object. self.setTagInstance(session, _aboutPath, object, about) else: objectId = util.generateObjectId() defer.returnValue(objectId)
def createObject(self, session, about): """ Pretend to create an object. If an about value is passed, check with our query resolver to see if the about value is known. If not (or if no about value was passed) return a random new object id. If we get an about value that the query resolver doesn't know about, we adjust our query resolver and tags client so that next time they do. This is to simulate PUT correctly, which creates the object with the about value in the case it doesn't already exist. @param session: a L{FakeSession} instance. @param about: A C{str} value for the about tag. @return: A C{Deferred} that fires with the object id of the new object. """ if about: results = yield self.resolveQuery( None, '%s = "%s"' % (_aboutPath, about)) if results: objectId = results.pop() else: objectId = util.generateObjectId() # Make sure the query resolver now knows how to correctly # resolve this about value. self.fakeQueryResolver.updateResults([objectId]) # And add an instance of the about tag to the object. self.setTagInstance(session, _aboutPath, object, about) else: objectId = util.generateObjectId() defer.returnValue(objectId)
def testPUTWithNoContentTypeButWithPayload(self): """ Check that if we attempt a PUT with a payload but don't send a Content-Type, we get a BAD_REQUEST response and a NoContentTypeHeader response error-class header. """ about = 'africa' tag = 'ntoll/binary' payload = 'random payload' objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver( about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. headers = { 'Content-Length': [str(len(payload))], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.BAD_REQUEST) self.assertEqual( request.getResponseHeader(buildHeader('Error-Class')), error.NoContentTypeHeader.__name__)
def testPUTWithNoContentTypeButWithPayload(self): """ Check that if we attempt a PUT with a payload but don't send a Content-Type, we get a BAD_REQUEST response and a NoContentTypeHeader response error-class header. """ about = 'africa' tag = 'ntoll/binary' payload = 'random payload' objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. headers = { 'Content-Length': [str(len(payload))], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.BAD_REQUEST) self.assertEqual(request.getResponseHeader(buildHeader('Error-Class')), error.NoContentTypeHeader.__name__)
def testPUTSetOfStringsNotAllStrings(self): """ PUT a set of strings (that are in fact not all strings) value for ntoll/rating onto the object about africa. This should result in a BAD_REQUEST status and an UnsupportedJSONType error class. """ about = 'africa' tag = 'ntoll/rating' tagset = ['good', 'bad', 6] objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver( about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. payload = json.dumps(tagset) headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [contentTypeForPrimitiveJSON], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.BAD_REQUEST) self.assertEqual( request.getResponseHeader(buildHeader('Error-Class')), error.UnsupportedJSONType.__name__)
def testPUTSetOfStringsNotAllStrings(self): """ PUT a set of strings (that are in fact not all strings) value for ntoll/rating onto the object about africa. This should result in a BAD_REQUEST status and an UnsupportedJSONType error class. """ about = 'africa' tag = 'ntoll/rating' tagset = ['good', 'bad', 6] objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. payload = json.dumps(tagset) headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [contentTypeForPrimitiveJSON], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.BAD_REQUEST) self.assertEqual(request.getResponseHeader(buildHeader('Error-Class')), error.UnsupportedJSONType.__name__)
def testPUTGETBinaryValueOnObjectAboutAfrica(self): """ PUT a binary value for ntoll/rating onto the object about africa. Then do two GET requests: - A GET with no Accept header (which means we accept anything) and check the result is what we set. - Do a GET with an Accept header that prevents FluidDB from delivering, and check we get a NOT_ACCEPTABLE status. """ about = 'africa' tag = 'ntoll/binary' value = '\x00\x01' mimetype = 'ntoll/personalbinary' objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver( about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. payload = value headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [mimetype], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT) # Test GET. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) self.assertEqual(request.getResponseHeader('Content-Type'), mimetype) self.assertEqual(body, value) # Test GET when no acceptable Accept header value. headers = {'Accept': ['italian/lira, chewing/gum']} request = FakeRequest('GET', None, headers) request.content = StringIO.StringIO() resource.render(request) self.assertEqual(request.status, http.NOT_ACCEPTABLE)
def testPUTGETBinaryValueOnObjectAboutAfrica(self): """ PUT a binary value for ntoll/rating onto the object about africa. Then do two GET requests: - A GET with no Accept header (which means we accept anything) and check the result is what we set. - Do a GET with an Accept header that prevents FluidDB from delivering, and check we get a NOT_ACCEPTABLE status. """ about = 'africa' tag = 'ntoll/binary' value = '\x00\x01' mimetype = 'ntoll/personalbinary' objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. payload = value headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [mimetype], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT) # Test GET. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) self.assertEqual(request.getResponseHeader('Content-Type'), mimetype) self.assertEqual(body, value) # Test GET when no acceptable Accept header value. headers = {'Accept': ['italian/lira, chewing/gum']} request = FakeRequest('GET', None, headers) request.content = StringIO.StringIO() resource.render(request) self.assertEqual(request.status, http.NOT_ACCEPTABLE)
def testPOSTObjectAboutChickenSoup(self): """ Test that a POST to /about/chicken%20soup results in a CREATED status and that we get back the id of the object that already existed (as will be supplied by the fake query resolver). """ about = 'chicken soup' objectId = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectId], self) facadeClient = FakeFacadeClient(fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutObjectResource(facadeClient, session, about) d = defer.Deferred() request = FakeRequest('POST', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.CREATED) responseDict = json.loads(body) self.assertEqual(responseDict['id'], objectId)
def testGETAboutWithDoubleQuotes(self): ''' Test that a GET to /about/chicken%20"soup"%20taste results in an OK status and that we get back the id of the object that already existed (as will be supplied by the fake query resolver). ''' about = 'chicken "soup" taste' aboutQuoted = r'chicken \"soup\" taste' objectId = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(aboutQuoted, [objectId], self) facadeClient = FakeFacadeClient(fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutObjectResource(facadeClient, session, about) d = defer.Deferred() request = FakeRequest('GET', d) request.args = {objects.showAboutArg: ['False']} request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.OK)
def testGETAboutWithDoubleQuotes(self): ''' Test that a GET to /about/chicken%20"soup"%20taste results in an OK status and that we get back the id of the object that already existed (as will be supplied by the fake query resolver). ''' about = 'chicken "soup" taste' aboutQuoted = r'chicken \"soup\" taste' objectId = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(aboutQuoted, [objectId], self) facadeClient = FakeFacadeClient(fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutObjectResource(facadeClient, session, about) d = defer.Deferred() request = FakeRequest('GET', d) request.args = {objects.showAboutArg: ['False']} request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.OK)
def testPOSTObjectAboutChickenSoup(self): """ Test that a POST to /about/chicken%20soup results in a CREATED status and that we get back the id of the object that already existed (as will be supplied by the fake query resolver). """ about = 'chicken soup' objectId = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectId], self) facadeClient = FakeFacadeClient(fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutObjectResource(facadeClient, session, about) d = defer.Deferred() request = FakeRequest('POST', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.CREATED) responseDict = json.loads(body) self.assertEqual(responseDict['id'], objectId)
def testGETObjectAboutBarcelona(self): """ Test that a GET of /about/barcelona results in an OK status and that we get back the id of the object that already existed (as will be supplied by the fake query resolver), and that it has no tags on it. """ about = 'barcelona' objectId = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectId], self) facadeClient = FakeFacadeClient(fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutObjectResource(facadeClient, session, about) d = defer.Deferred() request = FakeRequest('GET', d) request.args = {objects.showAboutArg: ['False']} request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) responseDict = json.loads(body) self.assertEqual(responseDict[objects.tagPathsArg], []) self.assertEqual(responseDict['id'], objectId)
def testGETObjectAboutBarcelona(self): """ Test that a GET of /about/barcelona results in an OK status and that we get back the id of the object that already existed (as will be supplied by the fake query resolver), and that it has no tags on it. """ about = 'barcelona' objectId = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectId], self) facadeClient = FakeFacadeClient(fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutObjectResource(facadeClient, session, about) d = defer.Deferred() request = FakeRequest('GET', d) request.args = {objects.showAboutArg: ['False']} request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) responseDict = json.loads(body) self.assertEqual(responseDict[objects.tagPathsArg], []) self.assertEqual(responseDict['id'], objectId)
def testPUTGETNonBinaryWithNoAcceptableType(self): """ PUT a primitive (non-binary) value for ntoll/rating onto the object about africa. Then do a GET with an Accept header that prevents FluidDB from delivering, and check we get a NOT_ACCEPTABLE status. """ about = 'africa' tag = 'ntoll/binary' value = 5 objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. payload = json.dumps(value) headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [contentTypeForPrimitiveJSON], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT) # Test GET when no acceptable Accept header value. headers = {'Accept': ['italian/lira, chewing/gum']} request = FakeRequest('GET', None, headers) request.content = StringIO.StringIO() resource.render(request) self.assertEqual(request.status, http.NOT_ACCEPTABLE)
def testPUTGETNonBinaryWithNoAcceptableType(self): """ PUT a primitive (non-binary) value for ntoll/rating onto the object about africa. Then do a GET with an Accept header that prevents FluidDB from delivering, and check we get a NOT_ACCEPTABLE status. """ about = 'africa' tag = 'ntoll/binary' value = 5 objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver( about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. payload = json.dumps(value) headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [contentTypeForPrimitiveJSON], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT) # Test GET when no acceptable Accept header value. headers = {'Accept': ['italian/lira, chewing/gum']} request = FakeRequest('GET', None, headers) request.content = StringIO.StringIO() resource.render(request) self.assertEqual(request.status, http.NOT_ACCEPTABLE)
def testPUTWithNoContentTypeNoPayload(self): """ Check that if we attempt a PUT with no payload and no Content-Type, we get an (ok) NO_CONTENT status (this is putting a None as the value). """ about = 'africa' tag = 'ntoll/binary' objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. d = defer.Deferred() request = FakeRequest('PUT', d) request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT)
def testPUTWithNoContentTypeNoPayload(self): """ Check that if we attempt a PUT with no payload and no Content-Type, we get an (ok) NO_CONTENT status (this is putting a None as the value). """ about = 'africa' tag = 'ntoll/binary' objectIdAboutAfrica = util.generateObjectId() fakeQueryResolver = FakeQueryResolver( about, [objectIdAboutAfrica], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test PUT. d = defer.Deferred() request = FakeRequest('PUT', d) request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT)
def testRatingForObjectAboutBarcelona(self): """ Run a series of tests on the ntoll/rating tag on the object about barcelona: - the tag should initially not be present. - we should successfully be able to do a PUT. - we should then be able to do a GET, HEAD, and DELETE in that order. - a final GET should then indicate the tag is gone. """ about = 'barcelona' tag = 'ntoll/rating' rating = 6 objectIdAboutBarcelona = util.generateObjectId() fakeQueryResolver = FakeQueryResolver( about, [objectIdAboutBarcelona], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test GET when there is no instance on the object. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.NOT_FOUND) # Test PUT. payload = json.dumps(rating) headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [contentTypeForPrimitiveJSON], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT) self.assertEqual( guessValue(fakeTagsClient.values[tag][objectIdAboutBarcelona]), rating) # Check that the right path, objectId, and value was passed to the # fake tags client. self.assertEqual(fakeTagsClient.values, { tag: {objectIdAboutBarcelona: createThriftValue(rating)}, }) # Test GET. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) self.assertEqual(request.getResponseHeader('Content-Type'), contentTypeForPrimitiveJSON) receivedRating = json.loads(body) self.assertEqual(receivedRating, rating) # Test HEAD d = defer.Deferred() request = FakeRequest('HEAD', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) self.assertEqual(body, '') # Test DELETE d = defer.Deferred() request = FakeRequest('DELETE', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.NO_CONTENT) # Test GET when, finally, there is no instance on the object. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.NOT_FOUND) # Check that the value really was deleted. self.assertEqual(fakeTagsClient.values, {tag: {}})
def testRatingForObjectAboutBarcelona(self): """ Run a series of tests on the ntoll/rating tag on the object about barcelona: - the tag should initially not be present. - we should successfully be able to do a PUT. - we should then be able to do a GET, HEAD, and DELETE in that order. - a final GET should then indicate the tag is gone. """ about = 'barcelona' tag = 'ntoll/rating' rating = 6 objectIdAboutBarcelona = util.generateObjectId() fakeQueryResolver = FakeQueryResolver(about, [objectIdAboutBarcelona], self) fakeTagsClient = FakeTagsClient() facadeClient = FakeFacadeClient(fakeTagsClient=fakeTagsClient, fakeQueryResolver=fakeQueryResolver) session = FakeSession() resource = AboutTagInstanceResource(facadeClient, session, about, tag) # Test GET when there is no instance on the object. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.NOT_FOUND) # Test PUT. payload = json.dumps(rating) headers = { 'Content-Length': [str(len(payload))], 'Content-Type': [contentTypeForPrimitiveJSON], } d = defer.Deferred() request = FakeRequest('PUT', d, headers) request.content = StringIO.StringIO(payload) resource.render(request) yield d self.assertEqual(request.status, http.NO_CONTENT) self.assertEqual( guessValue(fakeTagsClient.values[tag][objectIdAboutBarcelona]), rating) # Check that the right path, objectId, and value was passed to the # fake tags client. self.assertEqual(fakeTagsClient.values, { tag: { objectIdAboutBarcelona: createThriftValue(rating) }, }) # Test GET. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) self.assertEqual(request.getResponseHeader('Content-Type'), contentTypeForPrimitiveJSON) receivedRating = json.loads(body) self.assertEqual(receivedRating, rating) # Test HEAD d = defer.Deferred() request = FakeRequest('HEAD', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.OK) self.assertEqual(body, '') # Test DELETE d = defer.Deferred() request = FakeRequest('DELETE', d) request.content = StringIO.StringIO() resource.render(request) body = yield d self.assertEqual(request.status, http.NO_CONTENT) # Test GET when, finally, there is no instance on the object. d = defer.Deferred() request = FakeRequest('GET', d) request.content = StringIO.StringIO() resource.render(request) yield d self.assertEqual(request.status, http.NOT_FOUND) # Check that the value really was deleted. self.assertEqual(fakeTagsClient.values, {tag: {}})