[extensions-web] Fix metadata.json replacement in the zipfile and add tests.
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [extensions-web] Fix metadata.json replacement in the zipfile and add tests.
- Date: Fri, 30 Sep 2011 17:40:08 +0000 (UTC)
commit 074b7823eca4091859c96dc8b1bc0660bfefee61
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Tue Sep 27 15:22:35 2011 -0400
Fix metadata.json replacement in the zipfile and add tests.
sweettooth/extensions/models.py | 26 +++++++++-
.../extensions/testdata/LotsOfFiles/Craig.jpg | Bin 0 -> 80711 bytes
.../testdata/LotsOfFiles/LotsOfFiles.zip | Bin 0 -> 82309 bytes
sweettooth/extensions/testdata/LotsOfFiles/README | 4 ++
.../extensions/testdata/LotsOfFiles/extension.js | 7 +++
.../extensions/testdata/LotsOfFiles/metadata.json | 6 ++
.../testdata/LotsOfFiles/subdirectory/test.txt | 3 +
.../LotsOfFiles/subdirectory/test2/test.txt | 2 +
sweettooth/extensions/tests.py | 50 +++++++++++++++++++-
9 files changed, 95 insertions(+), 3 deletions(-)
---
diff --git a/sweettooth/extensions/models.py b/sweettooth/extensions/models.py
index 92a9002..0be22d9 100644
--- a/sweettooth/extensions/models.py
+++ b/sweettooth/extensions/models.py
@@ -193,6 +193,9 @@ class ExtensionVersion(models.Model):
data.update(fields)
return data
+ def make_metadata_json_string(self):
+ return json.dumps(self.make_metadata_json(), sort_keys=True, indent=2)
+
def get_zipfile(self, mode):
return ZipFile(self.source.storage.path(self.source.name), mode)
@@ -201,9 +204,28 @@ class ExtensionVersion(models.Model):
In the uploaded extension zipfile, edit metadata.json
to reflect the new contents.
"""
- zipfile = self.get_zipfile("a")
+
+ # We can't easily *replace* files in a zipfile
+ # archive. See http://bugs.python.org/issue6818.
+ # Just read all the contents from the old zipfile
+ # into memory and then emit a new one with the
+ # generated metadata.json
+ zipfile_in = self.get_zipfile("r")
+
+ filemap = {}
+ for info in zipfile_in.infolist():
+ if info.filename == "metadata.json":
+ continue
+
+ contents = zipfile_in.read(info)
+ filemap[info] = contents
+
+ zipfile = self.get_zipfile("w")
+ for info, contents in filemap.iteritems():
+ zipfile.writestr(info, contents)
+
metadata = self.make_metadata_json()
- zipfile.writestr("metadata.json", json.dumps(metadata, sort_keys=True, indent=2))
+ zipfile.writestr("metadata.json", self.make_metadata_json_string())
zipfile.close()
def parse_metadata_json(self, metadata):
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/Craig.jpg b/sweettooth/extensions/testdata/LotsOfFiles/Craig.jpg
new file mode 100644
index 0000000..ead9ce9
Binary files /dev/null and b/sweettooth/extensions/testdata/LotsOfFiles/Craig.jpg differ
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/LotsOfFiles.zip b/sweettooth/extensions/testdata/LotsOfFiles/LotsOfFiles.zip
new file mode 100644
index 0000000..51eee66
Binary files /dev/null and b/sweettooth/extensions/testdata/LotsOfFiles/LotsOfFiles.zip differ
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/README b/sweettooth/extensions/testdata/LotsOfFiles/README
new file mode 100644
index 0000000..7b8111f
--- /dev/null
+++ b/sweettooth/extensions/testdata/LotsOfFiles/README
@@ -0,0 +1,4 @@
+This is intended to test the metadata zipfile replacement with binary files and subdirs.
+
+Craig.jpg is an old file on my disk that's my go-to "I need an image to test with" file.
+I have no idea about its origins. if you know, I'd love to know.
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/extension.js b/sweettooth/extensions/testdata/LotsOfFiles/extension.js
new file mode 100644
index 0000000..bf9c324
--- /dev/null
+++ b/sweettooth/extensions/testdata/LotsOfFiles/extension.js
@@ -0,0 +1,7 @@
+// This is a dumb file.
+
+function init() {
+}
+
+var enable, disable;
+enable = disable = init;
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/metadata.json b/sweettooth/extensions/testdata/LotsOfFiles/metadata.json
new file mode 100644
index 0000000..590a368
--- /dev/null
+++ b/sweettooth/extensions/testdata/LotsOfFiles/metadata.json
@@ -0,0 +1,6 @@
+{
+ "uuid": "test-extension gnome org",
+ "name": "Test Extension",
+ "description": "Simple test metadata",
+ "url": "http://test-metadata.gnome.org"
+}
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/subdirectory/test.txt b/sweettooth/extensions/testdata/LotsOfFiles/subdirectory/test.txt
new file mode 100644
index 0000000..89ac2b1
--- /dev/null
+++ b/sweettooth/extensions/testdata/LotsOfFiles/subdirectory/test.txt
@@ -0,0 +1,3 @@
+
+testing subdirs
+
diff --git a/sweettooth/extensions/testdata/LotsOfFiles/subdirectory/test2/test.txt b/sweettooth/extensions/testdata/LotsOfFiles/subdirectory/test2/test.txt
new file mode 100644
index 0000000..0d21fec
--- /dev/null
+++ b/sweettooth/extensions/testdata/LotsOfFiles/subdirectory/test2/test.txt
@@ -0,0 +1,2 @@
+
+testing one more time
diff --git a/sweettooth/extensions/tests.py b/sweettooth/extensions/tests.py
index 0fbb218..c7b4835 100644
--- a/sweettooth/extensions/tests.py
+++ b/sweettooth/extensions/tests.py
@@ -1,9 +1,12 @@
import json
import os.path
+import tempfile
+from zipfile import ZipFile
from django.test import TestCase
from django.test.client import Client
+from django.core.files.base import File
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User
from extensions import models
@@ -11,7 +14,13 @@ from extensions import models
testdata_dir = os.path.join(os.path.dirname(__file__), 'testdata')
def get_test_zipfile(testname):
- return open(os.path.join(testdata_dir, testname, testname + ".zip"), 'rb')
+ original = open(os.path.join(testdata_dir, testname, testname + ".zip"), 'rb')
+ new_temp = tempfile.NamedTemporaryFile(suffix=testname + ".zip.temp")
+ new_temp.write(original.read())
+ new_temp.seek(0)
+ original.close()
+
+ return new_temp
class UploadTest(TestCase):
def setUp(self):
@@ -63,6 +72,45 @@ class UploadTest(TestCase):
self.assertTrue("description" not in extra)
self.assertTrue("url" not in extra)
+class ReplaceMetadataTest(TestCase):
+ def setUp(self):
+ self.username = 'TestUser1'
+ self.email = 'non-existant non-existant tld'
+ self.password = 'a random password'
+ self.user = User.objects.create_user(self.username, self.email, self.password)
+
+ def test_replace_metadata(self):
+ extension = models.Extension(creator=self.user)
+ version = models.ExtensionVersion()
+ version.extension = extension
+
+ old_zip_file = get_test_zipfile('LotsOfFiles')
+
+ metadata = models.parse_zipfile_metadata(old_zip_file)
+ old_zip_file.seek(0)
+
+ version.source = File(old_zip_file)
+
+ version.parse_metadata_json(metadata)
+ version.replace_metadata_json()
+ new_zip = version.get_zipfile('r')
+
+ old_zip = ZipFile(File(old_zip_file), 'r')
+ self.assertEqual(len(old_zip.infolist()), len(new_zip.infolist()))
+ self.assertEqual(new_zip.read("metadata.json"),
+ version.make_metadata_json_string())
+
+ for old_info in old_zip.infolist():
+ if old_info.filename == "metadata.json":
+ continue
+
+ new_info = new_zip.getinfo(old_info.filename)
+ self.assertEqual(old_zip.read(old_info), new_zip.read(new_info))
+ self.assertEqual(old_info.date_time, new_info.date_time)
+
+ old_zip.close()
+ new_zip.close()
+
class UploadTest(TestCase):
def setUp(self):
self.username = 'TestUser1'
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]