Commit b43adf6c authored by Łukasz Nowak's avatar Łukasz Nowak

Cleanup shacache and shadir restfulness.

Follow the specification of shacache and shadir: PUT is used in shadir,
POST is used in shacache in order to create new content. erp5_web can be used
without any modification to serve fully restfull POST interface.

Create special action for Web Site which reacts on POST type of request and
support it by low level functionality. This action is available in web view
only and affects only Web Sites configured for shacache.

Other changes:

 * do not check uploaded content, just return calculated sha
 * break compatibility during upload (better now then later)
 * avoid hiding errors during publishing content by hiding exceptions in
   WebSite_publishDocumentByActivity
 * do randomisation in tests and make them live test safe
 * connect to running web server in tests in order to use all stacks during
   uploading and downloading content
 * cleanup erp5_web_shacache and erp5_web_shadir business templates and remove
   not needed scripts
 * during testing treat running site as blackbox and do not try to be too smart
parent aa798bfd
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_web_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_web_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>web_post_shacache_view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>0.8</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Web Post Shacache View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/WebSite_viewAsWebPost</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: context.getSkinSelectionName() == \'SHACACHE\' and request.method == \'POST\' and object is not None and object.isWebMode() and not object.isEditableMode()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -63,52 +63,6 @@ def WebSection_getDocumentValue(self, key, portal=None, language=None,\ ...@@ -63,52 +63,6 @@ def WebSection_getDocumentValue(self, key, portal=None, language=None,\
return None return None
def WebSection_setObject(self, id, ob, **kw):
"""
Add any change of the file uploaded.
"""
sha512sum = hashlib.sha512()
self.REQUEST._file.seek(0)
while True:
d = self.REQUEST._file.read(1<<20)
if not d:
break
sha512sum.update(d)
reference = sha512sum.hexdigest()
if reference != id:
raise ValueError('The content does not match with sha512sum provided.')
# Set object properties
ob.setContentType('application/octet-stream')
ob.setFilename(id)
ob.setReference(reference)
return ob
def WebSection_putFactory(self, name, typ, body):
"""
API SHACACHE
- PUT /<key>
+ parameters required:
* data: it is the file content
The key is the file name.
"""
portal = self.getPortalObject()
document = portal.portal_contributions.newContent(data=body,
filename=name,
discover_metadata=False)
# We can only change the state of the object after all the activities and
# interaction workflow, to avoid any security problem.
document.activate(after_path_and_method_id=(document.getPath(), \
('convertToBaseFormat', 'Document_tryToConvertToBaseFormat', \
'immediateReindexObject', 'recursiveImmediateReindexObject')))\
.WebSite_publishDocumentByActivity()
return document
def File_viewAsWeb(self): def File_viewAsWeb(self):
""" """
Make possible to send the file data to the client without consume the Make possible to send the file data to the client without consume the
...@@ -147,3 +101,28 @@ def File_viewAsWeb(self): ...@@ -147,3 +101,28 @@ def File_viewAsWeb(self):
data=next_data data=next_data
return '' return ''
def WebSite_viewAsWebPost(self, *args, **kwargs):
portal = self.getPortalObject()
sha512sum = hashlib.sha512()
self.REQUEST._file.seek(0)
while True:
d = self.REQUEST._file.read(1<<20)
if not d:
break
sha512sum.update(d)
sha512sum = sha512sum.hexdigest()
document = portal.portal_contributions.newContent(data=self.REQUEST.BODY,
filename='shacache', discover_metadata=False, reference=sha512sum,
content_type='application/octet-stream')
# We can only change the state of the object after all the activities and
# interaction workflow, to avoid any security problem.
document.activate(after_path_and_method_id=(document.getPath(), \
('convertToBaseFormat', 'Document_tryToConvertToBaseFormat', \
'immediateReindexObject', 'recursiveImmediateReindexObject')))\
.publish()
self.REQUEST.RESPONSE.setStatus(201)
return sha512sum
...@@ -7,10 +7,6 @@ ...@@ -7,10 +7,6 @@
<skin_folder>erp5_web_shacache</skin_folder> <skin_folder>erp5_web_shacache</skin_folder>
<skin_selection>SHACACHE</skin_selection> <skin_selection>SHACACHE</skin_selection>
</skin_folder_selection> </skin_folder_selection>
<skin_folder_selection>
<skin_folder>erp5_web_shacache_core</skin_folder>
<skin_selection>View,SHACACHE</skin_selection>
</skin_folder_selection>
<skin_folder_selection> <skin_folder_selection>
<skin_folder>erp5_xhtml_style</skin_folder> <skin_folder>erp5_xhtml_style</skin_folder>
<skin_selection>SHACACHE</skin_selection> <skin_selection>SHACACHE</skin_selection>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<dictionary> <dictionary>
<item> <item>
<key> <string>_function</string> </key> <key> <string>_function</string> </key>
<value> <string>WebSection_setObject</string> </value> <value> <string>WebSite_viewAsWebPost</string> </value>
</item> </item>
<item> <item>
<key> <string>_module</string> </key> <key> <string>_module</string> </key>
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Base_setObject</string> </value> <value> <string>WebSite_viewAsWebPost</string> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>portal = context.getPortalObject()\n
if portal.portal_workflow.isTransitionPossible(context, \'publish\'):\n
context.publish()\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>WebSite_publishDocumentByActivity</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -28,8 +28,9 @@ ...@@ -28,8 +28,9 @@
############################################################################## ##############################################################################
import base64
import hashlib import hashlib
import random
class ShaCacheMixin(object): class ShaCacheMixin(object):
""" """
...@@ -56,21 +57,15 @@ class ShaCacheMixin(object): ...@@ -56,21 +57,15 @@ class ShaCacheMixin(object):
""" """
self.login() self.login()
self.portal = self.getPortal() self.portal = self.getPortal()
module = self.portal.web_site_module module = self.portal.web_site_module
shacache = getattr(module, 'shacache', None) self.shacache = module.newContent(portal_type='Web Site',
if shacache is None: title='SHA Cache Server', skin_selection_name='SHACACHE')
shacache = module.newContent(portal_type='Web Site', self.shacache.publish()
id='shacache', self.header_dict = {
title='SHA Cache Server', 'Content-Type': 'application/json',
skin_selection_name='SHACACHE') 'Authorization': 'Basic %s' % (base64.encodestring('ERP5TypeTestCase:'))
}
isTransitionPossible = self.portal.portal_workflow.isTransitionPossible self.shacache_url = self.shacache.absolute_url()
if isTransitionPossible(shacache, 'publish'): self.stepTic()
shacache.publish() self.data = 'Random Content. %s' % str(random.random())
self.stepTic()
self.shacache = shacache
self.data = 'Random Content. %s' % self.portal.Base_generateRandomString()
self.key = hashlib.sha512(self.data).hexdigest() self.key = hashlib.sha512(self.data).hexdigest()
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
import transaction import transaction
import httplib import httplib
from StringIO import StringIO import urlparse
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from ShaCacheMixin import ShaCacheMixin from ShaCacheMixin import ShaCacheMixin
...@@ -46,38 +46,19 @@ class TestShaCache(ShaCacheMixin, ERP5TypeTestCase): ...@@ -46,38 +46,19 @@ class TestShaCache(ShaCacheMixin, ERP5TypeTestCase):
""" """
return "SHACACHE - HTTP File Cache Server" return "SHACACHE - HTTP File Cache Server"
def beforeTearDown(self): def postFile(self, key=None):
"""
Clear everything for next test.
"""
for module in ('document_module',):
folder = self.portal[module]
folder.manage_delObjects(list(folder.objectIds()))
transaction.commit()
self.tic()
def putFile(self, key=None):
""" """
Post the file Post the file
""" """
if key is None: parsed = urlparse.urlparse(self.shacache_url)
key = self.key connection = httplib.HTTPConnection(parsed.hostname, parsed.port)
try: try:
data_file = StringIO() connection.request('POST', parsed.path, self.data, self.header_dict)
data_file.write(self.data) result = connection.getresponse()
data_file.seek(0) data = result.read()
self.portal.changeSkin('SHACACHE')
path = self.shacache.getPath()
response = self.publish('%s/%s' % (path, key),
request_method='PUT',
stdin=data_file,
basic='ERP5TypeTestCase:')
self.stepTic()
self.assertEqual(response.getStatus(), httplib.CREATED)
finally: finally:
data_file.close() connection.close()
return result.status, data
def getFile(self, key=None): def getFile(self, key=None):
""" """
...@@ -87,18 +68,30 @@ class TestShaCache(ShaCacheMixin, ERP5TypeTestCase): ...@@ -87,18 +68,30 @@ class TestShaCache(ShaCacheMixin, ERP5TypeTestCase):
if key is None: if key is None:
key = self.key key = self.key
self.portal.changeSkin('SHACACHE') parsed = urlparse.urlparse(self.shacache_url)
self.shacache.REQUEST.set('method', 'GET') connection = httplib.HTTPConnection(parsed.hostname, parsed.port)
return self.shacache.WebSection_getDocumentValue(key) try:
connection.request('GET', '/'.join([parsed.path, key]), None,
self.header_dict)
result = connection.getresponse()
data = result.read()
finally:
connection.close()
return result.status, data
def test_put_file(self): def test_put_file(self):
""" """
Check if the PUT method is creating an object. Check if the PUT method is creating an object.
""" """
self.putFile() result, data = self.postFile()
self.assertEquals(1, len(self.portal.document_module)) self.assertEqual(result, httplib.CREATED)
self.assertEqual(data, self.key)
transaction.commit()
self.tic()
document = self.portal.document_module.contentValues()[0] document = self.portal.portal_catalog.getResultValue(reference=self.key)
self.assertNotEqual(None, document)
self.assertEquals(self.key, document.getTitle()) self.assertEquals(self.key, document.getTitle())
self.assertEquals(self.key, document.getReference()) self.assertEquals(self.key, document.getReference())
self.assertEquals(self.data, document.getData()) self.assertEquals(self.data, document.getData())
...@@ -109,29 +102,39 @@ class TestShaCache(ShaCacheMixin, ERP5TypeTestCase): ...@@ -109,29 +102,39 @@ class TestShaCache(ShaCacheMixin, ERP5TypeTestCase):
""" """
Check if the file returned is the correct. Check if the file returned is the correct.
""" """
self.test_put_file() result, data = self.postFile()
self.assertEquals(1, len(self.portal.document_module)) self.assertEqual(result, httplib.CREATED)
self.assertEqual(data, self.key)
transaction.commit()
self.tic()
document = self.getFile() document = self.portal.portal_catalog.getResultValue(reference=self.key)
self.assertNotEquals(None, document) self.assertNotEqual(None, document)
self.assertEquals(self.data, document.getData()) result, data = self.getFile()
self.assertEqual(result, httplib.OK)
self.assertEquals(data, self.data)
def test_put_file_twice(self): def test_put_file_twice(self):
""" """
Check if is allowed to put the same file twice. Check if is allowed to put the same file twice.
""" """
self.putFile() self.postFile()
self.assertEquals(1, len(self.portal.document_module)) transaction.commit()
self.tic()
document = self.portal.document_module.contentValues()[0] document = self.portal.portal_catalog.getResultValue(reference=self.key)
self.assertEquals('Published', document.getValidationStateTitle()) self.assertEquals('Published', document.getValidationStateTitle())
self.putFile() self.postFile()
self.assertEquals(2, len(self.portal.document_module)) transaction.commit()
self.tic()
self.assertEquals(2, self.portal.portal_catalog.countResults(
reference=self.key)[0][0])
document2 = self.portal.document_module.contentValues()[1] document2 = self.portal.portal_catalog.getResultValue(reference=self.key,
sort_on=(('uid', 'ASC'),))
self.assertEquals('Published', document2.getValidationStateTitle()) self.assertEquals('Published', document2.getValidationStateTitle())
self.assertEquals('Archived', document.getValidationStateTitle()) self.assertEquals('archived', document.getValidationState())
47 59
\ No newline at end of file \ No newline at end of file
Web Site | web_post_shacache_view
\ No newline at end of file
erp5_web_download_theme | SHACACHE erp5_web_download_theme | SHACACHE
erp5_web_shacache | SHACACHE erp5_web_shacache | SHACACHE
erp5_web_shacache_core | SHACACHE
erp5_web_shacache_core | View
erp5_xhtml_style | SHACACHE erp5_xhtml_style | SHACACHE
\ No newline at end of file
erp5_web_shacache erp5_web_shacache
erp5_web_shacache_core \ No newline at end of file
\ No newline at end of file
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="ActionInformation" module="Products.CMFCore.ActionInformation"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
<item>
<key> <string>categories</string> </key>
<value>
<tuple>
<string>action_type/object_web_view</string>
</tuple>
</value>
</item>
<item>
<key> <string>category</string> </key>
<value> <string>object_web_view</string> </value>
</item>
<item>
<key> <string>condition</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>icon</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>web_post_shadir_view</string> </value>
</item>
<item>
<key> <string>permissions</string> </key>
<value>
<tuple>
<string>View</string>
</tuple>
</value>
</item>
<item>
<key> <string>priority</string> </key>
<value> <float>0.8</float> </value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Web Post Shacache View</string> </value>
</item>
<item>
<key> <string>visible</string> </key>
<value> <int>1</int> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>string:${object_url}/WebSite_viewAsWebPost</string> </value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="Expression" module="Products.CMFCore.Expression"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>text</string> </key>
<value> <string>python: context.getSkinSelectionName() == \'SHADIR\' and request.method == \'POST\' and object is not None and object.isWebMode() and not object.isEditableMode()</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
...@@ -104,3 +104,28 @@ def WebSection_setObject(self, id, ob, **kw): ...@@ -104,3 +104,28 @@ def WebSection_setObject(self, id, ob, **kw):
if expiration_date is not None: if expiration_date is not None:
ob.setExpirationDate(expiration_date) ob.setExpirationDate(expiration_date)
return ob return ob
def WebSection_putFactory(self, name, typ, body):
"""
API SHACACHE
- PUT /<key>
+ parameters required:
* data: it is the file content
The key is the file name.
"""
portal = self.getPortalObject()
if name is None:
name = 'shacache'
document = portal.portal_contributions.newContent(data=body,
filename=name,
discover_metadata=False)
# We can only change the state of the object after all the activities and
# interaction workflow, to avoid any security problem.
document.activate(after_path_and_method_id=(document.getPath(), \
('convertToBaseFormat', 'Document_tryToConvertToBaseFormat', \
'immediateReindexObject', 'recursiveImmediateReindexObject')))\
.publish()
return document
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
<skin_folder>erp5_web_download_theme</skin_folder> <skin_folder>erp5_web_download_theme</skin_folder>
<skin_selection>SHADIR</skin_selection> <skin_selection>SHADIR</skin_selection>
</skin_folder_selection> </skin_folder_selection>
<skin_folder_selection>
<skin_folder>erp5_web_shacache_core</skin_folder>
<skin_selection>SHADIR</skin_selection>
</skin_folder_selection>
<skin_folder_selection> <skin_folder_selection>
<skin_folder>erp5_web_shadir</skin_folder> <skin_folder>erp5_web_shadir</skin_folder>
<skin_selection>SHADIR</skin_selection> <skin_selection>SHADIR</skin_selection>
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
</item> </item>
<item> <item>
<key> <string>_module</string> </key> <key> <string>_module</string> </key>
<value> <string>ShaCache</string> </value> <value> <string>ShaDir</string> </value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
......
...@@ -2,25 +2,21 @@ ...@@ -2,25 +2,21 @@
<ZopeData> <ZopeData>
<record id="1" aka="AAAAAAAAAAE="> <record id="1" aka="AAAAAAAAAAE=">
<pickle> <pickle>
<global name="Folder" module="OFS.Folder"/> <global name="ExternalMethod" module="Products.ExternalMethod.ExternalMethod"/>
</pickle> </pickle>
<pickle> <pickle>
<dictionary> <dictionary>
<item> <item>
<key> <string>_local_properties</string> </key> <key> <string>_function</string> </key>
<value> <value> <string>WebSite_viewAsWebPost</string> </value>
<tuple/>
</value>
</item> </item>
<item> <item>
<key> <string>_objects</string> </key> <key> <string>_module</string> </key>
<value> <value> <string>ShaDir</string> </value>
<tuple/>
</value>
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>erp5_web_shacache_core</string> </value> <value> <string>WebSite_viewAsWebPost</string> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -27,10 +27,11 @@ ...@@ -27,10 +27,11 @@
# #
############################################################################## ##############################################################################
import base64
import hashlib import hashlib
import json import json
import platform import platform
import random
from DateTime import DateTime from DateTime import DateTime
...@@ -64,7 +65,7 @@ class ShaDirMixin(object): ...@@ -64,7 +65,7 @@ class ShaDirMixin(object):
self.login() self.login()
self.portal = self.getPortal() self.portal = self.getPortal()
self.key = self.portal.Base_generateRandomString() self.key = 'mykey' + str(random.random())
self.file_name = 'file.txt' self.file_name = 'file.txt'
self.urlmd5 = hashlib.md5(self.key).hexdigest() self.urlmd5 = hashlib.md5(self.key).hexdigest()
self.file_content = 'This is the content.' self.file_content = 'This is the content.'
...@@ -88,18 +89,14 @@ class ShaDirMixin(object): ...@@ -88,18 +89,14 @@ class ShaDirMixin(object):
self.data = json.dumps(self.data_list) self.data = json.dumps(self.data_list)
self.sha512sum = hashlib.sha512(self.data).hexdigest() self.sha512sum = hashlib.sha512(self.data).hexdigest()
module = self.portal.web_site_module self.header_dict = {
shadir = getattr(module, 'shadir', None) 'Content-Type': 'application/json',
if shadir is None: 'Authorization': 'Basic %s' % (base64.encodestring('ERP5TypeTestCase:'))
shadir = module.newContent(portal_type='Web Site', }
id='shadir',
title='SHA Dir Server',
skin_selection_name='SHADIR')
isTransitionPossible = self.portal.portal_workflow.isTransitionPossible module = self.portal.web_site_module
if isTransitionPossible(shadir, 'publish'): self.shadir = module.newContent(portal_type='Web Site',
shadir.publish() title='SHA Dir Server', skin_selection_name='SHADIR')
self.stepTic() self.shadir.publish()
self.shadir_url = self.shadir.absolute_url()
self.shadir = shadir self.stepTic()
...@@ -29,10 +29,11 @@ ...@@ -29,10 +29,11 @@
import httplib import httplib
import urlparse
import json import json
import transaction import transaction
import random
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
from StringIO import StringIO
from ShaDirMixin import ShaDirMixin from ShaDirMixin import ShaDirMixin
...@@ -47,41 +48,37 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -47,41 +48,37 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
""" """
return "SHADIR - HTTP Information Cache Server" return "SHADIR - HTTP Information Cache Server"
def postInformation(self, key=None): def postInformation(self, key=None, data=None):
""" """
Post the information calling the Python Script. Post the information calling the Python Script.
It simulates the real usage. It simulates the real usage.
""" """
if key is None: parsed = urlparse.urlparse(self.shadir_url)
key = self.key connection = httplib.HTTPConnection(parsed.hostname, parsed.port)
try: try:
data_file = StringIO() connection.request('PUT', '/'.join([parsed.path, key or self.key]),
data_file.write(self.data) data or self.data, self.header_dict)
data_file.seek(0) result = connection.getresponse()
data = result.read()
self.portal.changeSkin('SHADIR')
path = self.shadir.getPath()
response = self.publish('%s/%s' % (path, key),
request_method='PUT',
stdin=data_file,
basic='ERP5TypeTestCase:')
self.stepTic()
self.assertEqual(response.getStatus(), httplib.CREATED)
finally: finally:
data_file.close() connection.close()
return result.status, data
def getInformation(self, key=None): def getInformation(self, key=None):
""" """
Get the information calling the Python Script. Get the information calling the Python Script.
It simulates the real usage. It simulates the real usage.
""" """
if key is None: parsed = urlparse.urlparse(self.shadir_url)
key = self.key connection = httplib.HTTPConnection(parsed.hostname, parsed.port)
try:
self.portal.changeSkin('SHADIR') connection.request('GET', '/'.join([parsed.path, key or self.key]),
self.shadir.REQUEST.set('method', 'GET') self.data, self.header_dict)
return self.shadir.WebSection_getDocumentValue(key) result = connection.getresponse()
data = result.read()
finally:
connection.close()
return result.status, data
def beforeTearDown(self): def beforeTearDown(self):
""" """
...@@ -99,15 +96,23 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -99,15 +96,23 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
""" """
Check if posting information is working. Check if posting information is working.
""" """
self.postInformation() result, data = self.postInformation()
self.assertEqual(result, httplib.CREATED)
self.assertEqual(data, '')
transaction.commit()
self.tic()
# Asserting Data Set # Asserting Data Set
data_set = self.portal.data_set_module.contentValues()[0] data_set = self.portal.portal_catalog.getResultValue(
reference=self.key)
self.assertEquals(self.key, data_set.getReference()) self.assertEquals(self.key, data_set.getReference())
self.assertEquals('Published', data_set.getValidationStateTitle()) self.assertEquals('published', data_set.getValidationState())
# Asserting Document # Asserting Document
document = self.portal.document_module.contentValues()[0] document = self.portal.portal_catalog.getResultValue(
reference=self.sha512sum)
self.assertEquals(self.sha512sum, document.getTitle()) self.assertEquals(self.sha512sum, document.getTitle())
self.assertEquals(self.sha512sum, document.getReference()) self.assertEquals(self.sha512sum, document.getReference())
self.assertEquals(self.data, document.getData()) self.assertEquals(self.data, document.getData())
...@@ -123,10 +128,12 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -123,10 +128,12 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
""" """
self.postInformation() self.postInformation()
document = self.getInformation() transaction.commit()
self.assertNotEquals(None, document) self.tic()
result, data = self.getInformation()
self.assertEqual(result, httplib.OK)
data = document.getData()
information_list = json.loads(data) information_list = json.loads(data)
self.assertEquals(1, len(information_list)) self.assertEquals(1, len(information_list))
...@@ -136,20 +143,23 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -136,20 +143,23 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
""" """
Check if posting information is working. Check if posting information is working.
""" """
self.assertEquals(0, len(self.portal.data_set_module))
self.assertEquals(0, len(self.portal.document_module))
self.postInformation() self.postInformation()
for x in xrange(10): transaction.commit()
self.postInformation() self.tic()
self.postInformation()
transaction.commit()
self.tic()
self.assertEquals(1, len(self.portal.data_set_module)) self.assertEqual(1, self.portal.portal_catalog.countResults(
data_set = self.portal.data_set_module.contentValues()[0] reference=self.key)[0][0])
self.assertEquals(self.key, data_set.getReference()) data_set = self.portal.portal_catalog.getResultValue(
self.assertEquals('Published', data_set.getValidationStateTitle()) reference=self.key)
self.assertEqual(self.key, data_set.getReference())
self.assertEqual('published', data_set.getValidationState())
self.assertEquals(11, len(self.portal.document_module)) self.assertEqual(2, self.portal.portal_catalog.countResults(
reference=self.sha512sum)[0][0])
def test_get_information_for_single_data_set(self): def test_get_information_for_single_data_set(self):
""" """
...@@ -157,10 +167,10 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -157,10 +167,10 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
""" """
self.postInformation() self.postInformation()
document = self.getInformation() transaction.commit()
self.assertNotEquals(None, document) self.tic()
result, data = self.getInformation()
data = document.getData() self.assertEqual(result, httplib.OK)
information_list = json.loads(data) information_list = json.loads(data)
self.assertEquals(1, len(information_list)) self.assertEquals(1, len(information_list))
...@@ -168,7 +178,7 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -168,7 +178,7 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
def test_get_information_from_different_data_set(self): def test_get_information_from_different_data_set(self):
""" """
POST information to /information and to /information2 POST information with two different keys
It must create two Data Set and two Text documents. It must create two Data Set and two Text documents.
When the user retrieve the content of a given key, When the user retrieve the content of a given key,
...@@ -176,26 +186,45 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase): ...@@ -176,26 +186,45 @@ class TestShaDir(ShaDirMixin, ERP5TypeTestCase):
This relation is controlled by Data Set object. This relation is controlled by Data Set object.
""" """
self.assertEquals(0, len(self.portal.data_set_module))
self.assertEquals(0, len(self.portal.document_module))
self.postInformation() self.postInformation()
self.assertEquals(1, len(self.portal.data_set_module))
self.assertEquals(1, len(self.portal.document_module))
self.postInformation(key='information2') transaction.commit()
self.tic()
urlmd5_2 = 'anotherurlmd5' + str(random.random())
sha512_2 = 'anothersha512_2' + str(random.random())
key_2 = 'another_key' + str(random.random())
data_list_2 = [{'file': self.file_name,
'urlmd5': urlmd5_2,
'sha512': sha512_2,
'creation_date': str(self.creation_date),
'expiration_date': str(self.expiration_date),
'distribution': self.distribution,
'architecture': self.architecture},
"User SIGNATURE goes here."]
data_2 = json.dumps(data_list_2)
result, data = self.postInformation(key_2, data_2)
self.assertEqual(result, httplib.CREATED)
transaction.commit()
self.tic()
self.assertEquals(2, len(self.portal.data_set_module)) self.assertEquals(2, len(self.portal.data_set_module))
self.assertEquals(2, len(self.portal.document_module)) self.assertEquals(2, len(self.portal.document_module))
document = self.getInformation() result, document = self.getInformation()
self.assertEquals(1, len(json.loads(document.getData()))) self.assertEquals(1, len(json.loads(document)))
document2 = self.getInformation('information2') result, document2 = self.getInformation(key_2)
self.assertEquals(1, len(json.loads(document2.getData()))) self.assertEquals(1, len(json.loads(document2)))
self.postInformation() result, data = self.postInformation()
self.assertEqual(result, httplib.CREATED)
transaction.commit()
self.tic()
self.assertEquals(2, len(self.portal.data_set_module)) self.assertEquals(2, len(self.portal.data_set_module))
self.assertEquals(3, len(self.portal.document_module)) self.assertEquals(3, len(self.portal.document_module))
document3 = self.getInformation() result, document3 = self.getInformation()
self.assertEquals(2, len(json.loads(document3.getData()))) self.assertEquals(2, len(json.loads(document3)))
46 59
\ No newline at end of file \ No newline at end of file
Web Site | web_post_shadir_view
\ No newline at end of file
erp5_web_download_theme | SHADIR erp5_web_download_theme | SHADIR
erp5_web_shacache_core | SHADIR
erp5_web_shadir | SHADIR erp5_web_shadir | SHADIR
erp5_xhtml_style | SHADIR erp5_xhtml_style | SHADIR
\ No newline at end of file
...@@ -60,20 +60,14 @@ class ShaSecurityMixin(object): ...@@ -60,20 +60,14 @@ class ShaSecurityMixin(object):
self.stepTic() self.stepTic()
create = True create = True
start_date = '10/10/2000'
stop_date = '10/10/2100'
group=self.group group=self.group
for assignment in person.contentValues(portal_type="Assignment"): for assignment in person.contentValues(portal_type="Assignment"):
if assignment.getStartDate() == start_date and \ if assignment.getGroup() == self.group:
assignment.getStopDate() == stop_date and \
assignment.getGroup() == self.group:
create = False create = False
if create: if create:
assignment = person.newContent(portal_type='Assignment') assignment = person.newContent(portal_type='Assignment')
assignment.edit(start_date=start_date, assignment.edit(group=self.group)
stop_date=stop_date,
group=self.group)
assignment.open() assignment.open()
self.stepTic() self.stepTic()
......
20 21
\ No newline at end of file \ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment