diff --git a/test/test_handlers/api/__init__.py b/test/test_handlers/api/__init__.py new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/test/test_handlers/api/__init__.py @@ -0,0 +1 @@ + diff --git a/test/test_handlers/api/test_package_uploaders.py b/test/test_handlers/api/test_package_uploaders.py new file mode 100644 index 0000000..8fe1d58 --- /dev/null +++ b/test/test_handlers/api/test_package_uploaders.py @@ -0,0 +1,149 @@ +# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +from models.package import Package +from testcase import TestCase + +class PackageUploadersTest(TestCase): + def setUp(self): + super(PackageUploadersTest, self).setUp() + self.package = Package.new( + name='test-package', + uploaders=[self.normal_user('uploader1'), + self.normal_user('uploader2')]) + self.package.put() + + def test_create_requires_login(self): + response = self.testapp.post('/api/packages/test-package/uploaders', + {'email': self.normal_user().email()}, + status=401) + self.assert_json_error(response) + + def test_create_requires_uploader(self): + self.be_normal_oauth_user() + response = self.testapp.post('/api/packages/test-package/uploaders', + {'email': self.normal_user().email()}, + status=403) + self.assert_json_error(response) + + def test_create_requires_new_uploader(self): + self.be_normal_oauth_user('uploader1') + response = self.testapp.post( + '/api/packages/test-package/uploaders', + {'email': self.normal_user('uploader2').email()}, + status=400) + self.assert_json_error(response) + + def test_uploader_creates_new_uploader(self): + self.be_normal_oauth_user('uploader1') + response = self.testapp.post('/api/packages/test-package/uploaders', + {'email': self.normal_user().email()}) + self.assert_json_success(response) + + package = Package.get_by_key_name('test-package') + self.assertEquals(package.uploaders, [ + self.normal_user('uploader1'), + self.normal_user('uploader2'), + self.normal_user() + ]) + + def test_create_is_case_insensitive(self): + self.be_normal_oauth_user('uploader1') + response = self.testapp.post( + '/api/packages/test-package/uploaders', + {'email': self.normal_user('NAme').email()}) + self.assert_json_success(response) + + response = self.testapp.post( + '/api/packages/test-package/uploaders', + {'email': self.normal_user('naME').email()}, + status=400) + self.assert_json_error(response) + + package = Package.get_by_key_name('test-package') + self.assertEquals(package.uploaders, [ + self.normal_user('uploader1'), + self.normal_user('uploader2'), + self.normal_user('NAme') + ]) + + def test_admin_creates_new_uploader(self): + self.be_admin_oauth_user() + response = self.testapp.post('/api/packages/test-package/uploaders', + {'email': self.normal_user().email()}) + self.assert_json_success(response) + + package = Package.get_by_key_name('test-package') + self.assertEquals(package.uploaders, [ + self.normal_user('uploader1'), + self.normal_user('uploader2'), + self.normal_user() + ]) + + def test_delete_requires_login(self): + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('uploader1').email(), + status=401) + self.assert_json_error(response) + + def test_delete_requires_uploader(self): + self.be_normal_oauth_user() + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('uploader1').email(), + status=403) + self.assert_json_error(response) + + def test_cant_delete_non_uploader(self): + self.be_normal_oauth_user('uploader1') + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('non-uploader').email(), + status=400) + self.assert_json_error(response) + + def test_cant_delete_only_uploader(self): + self.package.uploaders = [self.normal_user('uploader1')] + self.package.put() + + self.be_normal_oauth_user('uploader1') + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('uploader1').email(), + status=400) + self.assert_json_error(response) + + def test_uploader_deletes_uploader(self): + self.be_normal_oauth_user('uploader1') + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('uploader1').email()) + self.assert_json_success(response) + + package = Package.get_by_key_name('test-package') + self.assertEquals( + package.uploaders, [self.normal_user('uploader2')]) + + def test_delete_is_case_insensitive(self): + self.be_normal_oauth_user('uploader1') + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('UpLoAdEr1').email()) + self.assert_json_success(response) + + package = Package.get_by_key_name('test-package') + self.assertEquals( + package.uploaders, [self.normal_user('uploader2')]) + + def test_admin_deletes_uploader(self): + self.be_admin_oauth_user() + response = self.testapp.delete( + '/api/packages/test-package/uploaders/' + + self.normal_user('uploader1').email()) + self.assert_json_success(response) + + package = Package.get_by_key_name('test-package') + self.assertEquals( + package.uploaders, [self.normal_user('uploader2')]) diff --git a/test/test_handlers/api/test_package_versions.py b/test/test_handlers/api/test_package_versions.py new file mode 100644 index 0000000..8338d5e --- /dev/null +++ b/test/test_handlers/api/test_package_versions.py @@ -0,0 +1,285 @@ +# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +import re +import json + +import handlers +from models.package import Package +from models.package_version import PackageVersion +from models.private_key import PrivateKey +from models.semantic_version import SemanticVersion +from testcase import TestCase + +class PackageVersionsTest(TestCase): + def setUp(self): + super(PackageVersionsTest, self).setUp() + self.package = Package.new( + name='test-package', + uploaders=[self.admin_user(), + self.normal_user('other-uploader')]) + self.package.put() + + def test_api_user_creates_new_package(self): + self.be_normal_oauth_user() + self.post_package_version(name='new-package', version='0.0.1') + + package = Package.get_by_key_name('new-package') + self.assertIsNotNone(package) + self.assertEqual(package.name, 'new-package') + self.assertEqual(package.uploaders, [handlers.get_current_user()]) + + version = package.version_set.get() + self.assertIsNotNone(version) + self.assertEqual(version.version, SemanticVersion('0.0.1')) + self.assertEqual(version.package.name, 'new-package') + + version = package.latest_version + self.assertIsNotNone(version) + self.assertEqual(version.version, SemanticVersion('0.0.1')) + self.assertEqual(version.package.name, 'new-package') + + self.assertEqual(package.updated, version.created) + self.assertEqual('This is a README.', version.readme.text) + + def test_api_uploadership_is_case_insensitive(self): + self.be_normal_oauth_user('NAme') + self.post_package_version(name='new-package', version='0.0.1') + + version = Package.get_by_key_name('new-package').latest_version + self.assertIsNotNone(version) + self.assertEqual(version.version, SemanticVersion('0.0.1')) + + self.be_normal_oauth_user('naME') + self.post_package_version(name='new-package', version='0.0.2') + + version = Package.get_by_key_name('new-package').latest_version + self.assertIsNotNone(version) + self.assertEqual(version.version, SemanticVersion('0.0.2')) + + def test_api_new_requires_oauth(self): + response = self.testapp.get('/api/packages/versions/new', + status=401) + self.assert_json_error(response) + # Since we didn't send any OAuth2 credentials, the WWW-Authenticate + # header shouldn't have OAuth2-specific fields. + self.assertEqual(response.headers['WWW-Authenticate'], 'Bearer') + + def test_api_new_requires_private_key(self): + self.be_admin_oauth_user() + PrivateKey.get_by_key_name('singleton').delete() + + response = self.testapp.get('/api/packages/versions/new', + status=500) + self.assert_json_error(response) + + def test_api_uploader_creates_package_version(self): + self.be_normal_oauth_user('other-uploader') + self.post_package_version('1.2.3') + + version = self.get_package_version('1.2.3') + self.assertIsNotNone(version) + self.assertEqual(version.version, SemanticVersion('1.2.3')) + self.assertEqual(version.package.name, 'test-package') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) + + def test_api_create_requires_admin(self): + self.be_normal_oauth_user() + + response = self.testapp.get('/api/packages/versions/abcd/create', + status=403) + self.assert_json_error(response) + + def test_api_create_requires_uploader(self): + Package.new(name='owned-package', + uploaders=[self.normal_user('owner')]).put() + self.be_normal_oauth_user() + + response = self.testapp.get( + '/api/packages/owned-package/versions/abcd/create', status=403) + self.assert_json_error(response) + + def test_api_create_requires_valid_id(self): + self.be_admin_oauth_user() + + response = self.testapp.get( + '/packages/versions/abcd/create.json', status=403) + self.assert_json_error(response) + + def test_api_create_requires_new_version_number(self): + self.be_admin_oauth_user() + self.package_version(self.package, '1.2.3', description='old').put() + + upload = self.upload_archive('test-package', '1.2.3', description='new') + response = self.create_package(upload, status=400) + self.assert_json_error(response) + + version = self.get_package_version('1.2.3') + self.assertEqual(version.pubspec['description'], 'old') + + def test_api_create_sets_latest_package_for_increased_version_number(self): + self.be_admin_oauth_user() + + self.post_package_version('1.2.3') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) + + self.post_package_version('1.2.4') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.4')) + + self.assert_package_updated_is_latest_version_created() + + def test_api_create_sets_latest_package_for_prerelease_versions_only(self): + self.be_admin_oauth_user() + + self.post_package_version('1.2.3-pre1') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre1')) + + self.post_package_version('1.2.3-pre0') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre1')) + + self.post_package_version('1.2.3-pre2') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre2')) + + self.assert_package_updated_is_latest_version_created() + + def test_api_create_sets_latest_package_to_old_version_over_prerelease_version(self): + self.be_admin_oauth_user() + + self.post_package_version('1.2.3-pre1') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre1')) + + self.post_package_version('1.2.0') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.0')) + + self.post_package_version('1.2.3-pre2') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.0')) + + self.assert_package_updated_is_latest_version_created() + + def test_api_create_doesnt_set_latest_package_for_decreased_version_number(self): + self.be_admin_oauth_user() + + self.post_package_version('1.2.3') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) + + self.post_package_version('1.2.2') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) + + self.assert_package_updated_is_latest_version_created() + + def test_api_create_doesnt_set_latest_package_for_prerelease_version_number(self): + self.be_admin_oauth_user() + + self.post_package_version('1.2.3') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) + + self.post_package_version('1.2.5-pre') + self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) + + self.assert_package_updated_is_latest_version_created() + + def test_api_create_sets_sort_order(self): + self.be_admin_oauth_user() + + self.post_package_version('1.2.3') + self.run_deferred_tasks() + self.assertEqual(self.get_package_version('1.2.3').sort_order, 0) + + self.post_package_version('1.2.4') + self.run_deferred_tasks() + self.assertEqual(self.get_package_version('1.2.3').sort_order, 0) + self.assertEqual(self.get_package_version('1.2.4').sort_order, 1) + + self.post_package_version('1.2.4-pre') + self.run_deferred_tasks() + self.assertEqual(self.get_package_version('1.2.3').sort_order, 0) + self.assertEqual(self.get_package_version('1.2.4-pre').sort_order, 1) + self.assertEqual(self.get_package_version('1.2.4').sort_order, 2) + + def test_api_show_package_version(self): + version = self.package_version(self.package, '1.2.3') + version.put() + + response = self.testapp.get('/api/packages/test-package/versions/1.2.3') + self.assertEqual(response.headers['Content-Type'], 'application/json') + + self.maxDiff = None + expected = self.package_version_dict('test-package', '1.2.3') + expected.update({ + 'created': version.created.isoformat(), + 'downloads': 0, + 'libraries': [], + 'uploader': self.admin_user().email() + }) + self.assertEqual(json.loads(response.body), expected) + + def test_api_dartdoc_requires_private_key(self): + self.be_admin_oauth_user() + self.post_package_version('1.2.3') + PrivateKey.get_by_key_name('singleton').delete() + + response = self.testapp.get( + '/api/packages/test-package/versions/1.2.3/new_dartdoc', + status=500) + self.assert_json_error(response) + + def test_api_dartdoc_requires_uploadership(self): + self.be_admin_oauth_user() + self.post_package_version('1.2.3') + + self.be_normal_oauth_user() + response = self.testapp.get( + '/api/packages/test-package/versions/1.2.3/new_dartdoc', + status=403) + self.assert_json_error(response) + + def test_api_uploader_gets_dartdoc_form(self): + self.be_normal_oauth_user('other-uploader') + self.post_package_version('1.2.3') + + response = self.testapp.get( + '/api/packages/test-package/versions/1.2.3/new_dartdoc') + content = json.loads(response.body) + self.assertEqual(content['fields']['key'], 'pub.dartlang.org/ns' + + '/staging/packages/test-package-1.2.3/dartdoc.json') + self.assertEqual(content['fields']['acl'], 'public-read') + + def test_api_uploader_gets_dartdoc_form_for_nonexistent_package(self): + self.be_normal_oauth_user('other-uploader') + + response = self.testapp.get( + '/packages/not-package/versions/1.2.3/new_dartdoc.json', + status=404) + self.assert_json_error(response) + + def post_package_version(self, version, name='test-package'): + response = self.create_package(self.upload_archive(name, version)) + self.assert_json_success(response) + + def create_package(self, upload, status=None): + get_response = self.testapp.get('/api/packages/versions/new') + self.assertEqual(get_response.status_int, 200) + content = json.loads(get_response.body) + post_response = self.testapp.post(str(content['url']), + content['fields'], + upload_files=[upload]) + + self.assertEqual(post_response.status_int, 302) + self.assertTrue(re.match( + r'^http://localhost:80/api/packages/versions/[^/]+/create$', + post_response.headers['Location'])) + + path = post_response.headers['Location'].replace( + 'http://localhost:80', '') + return self.testapp.get(path, status=status) + + def latest_version(self): + return Package.get_by_key_name('test-package').latest_version.version + + def get_package_version(self, version): + return PackageVersion.get_by_name_and_version('test-package', version) + + def assert_package_updated_is_latest_version_created(self): + package = Package.get_by_key_name('test-package') + self.assertEqual(package.updated, package.latest_version.created) diff --git a/test/test_handlers/api/test_packages.py b/test/test_handlers/api/test_packages.py new file mode 100644 index 0000000..f5d2206 --- /dev/null +++ b/test/test_handlers/api/test_packages.py @@ -0,0 +1,136 @@ +# Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +import json + +from models.package import Package +from testcase import TestCase + +class PackagesTest(TestCase): + def test_api_index_lists_packages_in_update_order(self): + self.be_admin_user() + + packages = ['armadillo', 'zebra', 'mongoose', 'snail'] + + for package in packages: + self.create_package(package, '1.0.0') + + # Make update time different than create time + self.set_latest_version('mongoose', '1.0.1') + + self.be_normal_user() + + response = self.testapp.get('/api/packages') + self.assertEqual(response.headers['Content-Type'], 'application/json') + result = json.loads(response.body) + + self.assertEqual(result['prev_url'], None) + self.assertEqual(result['next_url'], None) + self.assertEqual(result['pages'], 1) + + self.assertEqual(result['packages'][0]['name'], 'mongoose') + self.assertEqual(result['packages'][0]['latest']['version'], '1.0.1') + self.assertEqual(result['packages'][1]['name'], 'snail') + self.assertEqual(result['packages'][2]['name'], 'zebra') + self.assertEqual(result['packages'][3]['name'], 'armadillo') + + def test_api_index_lists_one_page_of_packages(self): + self.be_admin_user() + + packages = ['package%d' % i for i in range(0, 100)] + + for package in packages: + self.create_package(package, '1.0.0') + + self.be_normal_user() + + response = self.testapp.get('/api/packages') + self.assertEqual(response.headers['Content-Type'], 'application/json') + result = json.loads(response.body) + + self.assertEqual( + result['next_url'], 'http://localhost:80/api/packages?page=2') + self.assertEqual(result['prev_url'], None) + self.assertEqual(result['pages'], 2) + + for i in range(0, 50): + self.assertEqual(result['packages'][i]['name'], + 'package%d' % (99 - i)) + + def test_api_index_lists_second_page_of_packages(self): + self.be_admin_user() + + packages = ['package%d' % i for i in range(0, 100)] + + for package in packages: + self.create_package(package, '1.0.0') + + self.be_normal_user() + + response = self.testapp.get('/api/packages?page=2') + self.assertEqual(response.headers['Content-Type'], 'application/json') + result = json.loads(response.body) + + self.assertEqual( + result['prev_url'], 'http://localhost:80/api/packages?page=1') + self.assertEqual(result['next_url'], None) + self.assertEqual(result['pages'], 2) + + for i in range(0, 50): + self.assertEqual(result['packages'][i]['name'], + 'package%d' % (49 - i)) + + def test_api_get_non_existent_package(self): + response = self.testapp.get( + '/api/packages/test-package', status=404) + self.assertEqual(response.headers['Content-Type'], 'application/json') + self.assertEqual(json.loads(response.body), { + 'error': {'message': 'Package "test-package" doesn\'t exist.'} + }) + + def test_api_get_package_without_versions(self): + admin = self.admin_user() + Package.new(name='test-package', uploaders=[admin]).put() + + self.be_normal_user() + + response = self.testapp.get('/api/packages/test-package') + self.assertEqual(response.headers['Content-Type'], 'application/json') + result = json.loads(response.body) + self.assertEqual(result["name"], "test-package") + self.assertEqual(result["versions"], []) + self.assertEqual(result["latest"], None) + + def test_api_get_package_with_versions(self): + self.be_admin_user() + + self.create_package('test-package', '1.1.0') + self.create_package('test-package', '1.1.1') + self.create_package('test-package', '1.2.0') + + self.be_normal_user() + + package = Package.get_by_key_name('test-package') + + response = self.testapp.get('/api/packages/test-package') + self.assertEqual(response.headers['Content-Type'], 'application/json') + self.assertEqual(json.loads(response.body), { + "name": "test-package", + "url": "http://localhost:80/api/packages/test-package", + "uploaders_url": "http://localhost:80/api/packages/test-package/" + + "uploaders", + "version_url": "http://localhost:80/api/packages/test-package/" + + "versions/{version}", + "new_version_url": + "http://localhost:80/api/packages/test-package/versions/new", + "downloads": 0, + "uploaders": [self.admin_user().email()], + "created": package.created.isoformat(), + "versions": [ + self.package_version_dict("test-package", "1.1.0"), + self.package_version_dict("test-package", "1.1.1"), + self.package_version_dict("test-package", "1.2.0"), + ], + "latest": self.package_version_dict("test-package", "1.2.0") + }) diff --git a/test/test_handlers/api/test_version_negotiation.py b/test/test_handlers/api/test_version_negotiation.py new file mode 100644 index 0000000..5ce04e6 --- /dev/null +++ b/test/test_handlers/api/test_version_negotiation.py @@ -0,0 +1,33 @@ +# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file +# for details. All rights reserved. Use of this source code is governed by a +# BSD-style license that can be found in the LICENSE file. + +from testcase import TestCase + +class VersionNegotiationTest(TestCase): + # TODO(nweiz): when we have any actions that change behavior based on the + # API version, test that. Also test that the latest version is the default. + + def test_rejects_too_low_version(self): + self.testapp.get( + '/api/packages', + headers={'Accept': 'application/vnd.pub.v1+json'}, + status=406) + + def test_rejects_too_high_version(self): + self.testapp.get( + '/api/packages', + headers={'Accept': 'application/vnd.pub.v3+json'}, + status=406) + + def test_rejects_malformed_version(self): + self.testapp.get( + '/api/packages', + headers={'Accept': 'application/vnd.pub.asdf+json'}, + status=406) + + def test_rejects_malformed_format(self): + self.testapp.get( + '/api/packages', + headers={'Accept': 'application/vnd.pub.v2+yaml'}, + status=406) diff --git a/test/test_handlers/test_package_uploaders.py b/test/test_handlers/test_package_uploaders.py index 940aabc..5c1eba1 100644 --- a/test/test_handlers/test_package_uploaders.py +++ b/test/test_handlers/test_package_uploaders.py @@ -14,27 +14,6 @@ def setUp(self): self.normal_user('uploader2')]) self.package.put() - def test_create_requires_login(self): - response = self.testapp.post('/packages/test-package/uploaders.json', - {'email': self.normal_user().email()}, - status=401) - self.assert_json_error(response) - - def test_create_requires_uploader(self): - self.be_normal_oauth_user() - response = self.testapp.post('/packages/test-package/uploaders.json', - {'email': self.normal_user().email()}, - status=403) - self.assert_json_error(response) - - def test_create_requires_new_uploader(self): - self.be_normal_oauth_user('uploader1') - response = self.testapp.post( - '/packages/test-package/uploaders.json', - {'email': self.normal_user('uploader2').email()}, - status=400) - self.assert_json_error(response) - def test_uploader_creates_new_uploader(self): self.be_normal_oauth_user('uploader1') response = self.testapp.post('/packages/test-package/uploaders.json', @@ -48,73 +27,6 @@ def test_uploader_creates_new_uploader(self): self.normal_user() ]) - def test_create_is_case_insensitive(self): - self.be_normal_oauth_user('uploader1') - response = self.testapp.post( - '/packages/test-package/uploaders.json', - {'email': self.normal_user('NAme').email()}) - self.assert_json_success(response) - - response = self.testapp.post( - '/packages/test-package/uploaders.json', - {'email': self.normal_user('naME').email()}, - status=400) - self.assert_json_error(response) - - package = Package.get_by_key_name('test-package') - self.assertEquals(package.uploaders, [ - self.normal_user('uploader1'), - self.normal_user('uploader2'), - self.normal_user('NAme') - ]) - - def test_admin_creates_new_uploader(self): - self.be_admin_oauth_user() - response = self.testapp.post('/packages/test-package/uploaders.json', - {'email': self.normal_user().email()}) - self.assert_json_success(response) - - package = Package.get_by_key_name('test-package') - self.assertEquals(package.uploaders, [ - self.normal_user('uploader1'), - self.normal_user('uploader2'), - self.normal_user() - ]) - - def test_delete_requires_login(self): - response = self.testapp.delete( - '/packages/test-package/uploaders/%s.json' % - self.normal_user('uploader1').email(), - status=401) - self.assert_json_error(response) - - def test_delete_requires_uploader(self): - self.be_normal_oauth_user() - response = self.testapp.delete( - '/packages/test-package/uploaders/%s.json' % - self.normal_user('uploader1').email(), - status=403) - self.assert_json_error(response) - - def test_cant_delete_non_uploader(self): - self.be_normal_oauth_user('uploader1') - response = self.testapp.delete( - '/packages/test-package/uploaders/%s.json' % - self.normal_user('non-uploader').email(), - status=400) - self.assert_json_error(response) - - def test_cant_delete_only_uploader(self): - self.package.uploaders = [self.normal_user('uploader1')] - self.package.put() - - self.be_normal_oauth_user('uploader1') - response = self.testapp.delete( - '/packages/test-package/uploaders/%s.json' % - self.normal_user('uploader1').email(), - status=400) - self.assert_json_error(response) - def test_uploader_deletes_uploader(self): self.be_normal_oauth_user('uploader1') response = self.testapp.delete( @@ -125,25 +37,3 @@ def test_uploader_deletes_uploader(self): package = Package.get_by_key_name('test-package') self.assertEquals( package.uploaders, [self.normal_user('uploader2')]) - - def test_delete_is_case_insensitive(self): - self.be_normal_oauth_user('uploader1') - response = self.testapp.delete( - '/packages/test-package/uploaders/%s.json' % - self.normal_user('UpLoAdEr1').email()) - self.assert_json_success(response) - - package = Package.get_by_key_name('test-package') - self.assertEquals( - package.uploaders, [self.normal_user('uploader2')]) - - def test_admin_deletes_uploader(self): - self.be_admin_oauth_user() - response = self.testapp.delete( - '/packages/test-package/uploaders/%s.json' % - self.normal_user('uploader1').email()) - self.assert_json_success(response) - - package = Package.get_by_key_name('test-package') - self.assertEquals( - package.uploaders, [self.normal_user('uploader2')]) diff --git a/test/test_handlers/test_package_versions.py b/test/test_handlers/test_package_versions.py index 716ca4d..ee825a0 100644 --- a/test/test_handlers/test_package_versions.py +++ b/test/test_handlers/test_package_versions.py @@ -46,168 +46,6 @@ def test_user_creates_new_package(self): self.assertEqual(package.updated, version.created) self.assertEqual('This is a README.', version.readme.text) - def test_uploadership_is_case_insensitive(self): - self.be_normal_oauth_user('NAme') - self.post_package_version(name='new-package', version='0.0.1') - - version = Package.get_by_key_name('new-package').latest_version - self.assertIsNotNone(version) - self.assertEqual(version.version, SemanticVersion('0.0.1')) - - self.be_normal_oauth_user('naME') - self.post_package_version(name='new-package', version='0.0.2') - - version = Package.get_by_key_name('new-package').latest_version - self.assertIsNotNone(version) - self.assertEqual(version.version, SemanticVersion('0.0.2')) - - def test_new_requires_oauth(self): - response = self.testapp.get('/packages/test-package/versions/new.json', - status=401) - self.assert_json_error(response) - # Since we didn't send any OAuth2 credentials, the WWW-Authenticate - # header shouldn't have OAuth2-specific fields. - self.assertEqual(response.headers['WWW-Authenticate'], 'Bearer') - - def test_new_requires_uploadership(self): - self.be_normal_oauth_user() - - response = self.testapp.get('/packages/test-package/versions/new.json', - status=403) - self.assert_json_error(response) - self.assert_oauth_error(response) - - def test_new_requires_private_key(self): - self.be_admin_oauth_user() - PrivateKey.get_by_key_name('singleton').delete() - - response = self.testapp.get('/packages/test-package/versions/new.json', - status=500) - self.assert_json_error(response) - - def test_uploader_creates_package_version(self): - self.be_normal_oauth_user('other-uploader') - self.post_package_version('1.2.3') - - version = self.get_package_version('1.2.3') - self.assertIsNotNone(version) - self.assertEqual(version.version, SemanticVersion('1.2.3')) - self.assertEqual(version.package.name, 'test-package') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) - - def test_create_requires_admin(self): - self.be_normal_oauth_user() - - response = self.testapp.get('/packages/versions/abcd/create.json', - status=403) - self.assert_json_error(response) - - def test_create_requires_uploader(self): - Package.new(name='owned-package', - uploaders=[self.normal_user('owner')]).put() - self.be_normal_oauth_user() - - response = self.testapp.get( - '/packages/owned-package/versions/abcd/create.json', status=403) - self.assert_json_error(response) - - def test_create_requires_valid_id(self): - self.be_admin_oauth_user() - - response = self.testapp.get( - '/packages/versions/abcd/create.json', status=403) - self.assert_json_error(response) - - def test_create_requires_new_version_number(self): - self.be_admin_oauth_user() - self.package_version(self.package, '1.2.3', description='old').put() - - upload = self.upload_archive('test-package', '1.2.3', description='new') - response = self.create_package(upload, status=400) - self.assert_json_error(response) - - version = self.get_package_version('1.2.3') - self.assertEqual(version.pubspec['description'], 'old') - - def test_create_sets_latest_package_for_increased_version_number(self): - self.be_admin_oauth_user() - - self.post_package_version('1.2.3') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) - - self.post_package_version('1.2.4') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.4')) - - self.assert_package_updated_is_latest_version_created() - - def test_create_sets_latest_package_for_prerelease_versions_only(self): - self.be_admin_oauth_user() - - self.post_package_version('1.2.3-pre1') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre1')) - - self.post_package_version('1.2.3-pre0') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre1')) - - self.post_package_version('1.2.3-pre2') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre2')) - - self.assert_package_updated_is_latest_version_created() - - def test_create_sets_latest_package_to_old_version_over_prerelease_version(self): - self.be_admin_oauth_user() - - self.post_package_version('1.2.3-pre1') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3-pre1')) - - self.post_package_version('1.2.0') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.0')) - - self.post_package_version('1.2.3-pre2') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.0')) - - self.assert_package_updated_is_latest_version_created() - - def test_create_doesnt_set_latest_package_for_decreased_version_number(self): - self.be_admin_oauth_user() - - self.post_package_version('1.2.3') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) - - self.post_package_version('1.2.2') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) - - self.assert_package_updated_is_latest_version_created() - - def test_create_doesnt_set_latest_package_for_prerelease_version_number(self): - self.be_admin_oauth_user() - - self.post_package_version('1.2.3') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) - - self.post_package_version('1.2.5-pre') - self.assertEqual(self.latest_version(), SemanticVersion('1.2.3')) - - self.assert_package_updated_is_latest_version_created() - - def test_create_sets_sort_order(self): - self.be_admin_oauth_user() - - self.post_package_version('1.2.3') - self.run_deferred_tasks() - self.assertEqual(self.get_package_version('1.2.3').sort_order, 0) - - self.post_package_version('1.2.4') - self.run_deferred_tasks() - self.assertEqual(self.get_package_version('1.2.3').sort_order, 0) - self.assertEqual(self.get_package_version('1.2.4').sort_order, 1) - - self.post_package_version('1.2.4-pre') - self.run_deferred_tasks() - self.assertEqual(self.get_package_version('1.2.3').sort_order, 0) - self.assertEqual(self.get_package_version('1.2.4-pre').sort_order, 1) - self.assertEqual(self.get_package_version('1.2.4').sort_order, 2) - def test_show_package_version_tar_gz(self): version = self.package_version(self.package, '1.2.3') version.put() @@ -263,26 +101,6 @@ def test_show_package_version_yaml(self): 'text/yaml;charset=utf-8') self.assertEqual(yaml.load(response.body), version.pubspec) - def test_dartdoc_requires_private_key(self): - self.be_admin_oauth_user() - self.post_package_version('1.2.3') - PrivateKey.get_by_key_name('singleton').delete() - - response = self.testapp.get( - '/packages/test-package/versions/1.2.3/new_dartdoc.json', - status=500) - self.assert_json_error(response) - - def test_dartdoc_requires_uploadership(self): - self.be_admin_oauth_user() - self.post_package_version('1.2.3') - - self.be_normal_oauth_user() - response = self.testapp.get( - '/packages/test-package/versions/1.2.3/new_dartdoc.json', - status=403) - self.assert_json_error(response) - def test_uploader_gets_dartdoc_form(self): self.be_normal_oauth_user('other-uploader') self.post_package_version('1.2.3') @@ -294,14 +112,6 @@ def test_uploader_gets_dartdoc_form(self): '/staging/packages/test-package-1.2.3/dartdoc.json') self.assertEqual(content['fields']['acl'], 'public-read') - def test_uploader_gets_dartdoc_form_for_nonexistent_package(self): - self.be_normal_oauth_user('other-uploader') - - response = self.testapp.get( - '/packages/not-package/versions/1.2.3/new_dartdoc.json', - status=404) - self.assert_json_error(response) - def test_reload_requires_admin(self): self.be_normal_user() diff --git a/test/test_handlers/test_packages.py b/test/test_handlers/test_packages.py index 8ef4f7d..7ccc9cb 100644 --- a/test/test_handlers/test_packages.py +++ b/test/test_handlers/test_packages.py @@ -95,7 +95,7 @@ def test_page_two_json_lists_second_page_of_packages(self): ]) def test_get_non_existent_package(self): - self.testapp.get('/packages/package/test-package', status=404) + self.testapp.get('/packages/test-package', status=404) def test_get_unowned_package(self): Package.new(name='test-package', uploaders=[self.admin_user()]).put() diff --git a/test/testcase.py b/test/testcase.py index 07856e7..19ce307 100644 --- a/test/testcase.py +++ b/test/testcase.py @@ -309,7 +309,6 @@ def assert_json_success(self, response): def assert_oauth_error(self, response): """Assert that the given response is an OAuth2 error.""" - print(response.headers) self.assertTrue(response.headers['WWW-Authenticate'].startswith( 'Bearer error="')) @@ -392,6 +391,21 @@ def _link_exists(self, response, url): return any([link['href'] == url for link in self.html(response).find_all('a')]) + def package_version_dict(self, name, version): + """Returns the expected API dictionary for a package version.""" + + package_url = "http://localhost:80/api/packages/" + name + version_url = package_url + "/versions/" + version + return { + "version": version, + "url": version_url, + "package_url": package_url, + "new_dartdoc_url": version_url + "/new_dartdoc", + "archive_url": "http://localhost:80/packages/" + name + + "/versions/" + version + ".tar.gz", + "pubspec": {"name": name, "version": version} + } + @decorator def mock_not_on_dev_server(fn, *args, **kwargs): """A decorator for tests that need to appear to not be on the dev server.