class TestFileViewer(TestCase): def setUp(self): super(TestFileViewer, self).setUp() self.viewer = FileViewer(make_file(1, get_file('dictionary-test.xpi'))) def tearDown(self): self.viewer.cleanup() super(TestFileViewer, self).tearDown() def test_files_not_extracted(self): assert not self.viewer.is_extracted() def test_files_extracted(self): self.viewer.extract() assert self.viewer.is_extracted() def test_recurse_extract(self): self.viewer.src = get_file('recurse.xpi') self.viewer.extract() assert self.viewer.is_extracted() def test_recurse_contents(self): self.viewer.src = get_file('recurse.xpi') self.viewer.extract() files = self.viewer.get_files() file_list = [ 'recurse/recurse.xpi/chrome/test-root.txt', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar/test' ] for name in file_list: assert name in files def test_recurse_contents_of_zip(self): self.viewer.src = get_file('recurse.zip') self.viewer.extract() files = self.viewer.get_files() file_list = [ 'recurse/recurse.xpi/chrome/test-root.txt', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar/test' ] for name in file_list: assert name in files def test_locked(self): self.viewer.src = get_file('dictionary-test.xpi') # Lock was successfully attained assert self.viewer.extract() lock = flufl.lock.Lock( os.path.join(settings.TMP_PATH, 'file-viewer-%s.lock' % self.viewer.file.pk)) assert not lock.is_locked lock.lock() assert lock.is_locked # Not extracting, the viewer is locked, lock could not be attained assert not self.viewer.extract() def test_extract_file_locked_message(self): self.viewer.src = get_file('dictionary-test.xpi') assert not self.viewer.is_extracted() lock = flufl.lock.Lock( os.path.join(settings.TMP_PATH, 'file-viewer-%s.lock' % self.viewer.file.pk)) assert not lock.is_locked lock.lock() assert lock.is_locked msg = extract_file(self.viewer) assert str(msg.get()).startswith(u'File viewer is locked') msg.delete() def test_cleanup(self): self.viewer.extract() self.viewer.cleanup() assert not self.viewer.is_extracted() @freeze_time('2017-01-08 02:01:00') def test_dest(self): viewer = FileViewer(make_file(1, get_file('webextension.xpi'))) assert viewer.dest == os.path.join(settings.TMP_PATH, 'file_viewer', '0108', str(self.viewer.file.pk)) def test_isbinary(self): binary = self.viewer._is_binary for f in [ 'foo.rdf', 'foo.xml', 'foo.js', 'foo.py' 'foo.html', 'foo.txt', 'foo.dtd', 'foo.xul', 'foo.sh', 'foo.properties', 'foo.json', 'foo.src', 'CHANGELOG' ]: m, encoding = mimetypes.guess_type(f) assert not binary(m, f), '%s should not be binary' % f for f in ['foo.png', 'foo.gif', 'foo.exe', 'foo.swf']: m, encoding = mimetypes.guess_type(f) assert binary(m, f), '%s should be binary' % f filename = os.path.join(settings.TMP_PATH, 'test_isbinary') for txt in ['#!/usr/bin/python', '#python', u'\0x2']: open(filename, 'w').write(txt) m, encoding = mimetypes.guess_type(filename) assert not binary(m, filename), '%s should not be binary' % txt for txt in ['MZ']: open(filename, 'w').write(txt) m, encoding = mimetypes.guess_type(filename) assert binary(m, filename), '%s should be binary' % txt os.remove(filename) def test_truncate(self): truncate = self.viewer.truncate for x, y in ( ['foo.rdf', 'foo.rdf'], ['somelongfilename.rdf', 'somelongfilenam...rdf'], [u'unicode삮.txt', u'unicode\uc0ae.txt'], [u'unicodesomelong삮.txt', u'unicodesomelong...txt'], [ 'somelongfilename.somelongextension', 'somelongfilenam...somelonge..' ], ): assert truncate(x) == y def test_get_files_not_extracted(self): assert not self.viewer.get_files() def test_get_files_size(self): self.viewer.extract() files = self.viewer.get_files() assert len(files) == 14 def test_get_files_directory(self): self.viewer.extract() files = self.viewer.get_files() assert not files['install.js']['directory'] assert not files['install.js']['binary'] assert files['__MACOSX']['directory'] assert not files['__MACOSX']['binary'] def test_url_file(self): self.viewer.extract() files = self.viewer.get_files() url = reverse('files.list', args=[self.viewer.file.id, 'file', 'install.js']) file_url = files['install.js']['url'] assert file_url == url assert file_url.startswith('/en-US') # Make sure that the locale is properly used (see bug 1168794). with self.activate('fr'): self.viewer._files = {} # Reset the viewer's internal cache. files = self.viewer.get_files() url = reverse('files.list', args=[self.viewer.file.id, 'file', 'install.js']) file_url = files['install.js']['url'] assert file_url == url assert file_url.startswith('/fr') def test_get_files_depth(self): self.viewer.extract() files = self.viewer.get_files() assert files['dictionaries/license.txt']['depth'] == 1 def test_bom(self): dest = os.path.join(settings.TMP_PATH, 'test_bom') open(dest, 'w').write('foo'.encode('utf-16')) self.viewer.select('foo') self.viewer.selected = {'full': dest, 'size': 1} assert self.viewer.read_file() == u'foo' os.remove(dest) def test_syntax(self): for filename, syntax in [('foo.rdf', 'xml'), ('foo.xul', 'xml'), ('foo.json', 'js'), ('foo.jsm', 'js'), ('foo.htm', 'html'), ('foo.bar', 'plain'), ('foo.diff', 'plain')]: assert self.viewer.get_syntax(filename) == syntax def test_file_order(self): self.viewer.extract() dest = self.viewer.dest open(os.path.join(dest, 'chrome.manifest'), 'w') subdir = os.path.join(dest, 'chrome') os.mkdir(subdir) open(os.path.join(subdir, 'foo'), 'w') cache.clear() files = self.viewer.get_files().keys() rt = files.index(u'chrome') assert files[rt:rt + 3] == [u'chrome', u'chrome/foo', u'dictionaries'] @patch.object(settings, 'FILE_VIEWER_SIZE_LIMIT', 5) def test_file_size(self): self.viewer.extract() self.viewer.get_files() self.viewer.select('install.js') res = self.viewer.read_file() assert res == '' assert self.viewer.selected['msg'].startswith('File size is') @patch.object(settings, 'FILE_VIEWER_SIZE_LIMIT', 5) def test_file_size_unicode(self): with self.activate(locale='he'): self.viewer.extract() self.viewer.get_files() self.viewer.select('install.js') res = self.viewer.read_file() assert res == '' assert self.viewer.selected['msg'].startswith('File size is') @patch.object(settings, 'FILE_UNZIP_SIZE_LIMIT', 5) def test_contents_size(self): self.assertRaises(forms.ValidationError, self.viewer.extract) def test_default(self): self.viewer.extract() assert self.viewer.get_default(None) == 'install.rdf' def test_default_webextension(self): viewer = FileViewer(make_file(2, get_file('webextension.xpi'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_webextension_zip(self): viewer = FileViewer(make_file(2, get_file('webextension_no_id.zip'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_webextension_crx(self): viewer = FileViewer(make_file(2, get_file('webextension.crx'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_package_json(self): viewer = FileViewer(make_file(3, get_file('new-format-0.0.1.xpi'))) viewer.extract() assert viewer.get_default(None) == 'package.json' def test_delete_mid_read(self): self.viewer.extract() self.viewer.select('install.js') os.remove(os.path.join(self.viewer.dest, 'install.js')) res = self.viewer.read_file() assert res == '' assert self.viewer.selected['msg'].startswith('That file no') @patch('olympia.files.helpers.get_sha256') def test_delete_mid_tree(self, get_sha256): get_sha256.side_effect = IOError('ow') self.viewer.extract() assert {} == self.viewer.get_files() @patch('olympia.files.helpers.os.fsync') def test_verify_files_doesnt_call_fsync_regularly(self, fsync): self.viewer.extract() assert not fsync.called @patch('olympia.files.helpers.os.fsync') def test_verify_files_calls_fsync_on_differences(self, fsync): self.viewer.extract() assert not fsync.called files_to_verify = get_all_files(self.viewer.dest) files_to_verify.pop() with patch('olympia.files.helpers.get_all_files') as get_all_files_mck: get_all_files_mck.return_value = files_to_verify with pytest.raises(ValueError): # We don't put things back into place after fsync # so a `ValueError` is raised self.viewer._verify_files(files_to_verify) assert len(fsync.call_args_list) == len(files_to_verify) + 1
class TestFileHelper(TestCase): def setUp(self): super(TestFileHelper, self).setUp() self.viewer = FileViewer(make_file(1, get_file('dictionary-test.xpi'))) def tearDown(self): self.viewer.cleanup() super(TestFileHelper, self).tearDown() def test_files_not_extracted(self): eq_(self.viewer.is_extracted(), False) def test_files_extracted(self): self.viewer.extract() eq_(self.viewer.is_extracted(), True) def test_recurse_extract(self): self.viewer.src = get_file('recurse.xpi') self.viewer.extract() eq_(self.viewer.is_extracted(), True) def test_recurse_contents(self): self.viewer.src = get_file('recurse.xpi') self.viewer.extract() files = self.viewer.get_files() nm = [ 'recurse/recurse.xpi/chrome/test-root.txt', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar/test' ] for name in nm: eq_(name in files, True, 'File %r not extracted' % name) def test_cleanup(self): self.viewer.extract() self.viewer.cleanup() eq_(self.viewer.is_extracted(), False) def test_isbinary(self): binary = self.viewer._is_binary for f in [ 'foo.rdf', 'foo.xml', 'foo.js', 'foo.py' 'foo.html', 'foo.txt', 'foo.dtd', 'foo.xul', 'foo.sh', 'foo.properties', 'foo.json', 'foo.src', 'CHANGELOG' ]: m, encoding = mimetypes.guess_type(f) assert not binary(m, f), '%s should not be binary' % f for f in ['foo.png', 'foo.gif', 'foo.exe', 'foo.swf']: m, encoding = mimetypes.guess_type(f) assert binary(m, f), '%s should be binary' % f filename = os.path.join(settings.TMP_PATH, 'test_isbinary') for txt in ['#!/usr/bin/python', '#python', u'\0x2']: open(filename, 'w').write(txt) m, encoding = mimetypes.guess_type(filename) assert not binary(m, filename), '%s should not be binary' % txt for txt in ['MZ']: open(filename, 'w').write(txt) m, encoding = mimetypes.guess_type(filename) assert binary(m, filename), '%s should be binary' % txt os.remove(filename) def test_truncate(self): truncate = self.viewer.truncate for x, y in ( ['foo.rdf', 'foo.rdf'], ['somelongfilename.rdf', 'somelongfilenam...rdf'], [u'unicode삮.txt', u'unicode\uc0ae.txt'], [u'unicodesomelong삮.txt', u'unicodesomelong...txt'], [ 'somelongfilename.somelongextension', 'somelongfilenam...somelonge..' ], ): eq_(truncate(x), y) def test_get_files_not_extracted(self): assert not self.viewer.get_files() def test_get_files_size(self): self.viewer.extract() files = self.viewer.get_files() eq_(len(files), 14) def test_get_files_directory(self): self.viewer.extract() files = self.viewer.get_files() eq_(files['install.js']['directory'], False) eq_(files['install.js']['binary'], False) eq_(files['__MACOSX']['directory'], True) eq_(files['__MACOSX']['binary'], False) def test_url_file(self): self.viewer.extract() files = self.viewer.get_files() url = reverse('files.list', args=[self.viewer.file.id, 'file', 'install.js']) file_url = files['install.js']['url'] assert file_url == url assert file_url.startswith('/en-US') # Make sure that the locale is properly used (see bug 1168794). with self.activate('fr'): self.viewer._files = {} # Reset the viewer's internal cache. files = self.viewer.get_files() url = reverse('files.list', args=[self.viewer.file.id, 'file', 'install.js']) file_url = files['install.js']['url'] assert file_url == url assert file_url.startswith('/fr') def test_get_files_depth(self): self.viewer.extract() files = self.viewer.get_files() eq_(files['dictionaries/license.txt']['depth'], 1) def test_bom(self): dest = os.path.join(settings.TMP_PATH, 'test_bom') open(dest, 'w').write('foo'.encode('utf-16')) self.viewer.select('foo') self.viewer.selected = {'full': dest, 'size': 1} eq_(self.viewer.read_file(), u'foo') os.remove(dest) def test_syntax(self): for filename, syntax in [('foo.rdf', 'xml'), ('foo.xul', 'xml'), ('foo.json', 'js'), ('foo.jsm', 'js'), ('foo.bar', 'plain')]: eq_(self.viewer.get_syntax(filename), syntax) def test_file_order(self): self.viewer.extract() dest = self.viewer.dest open(os.path.join(dest, 'chrome.manifest'), 'w') subdir = os.path.join(dest, 'chrome') os.mkdir(subdir) open(os.path.join(subdir, 'foo'), 'w') cache.clear() files = self.viewer.get_files().keys() rt = files.index(u'chrome') eq_(files[rt:rt + 3], [u'chrome', u'chrome/foo', u'dictionaries']) @patch.object(settings, 'FILE_VIEWER_SIZE_LIMIT', 5) def test_file_size(self): self.viewer.extract() self.viewer.get_files() self.viewer.select('install.js') res = self.viewer.read_file() eq_(res, '') assert self.viewer.selected['msg'].startswith('File size is') @patch.object(settings, 'FILE_VIEWER_SIZE_LIMIT', 5) def test_file_size_unicode(self): with self.activate(locale='he'): self.viewer.extract() self.viewer.get_files() self.viewer.select('install.js') res = self.viewer.read_file() eq_(res, '') assert self.viewer.selected['msg'].startswith('File size is') @patch.object(settings, 'FILE_UNZIP_SIZE_LIMIT', 5) def test_contents_size(self): self.assertRaises(forms.ValidationError, self.viewer.extract) def test_default(self): self.viewer.extract() assert self.viewer.get_default(None) == 'install.rdf' def test_default_webextension(self): viewer = FileViewer(make_file(2, get_file('webextension.xpi'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_package_json(self): viewer = FileViewer(make_file(3, get_file('new-format-0.0.1.xpi'))) viewer.extract() assert viewer.get_default(None) == 'package.json' def test_delete_mid_read(self): self.viewer.extract() self.viewer.select('install.js') os.remove(os.path.join(self.viewer.dest, 'install.js')) res = self.viewer.read_file() eq_(res, '') assert self.viewer.selected['msg'].startswith('That file no') @patch('olympia.files.helpers.get_md5') def test_delete_mid_tree(self, get_md5): get_md5.side_effect = IOError('ow') self.viewer.extract() eq_({}, self.viewer.get_files())
class TestFileHelper(TestCase): def setUp(self): super(TestFileHelper, self).setUp() self.viewer = FileViewer(make_file(1, get_file('dictionary-test.xpi'))) def tearDown(self): self.viewer.cleanup() super(TestFileHelper, self).tearDown() def test_files_not_extracted(self): assert not self.viewer.is_extracted() def test_files_extracted(self): self.viewer.extract() assert self.viewer.is_extracted() def test_recurse_extract(self): self.viewer.src = get_file('recurse.xpi') self.viewer.extract() assert self.viewer.is_extracted() def test_recurse_contents(self): self.viewer.src = get_file('recurse.xpi') self.viewer.extract() files = self.viewer.get_files() file_list = [ 'recurse/recurse.xpi/chrome/test-root.txt', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar/test' ] for name in file_list: assert name in files def test_recurse_contents_of_zip(self): self.viewer.src = get_file('recurse.zip') self.viewer.extract() files = self.viewer.get_files() file_list = [ 'recurse/recurse.xpi/chrome/test-root.txt', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar', 'recurse/somejar.jar/recurse/recurse.xpi/chrome/test.jar/test' ] for name in file_list: assert name in files def test_cleanup(self): self.viewer.extract() self.viewer.cleanup() assert not self.viewer.is_extracted() def test_isbinary(self): binary = self.viewer._is_binary for f in ['foo.rdf', 'foo.xml', 'foo.js', 'foo.py' 'foo.html', 'foo.txt', 'foo.dtd', 'foo.xul', 'foo.sh', 'foo.properties', 'foo.json', 'foo.src', 'CHANGELOG']: m, encoding = mimetypes.guess_type(f) assert not binary(m, f), '%s should not be binary' % f for f in ['foo.png', 'foo.gif', 'foo.exe', 'foo.swf']: m, encoding = mimetypes.guess_type(f) assert binary(m, f), '%s should be binary' % f filename = os.path.join(settings.TMP_PATH, 'test_isbinary') for txt in ['#!/usr/bin/python', '#python', u'\0x2']: open(filename, 'w').write(txt) m, encoding = mimetypes.guess_type(filename) assert not binary(m, filename), '%s should not be binary' % txt for txt in ['MZ']: open(filename, 'w').write(txt) m, encoding = mimetypes.guess_type(filename) assert binary(m, filename), '%s should be binary' % txt os.remove(filename) def test_truncate(self): truncate = self.viewer.truncate for x, y in (['foo.rdf', 'foo.rdf'], ['somelongfilename.rdf', 'somelongfilenam...rdf'], [u'unicode삮.txt', u'unicode\uc0ae.txt'], [u'unicodesomelong삮.txt', u'unicodesomelong...txt'], ['somelongfilename.somelongextension', 'somelongfilenam...somelonge..'],): assert truncate(x) == y def test_get_files_not_extracted(self): assert not self.viewer.get_files() def test_get_files_size(self): self.viewer.extract() files = self.viewer.get_files() assert len(files) == 14 def test_get_files_directory(self): self.viewer.extract() files = self.viewer.get_files() assert not files['install.js']['directory'] assert not files['install.js']['binary'] assert files['__MACOSX']['directory'] assert not files['__MACOSX']['binary'] def test_url_file(self): self.viewer.extract() files = self.viewer.get_files() url = reverse('files.list', args=[self.viewer.file.id, 'file', 'install.js']) file_url = files['install.js']['url'] assert file_url == url assert file_url.startswith('/en-US') # Make sure that the locale is properly used (see bug 1168794). with self.activate('fr'): self.viewer._files = {} # Reset the viewer's internal cache. files = self.viewer.get_files() url = reverse('files.list', args=[self.viewer.file.id, 'file', 'install.js']) file_url = files['install.js']['url'] assert file_url == url assert file_url.startswith('/fr') def test_get_files_depth(self): self.viewer.extract() files = self.viewer.get_files() assert files['dictionaries/license.txt']['depth'] == 1 def test_bom(self): dest = os.path.join(settings.TMP_PATH, 'test_bom') open(dest, 'w').write('foo'.encode('utf-16')) self.viewer.select('foo') self.viewer.selected = {'full': dest, 'size': 1} assert self.viewer.read_file() == u'foo' os.remove(dest) def test_syntax(self): for filename, syntax in [('foo.rdf', 'xml'), ('foo.xul', 'xml'), ('foo.json', 'js'), ('foo.jsm', 'js'), ('foo.bar', 'plain')]: assert self.viewer.get_syntax(filename) == syntax def test_file_order(self): self.viewer.extract() dest = self.viewer.dest open(os.path.join(dest, 'chrome.manifest'), 'w') subdir = os.path.join(dest, 'chrome') os.mkdir(subdir) open(os.path.join(subdir, 'foo'), 'w') cache.clear() files = self.viewer.get_files().keys() rt = files.index(u'chrome') assert files[rt:rt + 3] == [u'chrome', u'chrome/foo', u'dictionaries'] @patch.object(settings, 'FILE_VIEWER_SIZE_LIMIT', 5) def test_file_size(self): self.viewer.extract() self.viewer.get_files() self.viewer.select('install.js') res = self.viewer.read_file() assert res == '' assert self.viewer.selected['msg'].startswith('File size is') @patch.object(settings, 'FILE_VIEWER_SIZE_LIMIT', 5) def test_file_size_unicode(self): with self.activate(locale='he'): self.viewer.extract() self.viewer.get_files() self.viewer.select('install.js') res = self.viewer.read_file() assert res == '' assert self.viewer.selected['msg'].startswith('File size is') @patch.object(settings, 'FILE_UNZIP_SIZE_LIMIT', 5) def test_contents_size(self): self.assertRaises(forms.ValidationError, self.viewer.extract) def test_default(self): self.viewer.extract() assert self.viewer.get_default(None) == 'install.rdf' def test_default_webextension(self): viewer = FileViewer(make_file(2, get_file('webextension.xpi'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_webextension_zip(self): viewer = FileViewer(make_file(2, get_file('webextension_no_id.zip'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_webextension_crx(self): viewer = FileViewer(make_file(2, get_file('webextension.crx'))) viewer.extract() assert viewer.get_default(None) == 'manifest.json' def test_default_package_json(self): viewer = FileViewer(make_file(3, get_file('new-format-0.0.1.xpi'))) viewer.extract() assert viewer.get_default(None) == 'package.json' def test_delete_mid_read(self): self.viewer.extract() self.viewer.select('install.js') os.remove(os.path.join(self.viewer.dest, 'install.js')) res = self.viewer.read_file() assert res == '' assert self.viewer.selected['msg'].startswith('That file no') @patch('olympia.files.helpers.get_md5') def test_delete_mid_tree(self, get_md5): get_md5.side_effect = IOError('ow') self.viewer.extract() assert {} == self.viewer.get_files()