From 7bdb917364203fb46c62a8caf5e09b6a8cd309c3 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 23 Aug 2016 15:42:01 -0400 Subject: [PATCH 01/65] Shuffle classes around in test_search/test_views This makes room for a TestProjectSearchAPI class. --- tests/test_search/test_views.py | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 9baad3e7710..a9b9ea0b66f 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -8,10 +8,18 @@ from website.util import api_url_for -class TestSearchViews(SearchTestCase): +class TestSearchPage(SearchTestCase): + + def test_search_projects(self): + factories.ProjectFactory(title='Foo Bar') + res = self.app.get('/search/', {'q': 'foo'}) + assert_equal(res.status_code, 200) + + +class TestUserSearchAPI(SearchTestCase): def setUp(self): - super(TestSearchViews, self).setUp() + super(TestUserSearchAPI, self).setUp() import website.search.search as search search.delete_all() @@ -22,7 +30,7 @@ def setUp(self): factories.UserFactory(fullname='Freddie Mercury{}'.format(i)) def tearDown(self): - super(TestSearchViews, self).tearDown() + super(TestUserSearchAPI, self).tearDown() import website.search.search as search search.delete_all() @@ -89,13 +97,8 @@ def test_search_pagination_smaller_pages_page_2(self): assert_equal(page, 2) assert_equal(pages, 3) - def test_search_projects(self): - url = '/search/' - res = self.app.get(url, {'q': self.project.title}) - assert_equal(res.status_code, 200) - -class TestODMTitleSearch(SearchTestCase): +class TestODMTitleSearchAPI(SearchTestCase): """ Docs from original method: :arg term: The substring of the title. :arg category: Category of the node. @@ -109,7 +112,7 @@ class TestODMTitleSearch(SearchTestCase): :return: a list of dictionaries of projects """ def setUp(self): - super(TestODMTitleSearch, self).setUp() + super(TestODMTitleSearchAPI, self).setUp() self.user = factories.AuthUserFactory() self.user_two = factories.AuthUserFactory() From 4d6d0d7decf2debcbfbfc8d9707438fe574bf2b5 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 23 Aug 2016 15:42:46 -0400 Subject: [PATCH 02/65] Start a class for project search API (v1) tests --- tests/test_search/test_views.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index a9b9ea0b66f..07fb7e0747d 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -16,6 +16,21 @@ def test_search_projects(self): assert_equal(res.status_code, 200) +class TestProjectSearchAPI(SearchTestCase): + + def results(self, query): + url = api_url_for('search_search', type='project') + return self.app.get(url, {'q': query}).json['results'] + + + def test_empty_results_are_empty(self): + assert self.results('foo') == [] + + def test_interesting_results_are_interesting(self): + factories.ProjectFactory(title='Foo Bar', is_public=True) + assert [x['title'] for x in self.results('foo')] == ['Foo Bar'] + + class TestUserSearchAPI(SearchTestCase): def setUp(self): From b3d31cc2c42a678162a2aecbfe0ab1394f60bb12 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 29 Aug 2016 19:28:23 -0400 Subject: [PATCH 03/65] Rewrite tests using parameterization --- tests/test_search/test_views.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 07fb7e0747d..f27fb0a3896 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -2,6 +2,7 @@ from __future__ import absolute_import, division, print_function, unicode_literals from nose.tools import * # noqa PEP8 asserts +from nose_parameterized import parameterized from tests import factories from tests.test_search import SearchTestCase @@ -16,19 +17,33 @@ def test_search_projects(self): assert_equal(res.status_code, 200) -class TestProjectSearchAPI(SearchTestCase): +PRIVATE, PUBLIC = range(2) +PROJECT, REGISTRATION = range(2) +ANON, AUTH, CONTRIB, OWNER = range(4) +Y, N = True, False + +cases = [ + (PRIVATE, PROJECT, ANON, N), + (PUBLIC, PROJECT, ANON, Y), +] + +class TestSearchSearchAPI(SearchTestCase): + """Exercises the website.search.views.search_search view. + """ def results(self, query): url = api_url_for('search_search', type='project') return self.app.get(url, {'q': query}).json['results'] + fixture_funcs = { + PROJECT: factories.ProjectFactory, + } - def test_empty_results_are_empty(self): - assert self.results('foo') == [] - - def test_interesting_results_are_interesting(self): - factories.ProjectFactory(title='Foo Bar', is_public=True) - assert [x['title'] for x in self.results('foo')] == ['Foo Bar'] + @parameterized.expand(cases) + def test(self, status, type_, role, included): + self.fixture_funcs[type_](title='Flim Flammity', is_public=status is PUBLIC) + expected = ['Flim Flammity'] if included else [] + assert_equal([x['title'] for x in self.results('flim')], expected) class TestUserSearchAPI(SearchTestCase): From aae954d79f242ce02ab46b76b5cdc0d3f33ac693 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 29 Aug 2016 19:44:04 -0400 Subject: [PATCH 04/65] Expand to registrations --- tests/test_search/test_views.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index f27fb0a3896..b5f1582539a 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -25,6 +25,8 @@ def test_search_projects(self): cases = [ (PRIVATE, PROJECT, ANON, N), (PUBLIC, PROJECT, ANON, Y), + (PRIVATE, REGISTRATION, ANON, N), + (PUBLIC, REGISTRATION, ANON, Y), ] class TestSearchSearchAPI(SearchTestCase): @@ -35,13 +37,15 @@ def results(self, query): url = api_url_for('search_search', type='project') return self.app.get(url, {'q': query}).json['results'] - fixture_funcs = { - PROJECT: factories.ProjectFactory, - } - @parameterized.expand(cases) def test(self, status, type_, role, included): - self.fixture_funcs[type_](title='Flim Flammity', is_public=status is PUBLIC) + if type_ == PROJECT: + factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + elif type_ == REGISTRATION: + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + factories.RegistrationFactory(project=project, is_public=status is PUBLIC) + else: + raise NotImplementedError expected = ['Flim Flammity'] if included else [] assert_equal([x['title'] for x in self.results('flim')], expected) From c579dfaff87fb13a814001088a969548bb1bd1e0 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 29 Aug 2016 21:45:51 -0400 Subject: [PATCH 05/65] Expand to components --- tests/test_search/test_views.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index b5f1582539a..14a4e7c76da 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -18,7 +18,7 @@ def test_search_projects(self): PRIVATE, PUBLIC = range(2) -PROJECT, REGISTRATION = range(2) +PROJECT, REGISTRATION, COMPONENT = range(3) ANON, AUTH, CONTRIB, OWNER = range(4) Y, N = True, False @@ -27,6 +27,8 @@ def test_search_projects(self): (PUBLIC, PROJECT, ANON, Y), (PRIVATE, REGISTRATION, ANON, N), (PUBLIC, REGISTRATION, ANON, Y), + (PRIVATE, COMPONENT, ANON, N), + (PUBLIC, COMPONENT, ANON, Y), ] class TestSearchSearchAPI(SearchTestCase): @@ -44,6 +46,9 @@ def test(self, status, type_, role, included): elif type_ == REGISTRATION: project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) factories.RegistrationFactory(project=project, is_public=status is PUBLIC) + elif type_ == COMPONENT: + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + factories.NodeFactory(parent=project, is_public=status is PUBLIC) else: raise NotImplementedError expected = ['Flim Flammity'] if included else [] From 626eaee157bf890e700fef7ff455b3dc88190b82 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 30 Aug 2016 06:44:49 -0400 Subject: [PATCH 06/65] Clean up tests we have so far - add a display name - stop searching just projects - fix component fixture --- tests/test_search/test_views.py | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 14a4e7c76da..f65225b27e3 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -23,12 +23,13 @@ def test_search_projects(self): Y, N = True, False cases = [ - (PRIVATE, PROJECT, ANON, N), - (PUBLIC, PROJECT, ANON, Y), - (PRIVATE, REGISTRATION, ANON, N), - (PUBLIC, REGISTRATION, ANON, Y), - (PRIVATE, COMPONENT, ANON, N), - (PUBLIC, COMPONENT, ANON, Y), + ("private project hidden from anon", PRIVATE, PROJECT, ANON, N), + ("private registration hidden from anon", PRIVATE, REGISTRATION, ANON, N), + ("private component hidden from anon", PRIVATE, COMPONENT, ANON, N), + + ("public project shown to anon", PUBLIC, PROJECT, ANON, Y), + ("public registration shown to anon", PUBLIC, REGISTRATION, ANON, Y), + ("public component shown to anon", PUBLIC, COMPONENT, ANON, Y), ] class TestSearchSearchAPI(SearchTestCase): @@ -36,19 +37,23 @@ class TestSearchSearchAPI(SearchTestCase): """ def results(self, query): - url = api_url_for('search_search', type='project') + url = api_url_for('search_search') return self.app.get(url, {'q': query}).json['results'] @parameterized.expand(cases) - def test(self, status, type_, role, included): + def test(self, ignored, status, type_, role, included): if type_ == PROJECT: factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) elif type_ == REGISTRATION: project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) factories.RegistrationFactory(project=project, is_public=status is PUBLIC) elif type_ == COMPONENT: - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - factories.NodeFactory(parent=project, is_public=status is PUBLIC) + project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) + factories.NodeFactory( + title='Flim Flammity', + parent=project, + is_public=status is PUBLIC, + ) else: raise NotImplementedError expected = ['Flim Flammity'] if included else [] From 82f0054309e3bb210ae74e74a232658150cd2f97 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 30 Aug 2016 10:15:26 -0400 Subject: [PATCH 07/65] Expand to files However, an extra check reveals that the registration test is not performing properly. --- tests/test_search/test_views.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index f65225b27e3..cc885a7d8fe 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -18,7 +18,7 @@ def test_search_projects(self): PRIVATE, PUBLIC = range(2) -PROJECT, REGISTRATION, COMPONENT = range(3) +PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() ANON, AUTH, CONTRIB, OWNER = range(4) Y, N = True, False @@ -26,10 +26,12 @@ def test_search_projects(self): ("private project hidden from anon", PRIVATE, PROJECT, ANON, N), ("private registration hidden from anon", PRIVATE, REGISTRATION, ANON, N), ("private component hidden from anon", PRIVATE, COMPONENT, ANON, N), + ("private file hidden from anon", PRIVATE, FILE, ANON, N), ("public project shown to anon", PUBLIC, PROJECT, ANON, Y), ("public registration shown to anon", PUBLIC, REGISTRATION, ANON, Y), ("public component shown to anon", PUBLIC, COMPONENT, ANON, Y), + ("public file shown to anon", PUBLIC, FILE, ANON, Y), ] class TestSearchSearchAPI(SearchTestCase): @@ -42,6 +44,7 @@ def results(self, query): @parameterized.expand(cases) def test(self, ignored, status, type_, role, included): + key = 'title' if type_ == PROJECT: factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) elif type_ == REGISTRATION: @@ -54,10 +57,15 @@ def test(self, ignored, status, type_, role, included): parent=project, is_public=status is PUBLIC, ) + elif type_ == FILE: + project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) + project.get_addon('osfstorage').get_root().append_file('Flim Flammity') + key = 'name' else: raise NotImplementedError - expected = ['Flim Flammity'] if included else [] - assert_equal([x['title'] for x in self.results('flim')], expected) + expected = [('Flim Flammity', type_)] if included else [] + results = self.results('flim') + assert_equal([(x[key], x['category']) for x in results], expected) class TestUserSearchAPI(SearchTestCase): From a0dedae25b52a538fbe6e86f1e9e5bc45459ee02 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 5 Sep 2016 19:29:56 -0400 Subject: [PATCH 08/65] Use mock_archive for the registration case --- tests/test_search/test_views.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index cc885a7d8fe..326237d3d5f 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -6,6 +6,7 @@ from tests import factories from tests.test_search import SearchTestCase +from tests.utils import mock_archive from website.util import api_url_for @@ -38,9 +39,10 @@ class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ - def results(self, query): + def results(self, query, category): url = api_url_for('search_search') - return self.app.get(url, {'q': query}).json['results'] + data = {'q': 'category:{} AND {}'.format(category, query)} + return self.app.get(url, data).json['results'] @parameterized.expand(cases) def test(self, ignored, status, type_, role, included): @@ -49,7 +51,7 @@ def test(self, ignored, status, type_, role, included): factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) elif type_ == REGISTRATION: project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - factories.RegistrationFactory(project=project, is_public=status is PUBLIC) + mock_archive(project, autocomplete=True, autoapprove=True).__enter__() elif type_ == COMPONENT: project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) factories.NodeFactory( @@ -64,7 +66,7 @@ def test(self, ignored, status, type_, role, included): else: raise NotImplementedError expected = [('Flim Flammity', type_)] if included else [] - results = self.results('flim') + results = self.results('flim', type_) assert_equal([(x[key], x['category']) for x in results], expected) From ca09ac641aa2daaef97cbf257d1379d56f47ebef Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 13 Sep 2016 16:24:09 -0400 Subject: [PATCH 09/65] Fix two public/anon tests --- tests/test_search/test_views.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 326237d3d5f..0edcd527c63 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -48,17 +48,20 @@ def results(self, query, category): def test(self, ignored, status, type_, role, included): key = 'title' if type_ == PROJECT: - factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + project.update_search() elif type_ == REGISTRATION: project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) mock_archive(project, autocomplete=True, autoapprove=True).__enter__() elif type_ == COMPONENT: project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) - factories.NodeFactory( + project.update_search() + component = factories.NodeFactory( title='Flim Flammity', parent=project, is_public=status is PUBLIC, ) + component.update_search() elif type_ == FILE: project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) project.get_addon('osfstorage').get_root().append_file('Flim Flammity') From a0ddd4b68400aaa664c2360684f8700f8484df25 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 16 Sep 2016 10:55:05 -0400 Subject: [PATCH 10/65] There is no such thing as a "private registration" --- tests/test_search/test_views.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 0edcd527c63..f0774d63159 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -25,7 +25,6 @@ def test_search_projects(self): cases = [ ("private project hidden from anon", PRIVATE, PROJECT, ANON, N), - ("private registration hidden from anon", PRIVATE, REGISTRATION, ANON, N), ("private component hidden from anon", PRIVATE, COMPONENT, ANON, N), ("private file hidden from anon", PRIVATE, FILE, ANON, N), From 6c4eaf56b54e3c3f3560d9bf88470dbbe65be332 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 16 Sep 2016 11:22:11 -0400 Subject: [PATCH 11/65] Extend to cover authenticated users --- tests/test_search/test_views.py | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index f0774d63159..94108bfe712 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -28,20 +28,29 @@ def test_search_projects(self): ("private component hidden from anon", PRIVATE, COMPONENT, ANON, N), ("private file hidden from anon", PRIVATE, FILE, ANON, N), + ("private project hidden from auth", PRIVATE, PROJECT, AUTH, N), + ("private component hidden from auth", PRIVATE, COMPONENT, AUTH, N), + ("private file hidden from auth", PRIVATE, FILE, AUTH, N), + ("public project shown to anon", PUBLIC, PROJECT, ANON, Y), ("public registration shown to anon", PUBLIC, REGISTRATION, ANON, Y), ("public component shown to anon", PUBLIC, COMPONENT, ANON, Y), ("public file shown to anon", PUBLIC, FILE, ANON, Y), + + ("public project shown to auth", PUBLIC, PROJECT, AUTH, Y), + ("public registration shown to auth", PUBLIC, REGISTRATION, AUTH, Y), + ("public component shown to auth", PUBLIC, COMPONENT, AUTH, Y), + ("public file shown to auth", PUBLIC, FILE, AUTH, Y), ] class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ - def results(self, query, category): + def results(self, query, category, auth): url = api_url_for('search_search') data = {'q': 'category:{} AND {}'.format(category, query)} - return self.app.get(url, data).json['results'] + return self.app.get(url, data, auth=auth).json['results'] @parameterized.expand(cases) def test(self, ignored, status, type_, role, included): @@ -67,8 +76,13 @@ def test(self, ignored, status, type_, role, included): key = 'name' else: raise NotImplementedError + + auth = None + if role is AUTH: + auth = factories.AuthUserFactory().auth + expected = [('Flim Flammity', type_)] if included else [] - results = self.results('flim', type_) + results = self.results('flim', type_, auth) assert_equal([(x[key], x['category']) for x in results], expected) From 1f3c16e22cbb69d6e4fc3a80bbdadeef05210f2c Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 16 Sep 2016 16:00:02 -0400 Subject: [PATCH 12/65] Factor out factory functions --- tests/test_search/test_views.py | 57 ++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 94108bfe712..23d2bf32fa2 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -43,6 +43,40 @@ def test_search_projects(self): ("public file shown to auth", PUBLIC, FILE, AUTH, Y), ] +def make_project(status): + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + project.update_search() + return 'title' + +def make_registration(status): + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + mock_archive(project, autocomplete=True, autoapprove=True).__enter__() + return 'title' + +def make_component(status): + project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) + project.update_search() + component = factories.NodeFactory( + title='Flim Flammity', + parent=project, + is_public=status is PUBLIC, + ) + component.update_search() + return 'title' + +def make_file(status): + project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) + project.get_addon('osfstorage').get_root().append_file('Flim Flammity') + return 'name' + +makers = { + PROJECT: make_project, + REGISTRATION: make_registration, + COMPONENT: make_component, + FILE: make_file, +} + + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ @@ -54,28 +88,7 @@ def results(self, query, category, auth): @parameterized.expand(cases) def test(self, ignored, status, type_, role, included): - key = 'title' - if type_ == PROJECT: - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - project.update_search() - elif type_ == REGISTRATION: - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - mock_archive(project, autocomplete=True, autoapprove=True).__enter__() - elif type_ == COMPONENT: - project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) - project.update_search() - component = factories.NodeFactory( - title='Flim Flammity', - parent=project, - is_public=status is PUBLIC, - ) - component.update_search() - elif type_ == FILE: - project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) - project.get_addon('osfstorage').get_root().append_file('Flim Flammity') - key = 'name' - else: - raise NotImplementedError + key = makers[type_](status) auth = None if role is AUTH: From adebf15ab23a17a3acd546f31e3452bc5787f6f8 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 09:38:42 -0400 Subject: [PATCH 13/65] Naively failing tests for private read --- tests/test_search/test_views.py | 35 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 23d2bf32fa2..ed2d1ce53bd 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -20,7 +20,7 @@ def test_search_projects(self): PRIVATE, PUBLIC = range(2) PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() -ANON, AUTH, CONTRIB, OWNER = range(4) +ANON, AUTH, READ = (None, '', 'r') Y, N = True, False cases = [ @@ -32,6 +32,11 @@ def test_search_projects(self): ("private component hidden from auth", PRIVATE, COMPONENT, AUTH, N), ("private file hidden from auth", PRIVATE, FILE, AUTH, N), + ("private project shown to read", PRIVATE, PROJECT, READ, Y), + ("private component shown to read", PRIVATE, COMPONENT, READ, Y), + ("private file shown to read", PRIVATE, FILE, READ, Y), + + ("public project shown to anon", PUBLIC, PROJECT, ANON, Y), ("public registration shown to anon", PUBLIC, REGISTRATION, ANON, Y), ("public component shown to anon", PUBLIC, COMPONENT, ANON, Y), @@ -41,19 +46,24 @@ def test_search_projects(self): ("public registration shown to auth", PUBLIC, REGISTRATION, AUTH, Y), ("public component shown to auth", PUBLIC, COMPONENT, AUTH, Y), ("public file shown to auth", PUBLIC, FILE, AUTH, Y), + + ("public project shown to read", PUBLIC, PROJECT, READ, Y), + ("public registration shown to read", PUBLIC, REGISTRATION, READ, Y), + ("public component shown to read", PUBLIC, COMPONENT, READ, Y), + ("public file shown to read", PUBLIC, FILE, READ, Y), ] -def make_project(status): +def make_project(status, user, perms): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) project.update_search() return 'title' -def make_registration(status): +def make_registration(status, user, perms): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) mock_archive(project, autocomplete=True, autoapprove=True).__enter__() return 'title' -def make_component(status): +def make_component(status, user, perms): project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) project.update_search() component = factories.NodeFactory( @@ -64,7 +74,7 @@ def make_component(status): component.update_search() return 'title' -def make_file(status): +def make_file(status, user, perms): project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) project.get_addon('osfstorage').get_root().append_file('Flim Flammity') return 'name' @@ -86,16 +96,17 @@ def results(self, query, category, auth): data = {'q': 'category:{} AND {}'.format(category, query)} return self.app.get(url, data, auth=auth).json['results'] - @parameterized.expand(cases) - def test(self, ignored, status, type_, role, included): - key = makers[type_](status) - auth = None - if role is AUTH: - auth = factories.AuthUserFactory().auth + @parameterized.expand(cases) + def test(self, ignored, status, type_, perms, included): + user = None + if perms is not None: + user = factories.AuthUserFactory() + make = makers[type_] + key = make(status, user, perms) expected = [('Flim Flammity', type_)] if included else [] - results = self.results('flim', type_, auth) + results = self.results('flim', type_, user.auth if user else None) assert_equal([(x[key], x['category']) for x in results], expected) From 8e2e87ee957fe973f5745309f25f72a34dd077c4 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 10:40:47 -0400 Subject: [PATCH 14/65] Start stubbing out fixture tests --- tests/test_search/test_views.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index ed2d1ce53bd..00852efd193 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -5,7 +5,7 @@ from nose_parameterized import parameterized from tests import factories -from tests.test_search import SearchTestCase +from tests.test_search import OsfTestCase, SearchTestCase from tests.utils import mock_archive from website.util import api_url_for @@ -87,6 +87,32 @@ def make_file(status, user, perms): } +class TestMakers(OsfTestCase): + + # mp - make_project + + def test_mp_specifies_title(self): + assert make_project('private', None, None) == 'title' + + + # mr - make_registration + + def test_mr_specifies_title(self): + assert make_registration('private', None, None) == 'title' + + + # mc - make_component + + def test_mc_specifies_title(self): + assert make_component('private', None, None) == 'title' + + + # mf - make_file + + def test_mf_specifies_name(self): + assert make_file('private', None, None) == 'name' + + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ From 448386a85c252e4abc2dfc6411be3198f93e6339 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 13:16:55 -0400 Subject: [PATCH 15/65] Write tests for project creation --- tests/test_search/test_views.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 00852efd193..a399001b400 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -5,8 +5,10 @@ from nose_parameterized import parameterized from tests import factories +from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase, SearchTestCase from tests.utils import mock_archive +from website.project.model import Node from website.util import api_url_for @@ -87,13 +89,25 @@ def make_file(status, user, perms): } -class TestMakers(OsfTestCase): +class TestMakers(DbIsolationMixin, OsfTestCase): + + def test_there_are_no_nodes_to_start_with(self): + assert Node.find().count() == 0 + # mp - make_project def test_mp_specifies_title(self): assert make_project('private', None, None) == 'title' + def test_mp_makes_private_project_private(self): + make_project(PRIVATE, None, None) + assert not Node.find_one().is_public + + def test_mp_makes_public_project_public(self): + make_project(PUBLIC, None, None) + assert Node.find_one().is_public + # mr - make_registration From 8a13e46405f3dbd643d9fd4414f861717dcd2583 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 15:08:50 -0400 Subject: [PATCH 16/65] More tests for projects, registrations, components --- tests/test_search/test_views.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index a399001b400..33e87609612 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -4,6 +4,8 @@ from nose.tools import * # noqa PEP8 asserts from nose_parameterized import parameterized +from modularodm import Q + from tests import factories from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase, SearchTestCase @@ -62,7 +64,7 @@ def make_project(status, user, perms): def make_registration(status, user, perms): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - mock_archive(project, autocomplete=True, autoapprove=True).__enter__() + mock_archive(project, autocomplete=True, autoapprove=True).__enter__() # ?! return 'title' def make_component(status, user, perms): @@ -114,12 +116,28 @@ def test_mp_makes_public_project_public(self): def test_mr_specifies_title(self): assert make_registration('private', None, None) == 'title' + def test_mr_makes_private_registration_public_there_are_no_private_registrations(self): + make_registration(PRIVATE, None, None) + assert Node.find_one(Q('is_registration', 'eq', True)).is_public + + def test_mr_makes_public_registration_public(self): + make_registration(PUBLIC, None, None) + assert Node.find_one(Q('is_registration', 'eq', True)).is_public + # mc - make_component def test_mc_specifies_title(self): assert make_component('private', None, None) == 'title' + def test_mc_makes_private_component_private(self): + make_component(PRIVATE, None, None) + assert not Node.find_one(Q('parent_node', 'ne', None)).is_public + + def test_mc_makes_public_component_public(self): + make_component(PUBLIC, None, None) + assert Node.find_one(Q('parent_node', 'ne', None)).is_public + # mf - make_file From ab07f2c6499606b8df138de4c02f4cb54ccdc5c7 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 15:14:03 -0400 Subject: [PATCH 17/65] Additional tests for files --- tests/test_search/test_views.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 33e87609612..53757355768 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -10,6 +10,7 @@ from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase, SearchTestCase from tests.utils import mock_archive +from website.files.models.base import File from website.project.model import Node from website.util import api_url_for @@ -144,6 +145,15 @@ def test_mc_makes_public_component_public(self): def test_mf_specifies_name(self): assert make_file('private', None, None) == 'name' + def test_mf_makes_private_file_private(self): + make_file(PRIVATE, None, None) + # Looks like privacy attaches to the node, not the file + assert not File.find_one(Q('is_file', 'eq', True)).node.is_public + + def test_mf_makes_public_file_public(self): + make_file(PUBLIC, None, None) + assert File.find_one(Q('is_file', 'eq', True)).node.is_public + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. From e75452f7dc85ab96b81f5b04bac7b5d74787b240 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 15:53:08 -0400 Subject: [PATCH 18/65] Check for default permissions --- tests/test_search/test_views.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 53757355768..b395f83063f 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -111,6 +111,11 @@ def test_mp_makes_public_project_public(self): make_project(PUBLIC, None, None) assert Node.find_one().is_public + def test_mp_uses_default_permissions(self): + make_project(PUBLIC, None, None) + node = Node.find_one() + assert node.permissions == {node.creator._id: ['read', 'write', 'admin']} + # mr - make_registration @@ -139,6 +144,11 @@ def test_mc_makes_public_component_public(self): make_component(PUBLIC, None, None) assert Node.find_one(Q('parent_node', 'ne', None)).is_public + def test_mc_uses_default_permissions(self): + make_component(PUBLIC, None, None) + node = Node.find_one(Q('parent_node', 'ne', None)) + assert node.permissions == {node.creator._id: ['read', 'write', 'admin']} + # mf - make_file @@ -154,6 +164,11 @@ def test_mf_makes_public_file_public(self): make_file(PUBLIC, None, None) assert File.find_one(Q('is_file', 'eq', True)).node.is_public + def test_mf_uses_default_permissions(self): + make_file(PUBLIC, None, None) + node = File.find_one(Q('is_file', 'eq', True)).node + assert node.permissions == {node.creator._id: ['read', 'write', 'admin']} + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. From c33663f422e7c81eaea89935bf8dbd04bafaedae Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 19 Sep 2016 16:26:54 -0400 Subject: [PATCH 19/65] Don't return from makers I think we'll want to return something else? --- tests/test_search/test_views.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index b395f83063f..fda76b2e1cf 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -61,12 +61,10 @@ def test_search_projects(self): def make_project(status, user, perms): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) project.update_search() - return 'title' def make_registration(status, user, perms): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) mock_archive(project, autocomplete=True, autoapprove=True).__enter__() # ?! - return 'title' def make_component(status, user, perms): project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) @@ -77,12 +75,10 @@ def make_component(status, user, perms): is_public=status is PUBLIC, ) component.update_search() - return 'title' def make_file(status, user, perms): project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) project.get_addon('osfstorage').get_root().append_file('Flim Flammity') - return 'name' makers = { PROJECT: make_project, @@ -187,7 +183,8 @@ def test(self, ignored, status, type_, perms, included): user = factories.AuthUserFactory() make = makers[type_] - key = make(status, user, perms) + make(status, user, perms) + key = 'name' if make is make_file else 'title' expected = [('Flim Flammity', type_)] if included else [] results = self.results('flim', type_, user.auth if user else None) assert_equal([(x[key], x['category']) for x in results], expected) From bacab8071ec63ecd8bea33236eea59a03a1aeccb Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 23 Sep 2016 18:23:54 -0400 Subject: [PATCH 20/65] Wire up a contributor: *now* they're failing tests --- tests/test_search/test_views.py | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index fda76b2e1cf..8bb0758118e 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -12,7 +12,7 @@ from tests.utils import mock_archive from website.files.models.base import File from website.project.model import Node -from website.util import api_url_for +from website.util import api_url_for, permissions class TestSearchPage(SearchTestCase): @@ -25,7 +25,7 @@ def test_search_projects(self): PRIVATE, PUBLIC = range(2) PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() -ANON, AUTH, READ = (None, '', 'r') +ANON, AUTH, READ = (None, [], [permissions.READ]) Y, N = True, False cases = [ @@ -58,15 +58,17 @@ def test_search_projects(self): ("public file shown to read", PUBLIC, FILE, READ, Y), ] -def make_project(status, user, perms): +def make_project(status): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) project.update_search() + return project -def make_registration(status, user, perms): +def make_registration(status): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) mock_archive(project, autocomplete=True, autoapprove=True).__enter__() # ?! + return project -def make_component(status, user, perms): +def make_component(status): project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) project.update_search() component = factories.NodeFactory( @@ -75,10 +77,12 @@ def make_component(status, user, perms): is_public=status is PUBLIC, ) component.update_search() + return component -def make_file(status, user, perms): +def make_file(status): project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) project.get_addon('osfstorage').get_root().append_file('Flim Flammity') + return project makers = { PROJECT: make_project, @@ -119,6 +123,7 @@ def test_mr_specifies_title(self): assert make_registration('private', None, None) == 'title' def test_mr_makes_private_registration_public_there_are_no_private_registrations(self): + # TODO Instead we need to test the different approval/embargo workflow states make_registration(PRIVATE, None, None) assert Node.find_one(Q('is_registration', 'eq', True)).is_public @@ -175,18 +180,21 @@ def results(self, query, category, auth): data = {'q': 'category:{} AND {}'.format(category, query)} return self.app.get(url, data, auth=auth).json['results'] - @parameterized.expand(cases) def test(self, ignored, status, type_, perms, included): - user = None + make = makers[type_] + thing = make(status) + key = 'name' if make is make_file else 'title' + + auth = None if perms is not None: user = factories.AuthUserFactory() + auth = user.auth + if perms: + thing.add_contributor(user, perms) - make = makers[type_] - make(status, user, perms) - key = 'name' if make is make_file else 'title' expected = [('Flim Flammity', type_)] if included else [] - results = self.results('flim', type_, user.auth if user else None) + results = self.results('flim', type_, auth) assert_equal([(x[key], x['category']) for x in results], expected) From 7260be15cbc4765eb61cce5e85c679f63e4a62d1 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 26 Sep 2016 09:45:08 -0400 Subject: [PATCH 21/65] Remove some tests that don't matter anymore I had though to vary the perms on the creator, but instead we're now adding a contributor. --- tests/test_search/test_views.py | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 8bb0758118e..fb4ac96a6f8 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -111,11 +111,6 @@ def test_mp_makes_public_project_public(self): make_project(PUBLIC, None, None) assert Node.find_one().is_public - def test_mp_uses_default_permissions(self): - make_project(PUBLIC, None, None) - node = Node.find_one() - assert node.permissions == {node.creator._id: ['read', 'write', 'admin']} - # mr - make_registration @@ -145,11 +140,6 @@ def test_mc_makes_public_component_public(self): make_component(PUBLIC, None, None) assert Node.find_one(Q('parent_node', 'ne', None)).is_public - def test_mc_uses_default_permissions(self): - make_component(PUBLIC, None, None) - node = Node.find_one(Q('parent_node', 'ne', None)) - assert node.permissions == {node.creator._id: ['read', 'write', 'admin']} - # mf - make_file @@ -165,11 +155,6 @@ def test_mf_makes_public_file_public(self): make_file(PUBLIC, None, None) assert File.find_one(Q('is_file', 'eq', True)).node.is_public - def test_mf_uses_default_permissions(self): - make_file(PUBLIC, None, None) - node = File.find_one(Q('is_file', 'eq', True)).node - assert node.permissions == {node.creator._id: ['read', 'write', 'admin']} - class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. From 7631317c605893bff06b7990da953500e53d5688 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 26 Sep 2016 14:26:29 -0400 Subject: [PATCH 22/65] Remove more out of date tests --- tests/test_search/test_views.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index fb4ac96a6f8..9d42d8e02a6 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -100,9 +100,6 @@ def test_there_are_no_nodes_to_start_with(self): # mp - make_project - def test_mp_specifies_title(self): - assert make_project('private', None, None) == 'title' - def test_mp_makes_private_project_private(self): make_project(PRIVATE, None, None) assert not Node.find_one().is_public @@ -114,9 +111,6 @@ def test_mp_makes_public_project_public(self): # mr - make_registration - def test_mr_specifies_title(self): - assert make_registration('private', None, None) == 'title' - def test_mr_makes_private_registration_public_there_are_no_private_registrations(self): # TODO Instead we need to test the different approval/embargo workflow states make_registration(PRIVATE, None, None) @@ -129,9 +123,6 @@ def test_mr_makes_public_registration_public(self): # mc - make_component - def test_mc_specifies_title(self): - assert make_component('private', None, None) == 'title' - def test_mc_makes_private_component_private(self): make_component(PRIVATE, None, None) assert not Node.find_one(Q('parent_node', 'ne', None)).is_public @@ -143,9 +134,6 @@ def test_mc_makes_public_component_public(self): # mf - make_file - def test_mf_specifies_name(self): - assert make_file('private', None, None) == 'name' - def test_mf_makes_private_file_private(self): make_file(PRIVATE, None, None) # Looks like privacy attaches to the node, not the file From 37b41b9388b50d5f5509f24a08535049fdcf3969 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 14:03:00 -0400 Subject: [PATCH 23/65] The thing is a node --- tests/test_search/test_views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 9d42d8e02a6..1e581191b0c 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -156,7 +156,7 @@ def results(self, query, category, auth): @parameterized.expand(cases) def test(self, ignored, status, type_, perms, included): make = makers[type_] - thing = make(status) + node = make(status) key = 'name' if make is make_file else 'title' auth = None @@ -164,7 +164,7 @@ def test(self, ignored, status, type_, perms, included): user = factories.AuthUserFactory() auth = user.auth if perms: - thing.add_contributor(user, perms) + node.add_contributor(user, perms) expected = [('Flim Flammity', type_)] if included else [] results = self.results('flim', type_, auth) From 9367f1a402c5a7018b04581c84cd4adc7e599f4e Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 14:08:43 -0400 Subject: [PATCH 24/65] Fix TestMakers --- tests/test_search/test_views.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 1e581191b0c..bd537499db7 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -101,11 +101,11 @@ def test_there_are_no_nodes_to_start_with(self): # mp - make_project def test_mp_makes_private_project_private(self): - make_project(PRIVATE, None, None) + make_project(PRIVATE) assert not Node.find_one().is_public def test_mp_makes_public_project_public(self): - make_project(PUBLIC, None, None) + make_project(PUBLIC) assert Node.find_one().is_public @@ -113,34 +113,34 @@ def test_mp_makes_public_project_public(self): def test_mr_makes_private_registration_public_there_are_no_private_registrations(self): # TODO Instead we need to test the different approval/embargo workflow states - make_registration(PRIVATE, None, None) + make_registration(PRIVATE) assert Node.find_one(Q('is_registration', 'eq', True)).is_public def test_mr_makes_public_registration_public(self): - make_registration(PUBLIC, None, None) + make_registration(PUBLIC) assert Node.find_one(Q('is_registration', 'eq', True)).is_public # mc - make_component def test_mc_makes_private_component_private(self): - make_component(PRIVATE, None, None) + make_component(PRIVATE) assert not Node.find_one(Q('parent_node', 'ne', None)).is_public def test_mc_makes_public_component_public(self): - make_component(PUBLIC, None, None) + make_component(PUBLIC) assert Node.find_one(Q('parent_node', 'ne', None)).is_public # mf - make_file def test_mf_makes_private_file_private(self): - make_file(PRIVATE, None, None) + make_file(PRIVATE) # Looks like privacy attaches to the node, not the file assert not File.find_one(Q('is_file', 'eq', True)).node.is_public def test_mf_makes_public_file_public(self): - make_file(PUBLIC, None, None) + make_file(PUBLIC) assert File.find_one(Q('is_file', 'eq', True)).node.is_public From 2f3bd8a7cc6f596c69874a79d8f4b60fe8322ba7 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 14:40:23 -0400 Subject: [PATCH 25/65] Start evolving towards a generator Nose-parameterized can take a generator. That means we can generate our list of test cases dynamically based on the various dimensions we want. --- tests/test_search/test_views.py | 87 ++++++++++++++++----------------- 1 file changed, 41 insertions(+), 46 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index bd537499db7..e04461340aa 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -22,42 +22,6 @@ def test_search_projects(self): res = self.app.get('/search/', {'q': 'foo'}) assert_equal(res.status_code, 200) - -PRIVATE, PUBLIC = range(2) -PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() -ANON, AUTH, READ = (None, [], [permissions.READ]) -Y, N = True, False - -cases = [ - ("private project hidden from anon", PRIVATE, PROJECT, ANON, N), - ("private component hidden from anon", PRIVATE, COMPONENT, ANON, N), - ("private file hidden from anon", PRIVATE, FILE, ANON, N), - - ("private project hidden from auth", PRIVATE, PROJECT, AUTH, N), - ("private component hidden from auth", PRIVATE, COMPONENT, AUTH, N), - ("private file hidden from auth", PRIVATE, FILE, AUTH, N), - - ("private project shown to read", PRIVATE, PROJECT, READ, Y), - ("private component shown to read", PRIVATE, COMPONENT, READ, Y), - ("private file shown to read", PRIVATE, FILE, READ, Y), - - - ("public project shown to anon", PUBLIC, PROJECT, ANON, Y), - ("public registration shown to anon", PUBLIC, REGISTRATION, ANON, Y), - ("public component shown to anon", PUBLIC, COMPONENT, ANON, Y), - ("public file shown to anon", PUBLIC, FILE, ANON, Y), - - ("public project shown to auth", PUBLIC, PROJECT, AUTH, Y), - ("public registration shown to auth", PUBLIC, REGISTRATION, AUTH, Y), - ("public component shown to auth", PUBLIC, COMPONENT, AUTH, Y), - ("public file shown to auth", PUBLIC, FILE, AUTH, Y), - - ("public project shown to read", PUBLIC, PROJECT, READ, Y), - ("public registration shown to read", PUBLIC, REGISTRATION, READ, Y), - ("public component shown to read", PUBLIC, COMPONENT, READ, Y), - ("public file shown to read", PUBLIC, FILE, READ, Y), -] - def make_project(status): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) project.update_search() @@ -84,13 +48,6 @@ def make_file(status): project.get_addon('osfstorage').get_root().append_file('Flim Flammity') return project -makers = { - PROJECT: make_project, - REGISTRATION: make_registration, - COMPONENT: make_component, - FILE: make_file, -} - class TestMakers(DbIsolationMixin, OsfTestCase): @@ -144,6 +101,46 @@ def test_mf_makes_public_file_public(self): assert File.find_one(Q('is_file', 'eq', True)).node.is_public +PRIVATE, PUBLIC = range(2) +PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() +ANON, AUTH, READ = (None, [], [permissions.READ]) +Y, N = True, False + +_cases = [ + ("private project hidden from anon", make_project, PRIVATE, ANON, PROJECT, N, 'title'), + ("private component hidden from anon", make_component, PRIVATE, ANON, COMPONENT, N, 'title'), + ("private file hidden from anon", make_file, PRIVATE, ANON, FILE, N, 'name'), + + ("private project hidden from auth", make_project, PRIVATE, AUTH, PROJECT, N, 'title'), + ("private component hidden from auth", make_component, PRIVATE, AUTH, COMPONENT, N, 'title'), + ("private file hidden from auth", make_file, PRIVATE, AUTH, FILE, N, 'name'), + + ("private project shown to read", make_project, PRIVATE, READ, PROJECT, Y, 'title'), + ("private component shown to read", make_component, PRIVATE, READ, COMPONENT, Y, 'title'), + ("private file shown to read", make_file, PRIVATE, READ, FILE, Y, 'name'), + + + ("public project shown to anon", make_project, PUBLIC, ANON, PROJECT, Y, 'title'), + ("public registration shown to anon", make_registration, PUBLIC, ANON, REGISTRATION, Y, 'title'), + ("public component shown to anon", make_component, PUBLIC, ANON, COMPONENT, Y, 'title'), + ("public file shown to anon", make_file, PUBLIC, ANON, FILE, Y, 'name'), + + ("public project shown to auth", make_project, PUBLIC, AUTH, PROJECT, Y, 'title'), + ("public registration shown to auth", make_registration, PUBLIC, AUTH, REGISTRATION, Y, 'title'), + ("public component shown to auth", make_component, PUBLIC, AUTH, COMPONENT, Y, 'title'), + ("public file shown to auth", make_file, PUBLIC, AUTH, FILE, Y, 'name'), + + ("public project shown to read", make_project, PUBLIC, READ, PROJECT, Y, 'title'), + ("public registration shown to read", make_registration, PUBLIC, READ, REGISTRATION, Y, 'title'), + ("public component shown to read", make_component, PUBLIC, READ, COMPONENT, Y, 'title'), + ("public file shown to read", make_file, PUBLIC, READ, FILE, Y, 'name'), +] + +def cases(): + for case in _cases: + yield case + + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ @@ -154,10 +151,8 @@ def results(self, query, category, auth): return self.app.get(url, data, auth=auth).json['results'] @parameterized.expand(cases) - def test(self, ignored, status, type_, perms, included): - make = makers[type_] + def test(self, ignored, make, status, perms, type_, included, key): node = make(status) - key = 'name' if make is make_file else 'title' auth = None if perms is not None: From 68ff540ec1719abe67c916822f6c0d41491d45a3 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 15:11:01 -0400 Subject: [PATCH 26/65] Generate test cases programmatically This paves the way for complexifying the test matrix. --- tests/test_search/test_views.py | 52 +++++++++++++-------------------- 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index e04461340aa..0e6c1f9c409 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -104,41 +104,31 @@ def test_mf_makes_public_file_public(self): PRIVATE, PUBLIC = range(2) PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() ANON, AUTH, READ = (None, [], [permissions.READ]) -Y, N = True, False -_cases = [ - ("private project hidden from anon", make_project, PRIVATE, ANON, PROJECT, N, 'title'), - ("private component hidden from anon", make_component, PRIVATE, ANON, COMPONENT, N, 'title'), - ("private file hidden from anon", make_file, PRIVATE, ANON, FILE, N, 'name'), - - ("private project hidden from auth", make_project, PRIVATE, AUTH, PROJECT, N, 'title'), - ("private component hidden from auth", make_component, PRIVATE, AUTH, COMPONENT, N, 'title'), - ("private file hidden from auth", make_file, PRIVATE, AUTH, FILE, N, 'name'), - - ("private project shown to read", make_project, PRIVATE, READ, PROJECT, Y, 'title'), - ("private component shown to read", make_component, PRIVATE, READ, COMPONENT, Y, 'title'), - ("private file shown to read", make_file, PRIVATE, READ, FILE, Y, 'name'), - - - ("public project shown to anon", make_project, PUBLIC, ANON, PROJECT, Y, 'title'), - ("public registration shown to anon", make_registration, PUBLIC, ANON, REGISTRATION, Y, 'title'), - ("public component shown to anon", make_component, PUBLIC, ANON, COMPONENT, Y, 'title'), - ("public file shown to anon", make_file, PUBLIC, ANON, FILE, Y, 'name'), - - ("public project shown to auth", make_project, PUBLIC, AUTH, PROJECT, Y, 'title'), - ("public registration shown to auth", make_registration, PUBLIC, AUTH, REGISTRATION, Y, 'title'), - ("public component shown to auth", make_component, PUBLIC, AUTH, COMPONENT, Y, 'title'), - ("public file shown to auth", make_file, PUBLIC, AUTH, FILE, Y, 'name'), +def get_test_name(status, type_, included, perms, **_): + return "{} {} {} {}".format( + 'private' if status is PRIVATE else 'public', + type_, + 'shown to' if included else 'hidden from', + 'anon' if perms is ANON else 'auth' if perms is AUTH else 'read' + ) - ("public project shown to read", make_project, PUBLIC, READ, PROJECT, Y, 'title'), - ("public registration shown to read", make_registration, PUBLIC, READ, REGISTRATION, Y, 'title'), - ("public component shown to read", make_component, PUBLIC, READ, COMPONENT, Y, 'title'), - ("public file shown to read", make_file, PUBLIC, READ, FILE, Y, 'name'), -] +MAKERS = { + PROJECT: make_project, + REGISTRATION: make_registration, + COMPONENT: make_component, + FILE: make_file, +} def cases(): - for case in _cases: - yield case + for status in (PRIVATE, PUBLIC): + for type_ in (PROJECT, REGISTRATION, COMPONENT, FILE): + make = MAKERS[type_] + if status is PRIVATE and type_ is REGISTRATION: continue + for perms in (ANON, AUTH, READ): + included = perms is READ if status is PRIVATE else True + key = 'name' if type_ is FILE else 'title' + yield get_test_name(**locals()), make, status, perms, type_, included, key class TestSearchSearchAPI(SearchTestCase): From 59f9fab7ee06e2af67fff97185eadaf822685f43 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 15:34:33 -0400 Subject: [PATCH 27/65] Add a couple tests for the generator itself --- tests/test_search/test_views.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 0e6c1f9c409..9bc5795df8f 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -1,6 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals +import unittest + from nose.tools import * # noqa PEP8 asserts from nose_parameterized import parameterized @@ -120,7 +122,7 @@ def get_test_name(status, type_, included, perms, **_): FILE: make_file, } -def cases(): +def generate_cases(): for status in (PRIVATE, PUBLIC): for type_ in (PROJECT, REGISTRATION, COMPONENT, FILE): make = MAKERS[type_] @@ -131,6 +133,18 @@ def cases(): yield get_test_name(**locals()), make, status, perms, type_, included, key +class TestGenerateCases(unittest.TestCase): + + # gc - generate_cases + + def test_gc_generates_cases(self): + assert_equal(len(list(generate_cases())), 21) + + def test_gc_doesnt_create_any_nodes(self): + list(generate_cases()) + assert_equal(len(Node.find()), 0) + + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ @@ -140,7 +154,7 @@ def results(self, query, category, auth): data = {'q': 'category:{} AND {}'.format(category, query)} return self.app.get(url, data, auth=auth).json['results'] - @parameterized.expand(cases) + @parameterized.expand(generate_cases) def test(self, ignored, make, status, perms, type_, included, key): node = make(status) From 2c5bb2e0db9a9ef6d098e55242dde25e24f902a2 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 16:29:41 -0400 Subject: [PATCH 28/65] Push perms work out of test func Seems to be the pattern here to keep the test function itself quite minimal, and use functional programming to build up the cases. --- tests/test_search/test_views.py | 35 +++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 9bc5795df8f..f5b10844601 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -105,14 +105,13 @@ def test_mf_makes_public_file_public(self): PRIVATE, PUBLIC = range(2) PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() -ANON, AUTH, READ = (None, [], [permissions.READ]) -def get_test_name(status, type_, included, perms, **_): +def get_test_name(status, type_, included, permfunc, **_): return "{} {} {} {}".format( 'private' if status is PRIVATE else 'public', type_, 'shown to' if included else 'hidden from', - 'anon' if perms is ANON else 'auth' if perms is AUTH else 'read' + permfunc.__name__ ) MAKERS = { @@ -122,15 +121,28 @@ def get_test_name(status, type_, included, perms, **_): FILE: make_file, } + +def anon(node): + return None + +def auth(node): + return factories.AuthUserFactory().auth + +def read(node): + user = factories.AuthUserFactory() + node.add_contributor(user, permissions.READ) + return user.auth + + def generate_cases(): for status in (PRIVATE, PUBLIC): for type_ in (PROJECT, REGISTRATION, COMPONENT, FILE): make = MAKERS[type_] if status is PRIVATE and type_ is REGISTRATION: continue - for perms in (ANON, AUTH, READ): - included = perms is READ if status is PRIVATE else True + for permfunc in (anon, auth, read): + included = permfunc is read if status is PRIVATE else True key = 'name' if type_ is FILE else 'title' - yield get_test_name(**locals()), make, status, perms, type_, included, key + yield get_test_name(**locals()), make, status, permfunc, type_, included, key class TestGenerateCases(unittest.TestCase): @@ -155,16 +167,9 @@ def results(self, query, category, auth): return self.app.get(url, data, auth=auth).json['results'] @parameterized.expand(generate_cases) - def test(self, ignored, make, status, perms, type_, included, key): + def test(self, ignored, make, status, permfunc, type_, included, key): node = make(status) - - auth = None - if perms is not None: - user = factories.AuthUserFactory() - auth = user.auth - if perms: - node.add_contributor(user, perms) - + auth = permfunc(node) expected = [('Flim Flammity', type_)] if included else [] results = self.results('flim', type_, auth) assert_equal([(x[key], x['category']) for x in results], expected) From 28ca96b62b943d739edf0ebc7c0b6a2d003f2216 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 27 Sep 2016 16:52:21 -0400 Subject: [PATCH 29/65] Add a test suite for the permfuncs --- tests/test_search/test_views.py | 46 +++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index f5b10844601..814f8c252d5 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -8,6 +8,7 @@ from modularodm import Q +from framework.auth.core import User from tests import factories from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase, SearchTestCase @@ -134,6 +135,51 @@ def read(node): return user.auth +class TestPermFuncs(DbIsolationMixin, OsfTestCase): + + @staticmethod + def get_user_id_from_authtuple(authtuple): + return User.find_one(Q('emails', 'eq', authtuple[0]))._id + + + # anon + + def test_anon_returns_none(self): + assert_equal(anon(make_project(PUBLIC)), None) + + def test_anon_makes_no_user(self): + anon(make_project(PUBLIC)) + assert_equal(len(User.find()), 1) # only the project creator + + + # auth + + def test_auth_returns_authtuple(self): + assert_equal(auth(make_project(PUBLIC))[1], 'password') + + def test_auth_creates_a_user(self): + auth(make_project(PUBLIC)) + assert_equal(len(User.find()), 2) # project creator + 1 + + def test_auth_user_is_not_a_contributor_on_the_node(self): + user_id = self.get_user_id_from_authtuple(auth(make_project(PUBLIC))) + assert_not_in(user_id, Node.find_one().permissions.keys()) + + + # read + + def test_read_returns_authtuple(self): + assert_equal(read(make_project(PUBLIC))[1], 'password') + + def test_read_creates_a_user(self): + read(make_project(PUBLIC)) + assert_equal(len(User.find()), 2) # project creator + 1 + + def test_read_user_is_a_contributor_on_the_node(self): + user_id = self.get_user_id_from_authtuple(read(make_project(PUBLIC))) + assert_in(user_id, Node.find_one().permissions.keys()) + + def generate_cases(): for status in (PRIVATE, PUBLIC): for type_ in (PROJECT, REGISTRATION, COMPONENT, FILE): From c0bafac100353896f959bdf196d5c56442d8652f Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 28 Sep 2016 08:40:31 -0400 Subject: [PATCH 30/65] Factor out varyfuncs and nodefuncs --- tests/test_search/test_views.py | 181 +++++++++++++++++--------------- 1 file changed, 97 insertions(+), 84 deletions(-) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index 814f8c252d5..c412a3bbd89 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -25,18 +25,23 @@ def test_search_projects(self): res = self.app.get('/search/', {'q': 'foo'}) assert_equal(res.status_code, 200) -def make_project(status): - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - project.update_search() - return project -def make_registration(status): +################################################################################################### +# Search Permissions Tests + +PRIVATE, PUBLIC = range(2) +PROJECT, COMPONENT = 'project component'.split() + + +# nodefuncs + +def proj(status=PUBLIC): project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - mock_archive(project, autocomplete=True, autoapprove=True).__enter__() # ?! + project.update_search() return project -def make_component(status): - project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) +def comp(status=PUBLIC): + project = factories.ProjectFactory(title='Slim Slammity', is_public=status is PUBLIC) project.update_search() component = factories.NodeFactory( title='Flim Flammity', @@ -46,82 +51,36 @@ def make_component(status): component.update_search() return component -def make_file(status): - project = factories.ProjectFactory(title='Blim Blammity', is_public=status is PUBLIC) - project.get_addon('osfstorage').get_root().append_file('Flim Flammity') - return project - -class TestMakers(DbIsolationMixin, OsfTestCase): +class TestNodeFuncs(DbIsolationMixin, OsfTestCase): def test_there_are_no_nodes_to_start_with(self): assert Node.find().count() == 0 - # mp - make_project + # proj - def test_mp_makes_private_project_private(self): - make_project(PRIVATE) + def test_proj_makes_private_project_private(self): + proj(PRIVATE) assert not Node.find_one().is_public - def test_mp_makes_public_project_public(self): - make_project(PUBLIC) + def test_proj_makes_public_project_public(self): + proj(PUBLIC) assert Node.find_one().is_public - # mr - make_registration - - def test_mr_makes_private_registration_public_there_are_no_private_registrations(self): - # TODO Instead we need to test the different approval/embargo workflow states - make_registration(PRIVATE) - assert Node.find_one(Q('is_registration', 'eq', True)).is_public - - def test_mr_makes_public_registration_public(self): - make_registration(PUBLIC) - assert Node.find_one(Q('is_registration', 'eq', True)).is_public + # comp - - # mc - make_component - - def test_mc_makes_private_component_private(self): - make_component(PRIVATE) + def test_comp_makes_private_component_private(self): + comp(PRIVATE) assert not Node.find_one(Q('parent_node', 'ne', None)).is_public - def test_mc_makes_public_component_public(self): - make_component(PUBLIC) + def test_comp_makes_public_component_public(self): + comp(PUBLIC) assert Node.find_one(Q('parent_node', 'ne', None)).is_public - # mf - make_file - - def test_mf_makes_private_file_private(self): - make_file(PRIVATE) - # Looks like privacy attaches to the node, not the file - assert not File.find_one(Q('is_file', 'eq', True)).node.is_public - - def test_mf_makes_public_file_public(self): - make_file(PUBLIC) - assert File.find_one(Q('is_file', 'eq', True)).node.is_public - - -PRIVATE, PUBLIC = range(2) -PROJECT, REGISTRATION, COMPONENT, FILE = 'project registration component file'.split() - -def get_test_name(status, type_, included, permfunc, **_): - return "{} {} {} {}".format( - 'private' if status is PRIVATE else 'public', - type_, - 'shown to' if included else 'hidden from', - permfunc.__name__ - ) - -MAKERS = { - PROJECT: make_project, - REGISTRATION: make_registration, - COMPONENT: make_component, - FILE: make_file, -} - +# permfuncs def anon(node): return None @@ -145,50 +104,100 @@ def get_user_id_from_authtuple(authtuple): # anon def test_anon_returns_none(self): - assert_equal(anon(make_project(PUBLIC)), None) + assert_equal(anon(proj(PUBLIC)), None) def test_anon_makes_no_user(self): - anon(make_project(PUBLIC)) + anon(proj(PUBLIC)) assert_equal(len(User.find()), 1) # only the project creator # auth def test_auth_returns_authtuple(self): - assert_equal(auth(make_project(PUBLIC))[1], 'password') + assert_equal(auth(proj(PUBLIC))[1], 'password') def test_auth_creates_a_user(self): - auth(make_project(PUBLIC)) + auth(proj(PUBLIC)) assert_equal(len(User.find()), 2) # project creator + 1 def test_auth_user_is_not_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(auth(make_project(PUBLIC))) + user_id = self.get_user_id_from_authtuple(auth(proj(PUBLIC))) assert_not_in(user_id, Node.find_one().permissions.keys()) # read def test_read_returns_authtuple(self): - assert_equal(read(make_project(PUBLIC))[1], 'password') + assert_equal(read(proj(PUBLIC))[1], 'password') def test_read_creates_a_user(self): - read(make_project(PUBLIC)) + read(proj(PUBLIC)) assert_equal(len(User.find()), 2) # project creator + 1 def test_read_user_is_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(read(make_project(PUBLIC))) + user_id = self.get_user_id_from_authtuple(read(proj(PUBLIC))) assert_in(user_id, Node.find_one().permissions.keys()) +# varyfuncs + +def base(node): + type_ = 'project' if node.parent_node is None else 'component' + return 'flim', type_, 'title', 'Flim Flammity' + +def file_on(node): + node.get_addon('osfstorage').get_root().append_file('Blim Blammity') + return 'blim', 'file', 'name', 'Blim Blammity' + +def registration_of(node): + mock_archive(node, autocomplete=True, autoapprove=True).__enter__() # ?! + return 'flim', 'registration', 'title', 'Flim Flammity' + + +class TestVaryFuncs(DbIsolationMixin, OsfTestCase): + + # base + + def test_base_specifies_project_for_project(self): + assert_equal(base(proj())[1], 'project') + + def test_base_specifies_component_for_component(self): + assert_equal(base(comp())[1], 'component') + + + # fo - file_on + + def test_fo_makes_a_file_on_a_node(self): + file_on(factories.ProjectFactory()) + assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') + + + # ro - registration_of + + def test_ro_makes_a_registration_of_a_node(self): + registration_of(factories.ProjectFactory(title='Flim Flammity')) + assert_equal(Node.find_one(Q('is_registration', 'eq', True)).title, 'Flim Flammity') + + +# gettin' it together + +def namefunc(varyfunc, status, nodefunc, included, permfunc, **_): + return "{}{} {} {} {}".format( + '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', + 'private' if status is PRIVATE else 'public', + 'project' if nodefunc is proj else 'component', + 'shown to' if included else 'hidden from', + permfunc.__name__ + ) + def generate_cases(): for status in (PRIVATE, PUBLIC): - for type_ in (PROJECT, REGISTRATION, COMPONENT, FILE): - make = MAKERS[type_] - if status is PRIVATE and type_ is REGISTRATION: continue + for nodefunc in (proj, comp): for permfunc in (anon, auth, read): included = permfunc is read if status is PRIVATE else True - key = 'name' if type_ is FILE else 'title' - yield get_test_name(**locals()), make, status, permfunc, type_, included, key + for varyfunc in (base, file_on, registration_of): + if status is PRIVATE and varyfunc is registration_of: continue + yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, included class TestGenerateCases(unittest.TestCase): @@ -196,7 +205,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 21) + assert_equal(len(list(generate_cases())), 30) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) @@ -213,13 +222,17 @@ def results(self, query, category, auth): return self.app.get(url, data, auth=auth).json['results'] @parameterized.expand(generate_cases) - def test(self, ignored, make, status, permfunc, type_, included, key): - node = make(status) + def test(self, ignored, varyfunc, nodefunc, status, permfunc, included): + node = nodefunc(status) auth = permfunc(node) - expected = [('Flim Flammity', type_)] if included else [] - results = self.results('flim', type_, auth) + query, type_, key, expected_name = varyfunc(node) + expected = [(expected_name, type_)] if included else [] + results = self.results(query, type_, auth) assert_equal([(x[key], x['category']) for x in results], expected) +# +################################################################################################### + class TestUserSearchAPI(SearchTestCase): From 58f12a367b257b82d18037990ae4f031c11245de Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 28 Sep 2016 08:53:19 -0400 Subject: [PATCH 31/65] Move permissions tests to their own file --- tests/test_search/test_permissions.py | 219 +++++++++++++++++++++++++ tests/test_search/test_views.py | 222 +------------------------- 2 files changed, 221 insertions(+), 220 deletions(-) create mode 100644 tests/test_search/test_permissions.py diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py new file mode 100644 index 00000000000..ca78afc243a --- /dev/null +++ b/tests/test_search/test_permissions.py @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function, unicode_literals + +import unittest + +from nose.tools import * # noqa PEP8 asserts + +from framework.auth.core import User +from modularodm import Q +from nose_parameterized import parameterized +from tests import factories +from tests.base import DbIsolationMixin +from tests.test_search import OsfTestCase, SearchTestCase +from tests.utils import mock_archive +from website.files.models.base import File +from website.project.model import Node +from website.util import api_url_for, permissions + + +PRIVATE, PUBLIC = range(2) +PROJECT, COMPONENT = 'project component'.split() + + +# nodefuncs + +def proj(status=PUBLIC): + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + project.update_search() + return project + +def comp(status=PUBLIC): + project = factories.ProjectFactory(title='Slim Slammity', is_public=status is PUBLIC) + project.update_search() + component = factories.NodeFactory( + title='Flim Flammity', + parent=project, + is_public=status is PUBLIC, + ) + component.update_search() + return component + + +class TestNodeFuncs(DbIsolationMixin, OsfTestCase): + + def test_there_are_no_nodes_to_start_with(self): + assert Node.find().count() == 0 + + + # proj + + def test_proj_makes_private_project_private(self): + proj(PRIVATE) + assert not Node.find_one().is_public + + def test_proj_makes_public_project_public(self): + proj(PUBLIC) + assert Node.find_one().is_public + + + # comp + + def test_comp_makes_private_component_private(self): + comp(PRIVATE) + assert not Node.find_one(Q('parent_node', 'ne', None)).is_public + + def test_comp_makes_public_component_public(self): + comp(PUBLIC) + assert Node.find_one(Q('parent_node', 'ne', None)).is_public + + +# permfuncs + +def anon(node): + return None + +def auth(node): + return factories.AuthUserFactory().auth + +def read(node): + user = factories.AuthUserFactory() + node.add_contributor(user, permissions.READ) + return user.auth + + +class TestPermFuncs(DbIsolationMixin, OsfTestCase): + + @staticmethod + def get_user_id_from_authtuple(authtuple): + return User.find_one(Q('emails', 'eq', authtuple[0]))._id + + + # anon + + def test_anon_returns_none(self): + assert_equal(anon(proj(PUBLIC)), None) + + def test_anon_makes_no_user(self): + anon(proj(PUBLIC)) + assert_equal(len(User.find()), 1) # only the project creator + + + # auth + + def test_auth_returns_authtuple(self): + assert_equal(auth(proj(PUBLIC))[1], 'password') + + def test_auth_creates_a_user(self): + auth(proj(PUBLIC)) + assert_equal(len(User.find()), 2) # project creator + 1 + + def test_auth_user_is_not_a_contributor_on_the_node(self): + user_id = self.get_user_id_from_authtuple(auth(proj(PUBLIC))) + assert_not_in(user_id, Node.find_one().permissions.keys()) + + + # read + + def test_read_returns_authtuple(self): + assert_equal(read(proj(PUBLIC))[1], 'password') + + def test_read_creates_a_user(self): + read(proj(PUBLIC)) + assert_equal(len(User.find()), 2) # project creator + 1 + + def test_read_user_is_a_contributor_on_the_node(self): + user_id = self.get_user_id_from_authtuple(read(proj(PUBLIC))) + assert_in(user_id, Node.find_one().permissions.keys()) + + +# varyfuncs + +def base(node): + type_ = 'project' if node.parent_node is None else 'component' + return 'flim', type_, 'title', 'Flim Flammity' + +def file_on(node): + node.get_addon('osfstorage').get_root().append_file('Blim Blammity') + return 'blim', 'file', 'name', 'Blim Blammity' + +def registration_of(node): + mock_archive(node, autocomplete=True, autoapprove=True).__enter__() # ?! + return 'flim', 'registration', 'title', 'Flim Flammity' + + +class TestVaryFuncs(DbIsolationMixin, OsfTestCase): + + # base + + def test_base_specifies_project_for_project(self): + assert_equal(base(proj())[1], 'project') + + def test_base_specifies_component_for_component(self): + assert_equal(base(comp())[1], 'component') + + + # fo - file_on + + def test_fo_makes_a_file_on_a_node(self): + file_on(factories.ProjectFactory()) + assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') + + + # ro - registration_of + + def test_ro_makes_a_registration_of_a_node(self): + registration_of(factories.ProjectFactory(title='Flim Flammity')) + assert_equal(Node.find_one(Q('is_registration', 'eq', True)).title, 'Flim Flammity') + + +# gettin' it together + +def namefunc(varyfunc, status, nodefunc, included, permfunc, **_): + return "{}{} {} {} {}".format( + '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', + 'private' if status is PRIVATE else 'public', + 'project' if nodefunc is proj else 'component', + 'shown to' if included else 'hidden from', + permfunc.__name__ + ) + +def generate_cases(): + for status in (PRIVATE, PUBLIC): + for nodefunc in (proj, comp): + for permfunc in (anon, auth, read): + included = permfunc is read if status is PRIVATE else True + for varyfunc in (base, file_on, registration_of): + if status is PRIVATE and varyfunc is registration_of: continue + yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, included + + +class TestGenerateCases(unittest.TestCase): + + # gc - generate_cases + + def test_gc_generates_cases(self): + assert_equal(len(list(generate_cases())), 30) + + def test_gc_doesnt_create_any_nodes(self): + list(generate_cases()) + assert_equal(len(Node.find()), 0) + + +class TestSearchSearchAPI(SearchTestCase): + """Exercises the website.search.views.search_search view. + """ + + def results(self, query, category, auth): + url = api_url_for('search_search') + data = {'q': 'category:{} AND {}'.format(category, query)} + return self.app.get(url, data, auth=auth).json['results'] + + @parameterized.expand(generate_cases) + def test(self, ignored, varyfunc, nodefunc, status, permfunc, included): + node = nodefunc(status) + auth = permfunc(node) + query, type_, key, expected_name = varyfunc(node) + expected = [(expected_name, type_)] if included else [] + results = self.results(query, type_, auth) + assert_equal([(x[key], x['category']) for x in results], expected) diff --git a/tests/test_search/test_views.py b/tests/test_search/test_views.py index c412a3bbd89..a9b9ea0b66f 100644 --- a/tests/test_search/test_views.py +++ b/tests/test_search/test_views.py @@ -1,21 +1,11 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals -import unittest - from nose.tools import * # noqa PEP8 asserts -from nose_parameterized import parameterized - -from modularodm import Q -from framework.auth.core import User from tests import factories -from tests.base import DbIsolationMixin -from tests.test_search import OsfTestCase, SearchTestCase -from tests.utils import mock_archive -from website.files.models.base import File -from website.project.model import Node -from website.util import api_url_for, permissions +from tests.test_search import SearchTestCase +from website.util import api_url_for class TestSearchPage(SearchTestCase): @@ -26,214 +16,6 @@ def test_search_projects(self): assert_equal(res.status_code, 200) -################################################################################################### -# Search Permissions Tests - -PRIVATE, PUBLIC = range(2) -PROJECT, COMPONENT = 'project component'.split() - - -# nodefuncs - -def proj(status=PUBLIC): - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - project.update_search() - return project - -def comp(status=PUBLIC): - project = factories.ProjectFactory(title='Slim Slammity', is_public=status is PUBLIC) - project.update_search() - component = factories.NodeFactory( - title='Flim Flammity', - parent=project, - is_public=status is PUBLIC, - ) - component.update_search() - return component - - -class TestNodeFuncs(DbIsolationMixin, OsfTestCase): - - def test_there_are_no_nodes_to_start_with(self): - assert Node.find().count() == 0 - - - # proj - - def test_proj_makes_private_project_private(self): - proj(PRIVATE) - assert not Node.find_one().is_public - - def test_proj_makes_public_project_public(self): - proj(PUBLIC) - assert Node.find_one().is_public - - - # comp - - def test_comp_makes_private_component_private(self): - comp(PRIVATE) - assert not Node.find_one(Q('parent_node', 'ne', None)).is_public - - def test_comp_makes_public_component_public(self): - comp(PUBLIC) - assert Node.find_one(Q('parent_node', 'ne', None)).is_public - - -# permfuncs - -def anon(node): - return None - -def auth(node): - return factories.AuthUserFactory().auth - -def read(node): - user = factories.AuthUserFactory() - node.add_contributor(user, permissions.READ) - return user.auth - - -class TestPermFuncs(DbIsolationMixin, OsfTestCase): - - @staticmethod - def get_user_id_from_authtuple(authtuple): - return User.find_one(Q('emails', 'eq', authtuple[0]))._id - - - # anon - - def test_anon_returns_none(self): - assert_equal(anon(proj(PUBLIC)), None) - - def test_anon_makes_no_user(self): - anon(proj(PUBLIC)) - assert_equal(len(User.find()), 1) # only the project creator - - - # auth - - def test_auth_returns_authtuple(self): - assert_equal(auth(proj(PUBLIC))[1], 'password') - - def test_auth_creates_a_user(self): - auth(proj(PUBLIC)) - assert_equal(len(User.find()), 2) # project creator + 1 - - def test_auth_user_is_not_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(auth(proj(PUBLIC))) - assert_not_in(user_id, Node.find_one().permissions.keys()) - - - # read - - def test_read_returns_authtuple(self): - assert_equal(read(proj(PUBLIC))[1], 'password') - - def test_read_creates_a_user(self): - read(proj(PUBLIC)) - assert_equal(len(User.find()), 2) # project creator + 1 - - def test_read_user_is_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(read(proj(PUBLIC))) - assert_in(user_id, Node.find_one().permissions.keys()) - - -# varyfuncs - -def base(node): - type_ = 'project' if node.parent_node is None else 'component' - return 'flim', type_, 'title', 'Flim Flammity' - -def file_on(node): - node.get_addon('osfstorage').get_root().append_file('Blim Blammity') - return 'blim', 'file', 'name', 'Blim Blammity' - -def registration_of(node): - mock_archive(node, autocomplete=True, autoapprove=True).__enter__() # ?! - return 'flim', 'registration', 'title', 'Flim Flammity' - - -class TestVaryFuncs(DbIsolationMixin, OsfTestCase): - - # base - - def test_base_specifies_project_for_project(self): - assert_equal(base(proj())[1], 'project') - - def test_base_specifies_component_for_component(self): - assert_equal(base(comp())[1], 'component') - - - # fo - file_on - - def test_fo_makes_a_file_on_a_node(self): - file_on(factories.ProjectFactory()) - assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') - - - # ro - registration_of - - def test_ro_makes_a_registration_of_a_node(self): - registration_of(factories.ProjectFactory(title='Flim Flammity')) - assert_equal(Node.find_one(Q('is_registration', 'eq', True)).title, 'Flim Flammity') - - -# gettin' it together - -def namefunc(varyfunc, status, nodefunc, included, permfunc, **_): - return "{}{} {} {} {}".format( - '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', - 'private' if status is PRIVATE else 'public', - 'project' if nodefunc is proj else 'component', - 'shown to' if included else 'hidden from', - permfunc.__name__ - ) - -def generate_cases(): - for status in (PRIVATE, PUBLIC): - for nodefunc in (proj, comp): - for permfunc in (anon, auth, read): - included = permfunc is read if status is PRIVATE else True - for varyfunc in (base, file_on, registration_of): - if status is PRIVATE and varyfunc is registration_of: continue - yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, included - - -class TestGenerateCases(unittest.TestCase): - - # gc - generate_cases - - def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 30) - - def test_gc_doesnt_create_any_nodes(self): - list(generate_cases()) - assert_equal(len(Node.find()), 0) - - -class TestSearchSearchAPI(SearchTestCase): - """Exercises the website.search.views.search_search view. - """ - - def results(self, query, category, auth): - url = api_url_for('search_search') - data = {'q': 'category:{} AND {}'.format(category, query)} - return self.app.get(url, data, auth=auth).json['results'] - - @parameterized.expand(generate_cases) - def test(self, ignored, varyfunc, nodefunc, status, permfunc, included): - node = nodefunc(status) - auth = permfunc(node) - query, type_, key, expected_name = varyfunc(node) - expected = [(expected_name, type_)] if included else [] - results = self.results(query, type_, auth) - assert_equal([(x[key], x['category']) for x in results], expected) - -# -################################################################################################### - - class TestUserSearchAPI(SearchTestCase): def setUp(self): From 1067bf07f2dfc6fbef48a55d74f58d52d4a03c3d Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 3 Oct 2016 07:59:47 -0400 Subject: [PATCH 32/65] Teach parameterized tests about expected failures --- tests/test_search/test_permissions.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index ca78afc243a..300b621f7c2 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -1,7 +1,9 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals +import sys import unittest +import unittest.case from nose.tools import * # noqa PEP8 asserts @@ -200,6 +202,29 @@ def test_gc_doesnt_create_any_nodes(self): assert_equal(len(Node.find()), 0) +def possiblyExpectFailure(case): + + # This is a hack to conditionally wrap a failure expectation around *some* + # of the cases we're feeding to node-parameterized. TODO It can be removed + # when we write the code to unfail the tests. + + def test(*a, **kw): # name must start with test or it's ignored + _, _, _, _, status, permfunc, _ = a + if status is PRIVATE and permfunc is read: + + # This bit is copied from the unittest/case.py:expectedFailure + # decorator. + + try: + return case(*a, **kw) + except Exception: + raise unittest.case._ExpectedFailure(sys.exc_info()) + raise unittest.case._UnexpectedSuccess + else: + return case(*a, **kw) + return test + + class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ @@ -210,6 +235,7 @@ def results(self, query, category, auth): return self.app.get(url, data, auth=auth).json['results'] @parameterized.expand(generate_cases) + @possiblyExpectFailure def test(self, ignored, varyfunc, nodefunc, status, permfunc, included): node = nodefunc(status) auth = permfunc(node) From 53c0a825216204ae23f77803744204d3eefc0f0a Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 5 Oct 2016 16:27:07 -0400 Subject: [PATCH 33/65] Fix bug with unexpected successes --- tests/test_search/test_permissions.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 300b621f7c2..e0d6d739e9d 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -216,12 +216,12 @@ def test(*a, **kw): # name must start with test or it's ignored # decorator. try: - return case(*a, **kw) + case(*a, **kw) except Exception: raise unittest.case._ExpectedFailure(sys.exc_info()) raise unittest.case._UnexpectedSuccess else: - return case(*a, **kw) + case(*a, **kw) return test From 7856c5a876a92487a69f93d8a488e712487e7fe2 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 5 Oct 2016 18:03:20 -0400 Subject: [PATCH 34/65] Tweak some names Preps for mixing in other registration states. --- tests/test_search/test_permissions.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index e0d6d739e9d..b39582cfc67 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -139,7 +139,7 @@ def file_on(node): node.get_addon('osfstorage').get_root().append_file('Blim Blammity') return 'blim', 'file', 'name', 'Blim Blammity' -def registration_of(node): +def approved_registration_of(node): mock_archive(node, autocomplete=True, autoapprove=True).__enter__() # ?! return 'flim', 'registration', 'title', 'Flim Flammity' @@ -162,10 +162,10 @@ def test_fo_makes_a_file_on_a_node(self): assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') - # ro - registration_of + # aro - approved_registration_of - def test_ro_makes_a_registration_of_a_node(self): - registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test_aro_makes_a_registration_of_a_node(self): + approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) assert_equal(Node.find_one(Q('is_registration', 'eq', True)).title, 'Flim Flammity') @@ -185,8 +185,8 @@ def generate_cases(): for nodefunc in (proj, comp): for permfunc in (anon, auth, read): included = permfunc is read if status is PRIVATE else True - for varyfunc in (base, file_on, registration_of): - if status is PRIVATE and varyfunc is registration_of: continue + for varyfunc in (base, file_on, approved_registration_of): + if status is PRIVATE and varyfunc is approved_registration_of: continue yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, included @@ -229,7 +229,7 @@ class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ - def results(self, query, category, auth): + def search(self, query, category, auth): url = api_url_for('search_search') data = {'q': 'category:{} AND {}'.format(category, query)} return self.app.get(url, data, auth=auth).json['results'] @@ -241,5 +241,5 @@ def test(self, ignored, varyfunc, nodefunc, status, permfunc, included): auth = permfunc(node) query, type_, key, expected_name = varyfunc(node) expected = [(expected_name, type_)] if included else [] - results = self.results(query, type_, auth) + results = self.search(query, type_, auth) assert_equal([(x[key], x['category']) for x in results], expected) From b93af5ff1091a5262bf83c2440308d274db909cc Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Thu, 6 Oct 2016 15:48:40 -0400 Subject: [PATCH 35/65] Add in unapproved unembargoed registrations --- tests/test_search/test_permissions.py | 70 ++++++++++++++++++++------- 1 file changed, 53 insertions(+), 17 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index b39582cfc67..e45e8df04d3 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -139,10 +139,28 @@ def file_on(node): node.get_addon('osfstorage').get_root().append_file('Blim Blammity') return 'blim', 'file', 'name', 'Blim Blammity' -def approved_registration_of(node): +_reg = 'flim', 'registration', 'title', 'Flim Flammity' + +def approved_unembargoed_registration_of(node): mock_archive(node, autocomplete=True, autoapprove=True).__enter__() # ?! - return 'flim', 'registration', 'title', 'Flim Flammity' + return _reg + +def unapproved_unembargoed_registration_of(node): + mock_archive(node, autocomplete=True, autoapprove=False).__enter__() # ?! + return _reg + +REGFUNCS = ( + approved_unembargoed_registration_of, + unapproved_unembargoed_registration_of, +) +VARYFUNCS = ( + base, + file_on, +) + REGFUNCS +PRIVATE_REGISTRATIONS = ( + unapproved_unembargoed_registration_of, +) class TestVaryFuncs(DbIsolationMixin, OsfTestCase): @@ -162,32 +180,45 @@ def test_fo_makes_a_file_on_a_node(self): assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') - # aro - approved_registration_of + # ro - *_registration_of - def test_aro_makes_a_registration_of_a_node(self): - approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) - assert_equal(Node.find_one(Q('is_registration', 'eq', True)).title, 'Flim Flammity') + def test_ro_makes_an_approved_unembargoed_registration_of_a_node(self): + approved_unembargoed_registration_of(factories.ProjectFactory(title='Flim Flammity')) + reg = Node.find_one(Q('is_registration', 'eq', True)) + assert_equal(reg.title, 'Flim Flammity') + ok_(reg.is_public) + + def test_ro_makes_an_unapproved_unembargoed_registration_of_a_node(self): + unapproved_unembargoed_registration_of(factories.ProjectFactory(title='Flim Flammity')) + reg = Node.find_one(Q('is_registration', 'eq', True)) + assert_equal(reg.title, 'Flim Flammity') + ok_(not reg.is_public) # gettin' it together -def namefunc(varyfunc, status, nodefunc, included, permfunc, **_): +def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): return "{}{} {} {} {}".format( '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', 'private' if status is PRIVATE else 'public', 'project' if nodefunc is proj else 'component', - 'shown to' if included else 'hidden from', + 'shown to' if should_see else 'hidden from', permfunc.__name__ ) +def seefunc(status, varyfunc, permfunc): + if status is PRIVATE or varyfunc in PRIVATE_REGISTRATIONS: + return permfunc is read + return True + def generate_cases(): for status in (PRIVATE, PUBLIC): for nodefunc in (proj, comp): for permfunc in (anon, auth, read): - included = permfunc is read if status is PRIVATE else True - for varyfunc in (base, file_on, approved_registration_of): - if status is PRIVATE and varyfunc is approved_registration_of: continue - yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, included + for varyfunc in VARYFUNCS: + if status is PRIVATE and varyfunc in REGFUNCS: continue + should_see = seefunc(status, varyfunc, permfunc) + yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, should_see class TestGenerateCases(unittest.TestCase): @@ -195,7 +226,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 30) + assert_equal(len(list(generate_cases())), 36) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) @@ -208,9 +239,14 @@ def possiblyExpectFailure(case): # of the cases we're feeding to node-parameterized. TODO It can be removed # when we write the code to unfail the tests. + def should_fail(status, varyfunc, permfunc): + if status is PRIVATE or varyfunc in PRIVATE_REGISTRATIONS: + return permfunc is read + return False + def test(*a, **kw): # name must start with test or it's ignored - _, _, _, _, status, permfunc, _ = a - if status is PRIVATE and permfunc is read: + _, _, varyfunc, _, status, permfunc, _ = a + if should_fail(status, varyfunc, permfunc): # This bit is copied from the unittest/case.py:expectedFailure # decorator. @@ -236,10 +272,10 @@ def search(self, query, category, auth): @parameterized.expand(generate_cases) @possiblyExpectFailure - def test(self, ignored, varyfunc, nodefunc, status, permfunc, included): + def test(self, ignored, varyfunc, nodefunc, status, permfunc, should_see): node = nodefunc(status) auth = permfunc(node) query, type_, key, expected_name = varyfunc(node) - expected = [(expected_name, type_)] if included else [] + expected = [(expected_name, type_)] if should_see else [] results = self.search(query, type_, auth) assert_equal([(x[key], x['category']) for x in results], expected) From c697edca9f2e3e276f3e36c4213069f09056f31e Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 7 Oct 2016 07:10:26 -0400 Subject: [PATCH 36/65] Deduplicate a couple things - Reuse the seefunc condition in should_fail. - Fold PRIVATE_REGISTRATIONS under VARYFUNCS. --- tests/test_search/test_permissions.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index e45e8df04d3..aa641030207 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -149,19 +149,17 @@ def unapproved_unembargoed_registration_of(node): mock_archive(node, autocomplete=True, autoapprove=False).__enter__() # ?! return _reg -REGFUNCS = ( - approved_unembargoed_registration_of, +REGFUNCS_PRIVATE = ( unapproved_unembargoed_registration_of, ) +REGFUNCS = ( + approved_unembargoed_registration_of, +) + REGFUNCS_PRIVATE VARYFUNCS = ( base, file_on, ) + REGFUNCS -PRIVATE_REGISTRATIONS = ( - unapproved_unembargoed_registration_of, -) - class TestVaryFuncs(DbIsolationMixin, OsfTestCase): # base @@ -206,10 +204,10 @@ def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): permfunc.__name__ ) -def seefunc(status, varyfunc, permfunc): - if status is PRIVATE or varyfunc in PRIVATE_REGISTRATIONS: +def seefunc(status, varyfunc, permfunc, default__TODO_remove_this_argument=True): + if status is PRIVATE or varyfunc in REGFUNCS_PRIVATE: return permfunc is read - return True + return default__TODO_remove_this_argument def generate_cases(): for status in (PRIVATE, PUBLIC): @@ -217,7 +215,7 @@ def generate_cases(): for permfunc in (anon, auth, read): for varyfunc in VARYFUNCS: if status is PRIVATE and varyfunc in REGFUNCS: continue - should_see = seefunc(status, varyfunc, permfunc) + should_see = seefunc(status, varyfunc, permfunc) # namefunc wants this yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, should_see @@ -239,14 +237,9 @@ def possiblyExpectFailure(case): # of the cases we're feeding to node-parameterized. TODO It can be removed # when we write the code to unfail the tests. - def should_fail(status, varyfunc, permfunc): - if status is PRIVATE or varyfunc in PRIVATE_REGISTRATIONS: - return permfunc is read - return False - def test(*a, **kw): # name must start with test or it's ignored _, _, varyfunc, _, status, permfunc, _ = a - if should_fail(status, varyfunc, permfunc): + if seefunc(status, varyfunc, permfunc, False): # This bit is copied from the unittest/case.py:expectedFailure # decorator. From 41435f4e10199c08094c499dc99712675196c378 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 7 Oct 2016 17:13:21 -0400 Subject: [PATCH 37/65] Neaten up varyfuncs --- tests/test_search/test_permissions.py | 36 +++++++++++++-------------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index aa641030207..17183aa8b3b 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -139,21 +139,21 @@ def file_on(node): node.get_addon('osfstorage').get_root().append_file('Blim Blammity') return 'blim', 'file', 'name', 'Blim Blammity' -_reg = 'flim', 'registration', 'title', 'Flim Flammity' +def _register(*a, **kw): + mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy + return 'flim', 'registration', 'title', 'Flim Flammity' -def approved_unembargoed_registration_of(node): - mock_archive(node, autocomplete=True, autoapprove=True).__enter__() # ?! - return _reg +def unembargoed_unapproved_registration_of(node): # ?! + return _register(node) -def unapproved_unembargoed_registration_of(node): - mock_archive(node, autocomplete=True, autoapprove=False).__enter__() # ?! - return _reg +def unembargoed_approved_registration_of(node): + return _register(node, autoapprove=True) REGFUNCS_PRIVATE = ( - unapproved_unembargoed_registration_of, + unembargoed_unapproved_registration_of, ) REGFUNCS = ( - approved_unembargoed_registration_of, + unembargoed_approved_registration_of, ) + REGFUNCS_PRIVATE VARYFUNCS = ( base, @@ -178,19 +178,19 @@ def test_fo_makes_a_file_on_a_node(self): assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') - # ro - *_registration_of + # _ro - *_registration_of - def test_ro_makes_an_approved_unembargoed_registration_of_a_node(self): - approved_unembargoed_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test__ro_makes_an_unembargoed_approved_registration_of_a_node(self): + unembargoed_approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) - assert_equal(reg.title, 'Flim Flammity') - ok_(reg.is_public) + assert_equal(reg.registration_approval.state, 'approved') + ok_(not reg.embargo) - def test_ro_makes_an_unapproved_unembargoed_registration_of_a_node(self): - unapproved_unembargoed_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test__ro_makes_an_unembargoed_unapproved_registration_of_a_node(self): + unembargoed_unapproved_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) - assert_equal(reg.title, 'Flim Flammity') - ok_(not reg.is_public) + assert_equal(reg.registration_approval.state, 'unapproved') + ok_(not reg.embargo) # gettin' it together From b71cb55349e579e6a4a1cf1a0c632d496e171fb0 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 10 Oct 2016 12:03:21 -0400 Subject: [PATCH 38/65] Embargoed, unapproved registration It's not really *un*approved so much as *a*approved. --- tests/test_search/test_permissions.py | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 17183aa8b3b..457062d503b 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -149,8 +149,12 @@ def unembargoed_unapproved_registration_of(node): # ?! def unembargoed_approved_registration_of(node): return _register(node, autoapprove=True) +def embargoed_unapproved_registration_of(node): + return _register(node, embargo=True) + REGFUNCS_PRIVATE = ( unembargoed_unapproved_registration_of, + embargoed_unapproved_registration_of, ) REGFUNCS = ( unembargoed_approved_registration_of, @@ -178,19 +182,25 @@ def test_fo_makes_a_file_on_a_node(self): assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') - # _ro - *_registration_of + # *ro - *_registration_of - def test__ro_makes_an_unembargoed_approved_registration_of_a_node(self): + def test_uaro_makes_an_unembargoed_approved_registration_of_a_node(self): unembargoed_approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) - assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'approved') - def test__ro_makes_an_unembargoed_unapproved_registration_of_a_node(self): + def test_uuro_makes_an_unembargoed_unapproved_registration_of_a_node(self): unembargoed_unapproved_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) - assert_equal(reg.registration_approval.state, 'unapproved') ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'unapproved') + + def test_euro_makes_an_embargoed_aapproved_registration_of_a_node(self): + embargoed_unapproved_registration_of(factories.ProjectFactory(title='Flim Flammity')) + reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.embargo) + ok_(not reg.registration_approval) # gettin' it together @@ -224,7 +234,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 36) + assert_equal(len(list(generate_cases())), 42) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) From 3b75f2686a9ffa0d1fb987c6c16a0f5bcaf14d2e Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sat, 15 Oct 2016 07:06:17 -0400 Subject: [PATCH 39/65] Start generating reg. variants programmatically This commit only replaces the three *_registration_of functions we had previously. The next step is to open up the other possible combos. --- tests/test_search/test_permissions.py | 59 +++++++++++++++++++-------- 1 file changed, 41 insertions(+), 18 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 457062d503b..86f7eba176f 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -143,26 +143,49 @@ def _register(*a, **kw): mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy return 'flim', 'registration', 'title', 'Flim Flammity' -def unembargoed_unapproved_registration_of(node): # ?! - return _register(node) - -def unembargoed_approved_registration_of(node): - return _register(node, autoapprove=True) - -def embargoed_unapproved_registration_of(node): - return _register(node, embargo=True) - -REGFUNCS_PRIVATE = ( - unembargoed_unapproved_registration_of, - embargoed_unapproved_registration_of, -) -REGFUNCS = ( - unembargoed_approved_registration_of, -) + REGFUNCS_PRIVATE +def name_regfunc(embargo, autoapprove, **_): + return '{}_{}_registration_of'.format( + 'embargoed' if embargo else 'unembargoed', + 'approved' if autoapprove else 'unapproved', + ).encode('ascii') + +def create_regfunc(**kw): + def regfunc(node): + return _register(node, **kw) + regfunc.__name__ = name_regfunc(**kw) + return regfunc + +def create_regfuncs(): + public = set() + private = set() + for embargo in (False, True): + for autoapprove in (False, True): + if embargo and autoapprove: continue # TODO + for autocomplete in (True,): # TODO + for autoapprove_retraction in (None,): # TODO + retraction = autoapprove_retraction is not None + regfunc = create_regfunc( + embargo=embargo, + retraction=retraction, + autoapprove_retraction=autoapprove_retraction, + autocomplete=autocomplete, + autoapprove=autoapprove, + ) + should_be_public = (not embargo) and autoapprove and autocomplete + (public if should_be_public else private).add(regfunc) + return public, private + +REGFUNCS_PUBLIC, REGFUNCS_PRIVATE = create_regfuncs() +REGFUNCS = REGFUNCS_PUBLIC | REGFUNCS_PRIVATE + +locals_dict = locals() +for regfunc in REGFUNCS: + locals_dict[regfunc.__name__] = regfunc + VARYFUNCS = ( base, file_on, -) + REGFUNCS +) + tuple(REGFUNCS) class TestVaryFuncs(DbIsolationMixin, OsfTestCase): @@ -182,7 +205,7 @@ def test_fo_makes_a_file_on_a_node(self): assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') - # *ro - *_registration_of + # regfuncs def test_uaro_makes_an_unembargoed_approved_registration_of_a_node(self): unembargoed_approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) From 2b64ea4ff87b53cec5f57fe9cc64e2dc4ba1c5d2 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sat, 15 Oct 2016 07:30:47 -0400 Subject: [PATCH 40/65] Bring back approved embargo Now that I understand what's going on. --- tests/test_search/test_permissions.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 86f7eba176f..ee01fef77fc 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -160,7 +160,6 @@ def create_regfuncs(): private = set() for embargo in (False, True): for autoapprove in (False, True): - if embargo and autoapprove: continue # TODO for autocomplete in (True,): # TODO for autoapprove_retraction in (None,): # TODO retraction = autoapprove_retraction is not None @@ -219,11 +218,17 @@ def test_uuro_makes_an_unembargoed_unapproved_registration_of_a_node(self): ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') - def test_euro_makes_an_embargoed_aapproved_registration_of_a_node(self): + def test_earo_makes_an_embargoed_approved_registration_of_a_node(self): + embargoed_approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) + reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'approved') + + def test_euro_makes_an_embargoed_unapproved_registration_of_a_node(self): embargoed_unapproved_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) ok_(reg.embargo) - ok_(not reg.registration_approval) + assert_equal(reg.embargo.state, 'unapproved') # gettin' it together @@ -257,7 +262,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 42) + assert_equal(len(list(generate_cases())), 48) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) From 5ec0c2d1890d21f2ad06d3cf7c5c6b570c805d5a Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sun, 30 Oct 2016 20:35:21 -0400 Subject: [PATCH 41/65] Mix completeness into the regfunc generator --- tests/test_search/test_permissions.py | 42 +++++++++++++++++++-------- 1 file changed, 30 insertions(+), 12 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index ee01fef77fc..2fbec31b298 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -143,10 +143,11 @@ def _register(*a, **kw): mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy return 'flim', 'registration', 'title', 'Flim Flammity' -def name_regfunc(embargo, autoapprove, **_): - return '{}_{}_registration_of'.format( +def name_regfunc(embargo, autoapprove, autocomplete, **_): + return '{}_{}_{}_registration_of'.format( 'embargoed' if embargo else 'unembargoed', 'approved' if autoapprove else 'unapproved', + 'complete' if autocomplete else 'incomplete', ).encode('ascii') def create_regfunc(**kw): @@ -160,7 +161,7 @@ def create_regfuncs(): private = set() for embargo in (False, True): for autoapprove in (False, True): - for autocomplete in (True,): # TODO + for autocomplete in (True, False): for autoapprove_retraction in (None,): # TODO retraction = autoapprove_retraction is not None regfunc = create_regfunc( @@ -206,26 +207,43 @@ def test_fo_makes_a_file_on_a_node(self): # regfuncs - def test_uaro_makes_an_unembargoed_approved_registration_of_a_node(self): - unembargoed_approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def F(self): + return factories.ProjectFactory(title='Flim Flammity') + + def test_number_of_regfuncs(self): + assert_equal(len(REGFUNCS), 8) + + def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): + unembargoed_approved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') + ok_(reg.archive_job.done) - def test_uuro_makes_an_unembargoed_unapproved_registration_of_a_node(self): - unembargoed_unapproved_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(self): + unembargoed_approved_incomplete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + + ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'approved') + ok_(not reg.archive_job.done) + + def test_uuro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): + unembargoed_unapproved_complete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') - def test_earo_makes_an_embargoed_approved_registration_of_a_node(self): - embargoed_approved_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test_earo_makes_an_embargoed_approved_complete_registration_of_a_node(self): + embargoed_approved_complete_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') - def test_euro_makes_an_embargoed_unapproved_registration_of_a_node(self): - embargoed_unapproved_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test_euro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): + embargoed_unapproved_complete_registration_of(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') @@ -262,7 +280,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 48) + assert_equal(len(list(generate_cases())), 72) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) From 8691b0a57a90360d926251caf0c47400e02977d6 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sun, 30 Oct 2016 21:55:10 -0400 Subject: [PATCH 42/65] Fill out the rest of the new regfunc tests --- tests/test_search/test_permissions.py | 40 +++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 2fbec31b298..7adb63358a2 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -159,6 +159,7 @@ def regfunc(node): def create_regfuncs(): public = set() private = set() + # Default values are listed first for all of these ... for embargo in (False, True): for autoapprove in (False, True): for autocomplete in (True, False): @@ -229,24 +230,53 @@ def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(s assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) - def test_uuro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): + def test_uucro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): unembargoed_unapproved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') + ok_(reg.archive_job.done) + + def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node(self): + unembargoed_unapproved_incomplete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'unapproved') + ok_(not reg.archive_job.done) - def test_earo_makes_an_embargoed_approved_complete_registration_of_a_node(self): - embargoed_approved_complete_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self): + embargoed_approved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') + ok_(reg.archive_job.done) - def test_euro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): - embargoed_unapproved_complete_registration_of(factories.ProjectFactory(title='Flim Flammity')) + def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(self): + embargoed_approved_incomplete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'approved') + ok_(not reg.archive_job.done) + + def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): + embargoed_unapproved_complete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') + ok_(reg.archive_job.done) + + def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(self): + embargoed_unapproved_incomplete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'unapproved') + ok_(not reg.archive_job.done) # gettin' it together From 6fca0798bdada580d83e84d8c22b460ef8717815 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 8 Nov 2016 05:42:02 -0800 Subject: [PATCH 43/65] Add a test for the number of tests --- tests/test_search/test_permissions.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 7adb63358a2..3a53fe8b820 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals +import re import sys import unittest import unittest.case @@ -214,6 +215,11 @@ def F(self): def test_number_of_regfuncs(self): assert_equal(len(REGFUNCS), 8) + def test_number_of_regfunc_tests(self): + is_regfunc_test = lambda n: re.match('test_.*makes_an_.*_registration_of_a_node', n) + regfunc_tests = filter(is_regfunc_test, self.__class__.__dict__.keys()) + assert_equal(len(regfunc_tests), len(REGFUNCS)) + def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): unembargoed_approved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) From 64d0eb087dcfc4deccb12e638b70a48bf7998c85 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 8 Nov 2016 06:35:42 -0800 Subject: [PATCH 44/65] Include retraction info in regfunc name --- tests/test_search/test_permissions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 3a53fe8b820..2e141a7d074 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -144,8 +144,12 @@ def _register(*a, **kw): mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy return 'flim', 'registration', 'title', 'Flim Flammity' -def name_regfunc(embargo, autoapprove, autocomplete, **_): - return '{}_{}_{}_registration_of'.format( +def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_retraction, **_): + retraction_part = '' if not retraction else \ + '{}_retraction_of_an_'.format('approved' if autoapprove_retraction else + 'unapproved') + return '{}{}_{}_{}_registration_of'.format( + retraction_part, 'embargoed' if embargo else 'unembargoed', 'approved' if autoapprove else 'unapproved', 'complete' if autocomplete else 'incomplete', From 1388a39cbfa28addc0ddd8cfcfefc97892b332c4 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 8 Nov 2016 07:15:35 -0800 Subject: [PATCH 45/65] Mix in unapproved retractions --- tests/test_search/test_permissions.py | 74 +++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 3 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 2e141a7d074..119da05f687 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -168,8 +168,12 @@ def create_regfuncs(): for embargo in (False, True): for autoapprove in (False, True): for autocomplete in (True, False): - for autoapprove_retraction in (None,): # TODO + for autoapprove_retraction in (None, False): # TODO retraction = autoapprove_retraction is not None + + if retraction and not (autoapprove or embargo): + continue # 'Only public or embargoed registrations may be withdrawn.' + regfunc = create_regfunc( embargo=embargo, retraction=retraction, @@ -217,17 +221,19 @@ def F(self): return factories.ProjectFactory(title='Flim Flammity') def test_number_of_regfuncs(self): - assert_equal(len(REGFUNCS), 8) + assert_equal(len(REGFUNCS), 14) def test_number_of_regfunc_tests(self): is_regfunc_test = lambda n: re.match('test_.*makes_an_.*_registration_of_a_node', n) regfunc_tests = filter(is_regfunc_test, self.__class__.__dict__.keys()) assert_equal(len(regfunc_tests), len(REGFUNCS)) + # no retraction def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): unembargoed_approved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(reg.archive_job.done) @@ -236,6 +242,7 @@ def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(s unembargoed_approved_incomplete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) @@ -244,6 +251,7 @@ def test_uucro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(s unembargoed_unapproved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') ok_(reg.archive_job.done) @@ -252,6 +260,7 @@ def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node unembargoed_unapproved_incomplete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') ok_(not reg.archive_job.done) @@ -260,6 +269,7 @@ def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self) embargoed_approved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) @@ -268,6 +278,7 @@ def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(sel embargoed_approved_incomplete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) @@ -276,6 +287,7 @@ def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(sel embargoed_unapproved_complete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) @@ -284,6 +296,62 @@ def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(s embargoed_unapproved_incomplete_registration_of(self.F()) reg = Node.find_one(Q('is_registration', 'eq', True)) + ok_(reg.retraction is None) + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'unapproved') + ok_(not reg.archive_job.done) + + # unapproved retraction + def test_urouacro_makes_an_unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): + unapproved_retraction_of_an_unembargoed_approved_complete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + assert_equal(reg.retraction.state, 'unapproved') + ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'approved') + ok_(reg.archive_job.done) + + def test_urouairo_makes_an_unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): + unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + assert_equal(reg.retraction.state, 'unapproved') + ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'approved') + ok_(not reg.archive_job.done) + + def test_uroeacro_makes_an_unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): + unapproved_retraction_of_an_embargoed_approved_complete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + assert_equal(reg.retraction.state, 'unapproved') + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'approved') + ok_(reg.archive_job.done) + + def test_uroeairo_makes_an_unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): + unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + assert_equal(reg.retraction.state, 'unapproved') + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'approved') + ok_(not reg.archive_job.done) + + def test_uroeucro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): + unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + assert_equal(reg.retraction.state, 'unapproved') + ok_(reg.embargo) + assert_equal(reg.embargo.state, 'unapproved') + ok_(reg.archive_job.done) + + def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): + unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of(self.F()) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + assert_equal(reg.retraction.state, 'unapproved') ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(not reg.archive_job.done) @@ -320,7 +388,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 72) + assert_equal(len(list(generate_cases())), 108) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) From dff447af620fec9385fef95732930e70a076263b Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 8 Nov 2016 07:20:47 -0800 Subject: [PATCH 46/65] DRY up the regfunc tests --- tests/test_search/test_permissions.py | 61 ++++++++------------------- 1 file changed, 17 insertions(+), 44 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 119da05f687..85398c985e5 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -217,8 +217,9 @@ def test_fo_makes_a_file_on_a_node(self): # regfuncs - def F(self): - return factories.ProjectFactory(title='Flim Flammity') + def Reg(self, func): + func(factories.ProjectFactory(title='Flim Flammity')) + return Node.find_one(Q('is_registration', 'eq', True)) def test_number_of_regfuncs(self): assert_equal(len(REGFUNCS), 14) @@ -230,72 +231,56 @@ def test_number_of_regfunc_tests(self): # no retraction def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): - unembargoed_approved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unembargoed_approved_complete_registration_of) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(reg.archive_job.done) def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(self): - unembargoed_approved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unembargoed_approved_incomplete_registration_of) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) def test_uucro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): - unembargoed_unapproved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unembargoed_unapproved_complete_registration_of) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') ok_(reg.archive_job.done) def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node(self): - unembargoed_unapproved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unembargoed_unapproved_incomplete_registration_of) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') ok_(not reg.archive_job.done) def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self): - embargoed_approved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(embargoed_approved_complete_registration_of) ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(self): - embargoed_approved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(embargoed_approved_incomplete_registration_of) ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): - embargoed_unapproved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(embargoed_unapproved_complete_registration_of) ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - embargoed_unapproved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(embargoed_unapproved_incomplete_registration_of) ok_(reg.retraction is None) ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') @@ -303,54 +288,42 @@ def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(s # unapproved retraction def test_urouacro_makes_an_unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - unapproved_retraction_of_an_unembargoed_approved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_complete_registration_of) assert_equal(reg.retraction.state, 'unapproved') ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(reg.archive_job.done) def test_urouairo_makes_an_unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of) assert_equal(reg.retraction.state, 'unapproved') ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) def test_uroeacro_makes_an_unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - unapproved_retraction_of_an_embargoed_approved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_complete_registration_of) assert_equal(reg.retraction.state, 'unapproved') ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) def test_uroeairo_makes_an_unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of) assert_equal(reg.retraction.state, 'unapproved') ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) def test_uroeucro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of) assert_equal(reg.retraction.state, 'unapproved') ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of(self.F()) - reg = Node.find_one(Q('is_registration', 'eq', True)) - + reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of) assert_equal(reg.retraction.state, 'unapproved') ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') From dcc5afcde759401416700297c07ebe7a36024714 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Tue, 8 Nov 2016 07:24:08 -0800 Subject: [PATCH 47/65] Remove redundant check from some tests This is adequately covered by the subsequent check. --- tests/test_search/test_permissions.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 85398c985e5..25c2bad5020 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -261,28 +261,24 @@ def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self): reg = self.Reg(embargoed_approved_complete_registration_of) ok_(reg.retraction is None) - ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(self): reg = self.Reg(embargoed_approved_incomplete_registration_of) ok_(reg.retraction is None) - ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): reg = self.Reg(embargoed_unapproved_complete_registration_of) ok_(reg.retraction is None) - ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(self): reg = self.Reg(embargoed_unapproved_incomplete_registration_of) ok_(reg.retraction is None) - ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(not reg.archive_job.done) @@ -304,28 +300,24 @@ def test_urouairo_makes_an_unapproved_retraction_of_an_unembargoed_approved_inco def test_uroeacro_makes_an_unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_complete_registration_of) assert_equal(reg.retraction.state, 'unapproved') - ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) def test_uroeairo_makes_an_unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of) assert_equal(reg.retraction.state, 'unapproved') - ok_(reg.embargo) assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) def test_uroeucro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of) assert_equal(reg.retraction.state, 'unapproved') - ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of) assert_equal(reg.retraction.state, 'unapproved') - ok_(reg.embargo) assert_equal(reg.embargo.state, 'unapproved') ok_(not reg.archive_job.done) From a00d84664416a736bddf6b97977f3eea499b5316 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 9 Nov 2016 06:30:57 -0800 Subject: [PATCH 48/65] Round out regfuncs with approved retractions --- tests/test_search/test_permissions.py | 42 +++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 25c2bad5020..af1dc2b795d 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -168,7 +168,7 @@ def create_regfuncs(): for embargo in (False, True): for autoapprove in (False, True): for autocomplete in (True, False): - for autoapprove_retraction in (None, False): # TODO + for autoapprove_retraction in (None, False, True): retraction = autoapprove_retraction is not None if retraction and not (autoapprove or embargo): @@ -222,7 +222,7 @@ def Reg(self, func): return Node.find_one(Q('is_registration', 'eq', True)) def test_number_of_regfuncs(self): - assert_equal(len(REGFUNCS), 14) + assert_equal(len(REGFUNCS), 20) def test_number_of_regfunc_tests(self): is_regfunc_test = lambda n: re.match('test_.*makes_an_.*_registration_of_a_node', n) @@ -321,6 +321,44 @@ def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_inco assert_equal(reg.embargo.state, 'unapproved') ok_(not reg.archive_job.done) + # approved retraction + def test_arouacro_makes_an_approved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_an_unembargoed_approved_complete_registration_of) + assert_equal(reg.retraction.state, 'approved') + ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'approved') + ok_(reg.archive_job.done) + + def test_arouairo_makes_an_approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_an_unembargoed_approved_incomplete_registration_of) + assert_equal(reg.retraction.state, 'approved') + ok_(not reg.embargo) + assert_equal(reg.registration_approval.state, 'approved') + ok_(not reg.archive_job.done) + + def test_aroeacro_makes_an_approved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_an_embargoed_approved_complete_registration_of) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(reg.archive_job.done) + + def test_aroeairo_makes_an_approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_an_embargoed_approved_incomplete_registration_of) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(not reg.archive_job.done) + + def test_aroeucro_makes_an_approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_complete_registration_of) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(reg.archive_job.done) + + def test_aroeuiro_makes_an_approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(not reg.archive_job.done) # gettin' it together From 415cf420cb6a2ec530c928b06efdc58204db3770 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 18 Nov 2016 21:00:58 -0800 Subject: [PATCH 49/65] Update expectations regarding retractions --- tests/test_search/test_permissions.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index af1dc2b795d..f978bc575d9 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -181,7 +181,16 @@ def create_regfuncs(): autocomplete=autocomplete, autoapprove=autoapprove, ) - should_be_public = (not embargo) and autoapprove and autocomplete + + if retraction and embargo: + # Approving a retraction removes embargoes and makes the reg public, + # but only for *completed* registrations. + should_be_public = autoapprove_retraction and autocomplete + elif embargo: + should_be_public = False + else: + should_be_public = autoapprove and autocomplete + (public if should_be_public else private).add(regfunc) return public, private @@ -383,7 +392,9 @@ def generate_cases(): for varyfunc in VARYFUNCS: if status is PRIVATE and varyfunc in REGFUNCS: continue should_see = seefunc(status, varyfunc, permfunc) # namefunc wants this - yield namefunc(**locals()), varyfunc, nodefunc, status, permfunc, should_see + name = namefunc(**locals()) + if want(name): + yield name, varyfunc, nodefunc, status, permfunc, should_see class TestGenerateCases(unittest.TestCase): @@ -420,6 +431,12 @@ def test(*a, **kw): # name must start with test or it's ignored case(*a, **kw) return test +def want(name): # This is a helper to filter down to one of the generated tests + return True + n = ( 'embargoed unapproved complete registration of public component hidden from anon' + , 'approved retraction of an embargoed unapproved complete registration of public component hidden from anon' + ) + return name == n[1] class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. From 8bca5a998f7ebda633014f6e80c9d5456420374d Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 21 Nov 2016 07:16:55 -0500 Subject: [PATCH 50/65] Update number of tests --- tests/test_search/test_permissions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index f978bc575d9..5cc66763bac 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -402,7 +402,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 108) + assert_equal(len(list(generate_cases())), 144) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) From 6ff365859bc281bc7f7cd8b2aaa75fa358aec1a3 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 21 Nov 2016 07:22:55 -0500 Subject: [PATCH 51/65] Remove unused constants --- tests/test_search/test_permissions.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 5cc66763bac..39e2e24a2fd 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -21,7 +21,6 @@ PRIVATE, PUBLIC = range(2) -PROJECT, COMPONENT = 'project component'.split() # nodefuncs From 5b1efc35d33525a61e0f4e563940788ac162c238 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 21 Nov 2016 07:36:06 -0500 Subject: [PATCH 52/65] Remove a vestigial helper --- tests/test_search/test_permissions.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions.py index 39e2e24a2fd..a7aa2b5b90f 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions.py @@ -368,6 +368,7 @@ def test_aroeuiro_makes_an_approved_retraction_of_an_embargoed_unapproved_incomp assert_equal(reg.embargo.state, 'rejected') ok_(not reg.archive_job.done) + # gettin' it together def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): @@ -392,8 +393,7 @@ def generate_cases(): if status is PRIVATE and varyfunc in REGFUNCS: continue should_see = seefunc(status, varyfunc, permfunc) # namefunc wants this name = namefunc(**locals()) - if want(name): - yield name, varyfunc, nodefunc, status, permfunc, should_see + yield name, varyfunc, nodefunc, status, permfunc, should_see class TestGenerateCases(unittest.TestCase): @@ -430,13 +430,6 @@ def test(*a, **kw): # name must start with test or it's ignored case(*a, **kw) return test -def want(name): # This is a helper to filter down to one of the generated tests - return True - n = ( 'embargoed unapproved complete registration of public component hidden from anon' - , 'approved retraction of an embargoed unapproved complete registration of public component hidden from anon' - ) - return name == n[1] - class TestSearchSearchAPI(SearchTestCase): """Exercises the website.search.views.search_search view. """ From 96a1a46354b039f22aec0561fc145dbb787ff662 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Mon, 21 Nov 2016 08:39:28 -0500 Subject: [PATCH 53/65] Refactor into multiple files --- .../test_search/test_permissions/__init__.py | 108 +++++++++ .../test_permissions/test_nodefuncs.py | 60 +++++ .../test_permissions/test_permfuncs.py | 73 ++++++ .../test_varyfuncs.py} | 209 +----------------- 4 files changed, 250 insertions(+), 200 deletions(-) create mode 100644 tests/test_search/test_permissions/__init__.py create mode 100644 tests/test_search/test_permissions/test_nodefuncs.py create mode 100644 tests/test_search/test_permissions/test_permfuncs.py rename tests/test_search/{test_permissions.py => test_permissions/test_varyfuncs.py} (64%) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py new file mode 100644 index 00000000000..a661e8bbf70 --- /dev/null +++ b/tests/test_search/test_permissions/__init__.py @@ -0,0 +1,108 @@ +# -*- coding: utf-8 -*- +"""This is a test suite for permissions on the search_search endpoint. It has four parts: + + - nodefuncs - functions for different Node types + - permfuncs - functions for different permissions + - varyfuncs - functions for different Node state variants + - TestSearchSearchAPI - the actual tests against the search_search API, + which are generated from a combination of the above three function types + +""" +from __future__ import absolute_import, division, print_function, unicode_literals + +import sys +import unittest +import unittest.case + +from nose.tools import assert_equal + +from nose_parameterized import parameterized +from tests.test_search import SearchTestCase +from tests.test_search.test_permissions.test_varyfuncs import VARYFUNCS, REGFUNCS, REGFUNCS_PRIVATE +from tests.test_search.test_permissions.test_varyfuncs import base +from tests.test_search.test_permissions.test_permfuncs import anon, auth, read +from tests.test_search.test_permissions.test_nodefuncs import proj, comp, PUBLIC, PRIVATE +from website.project.model import Node +from website.util import api_url_for + + +def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): + return "{}{} {} {} {}".format( + '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', + 'private' if status is PRIVATE else 'public', + 'project' if nodefunc is proj else 'component', + 'shown to' if should_see else 'hidden from', + permfunc.__name__ + ) + + +def seefunc(status, varyfunc, permfunc, default__TODO_remove_this_argument=True): + if status is PRIVATE or varyfunc in REGFUNCS_PRIVATE: + return permfunc is read + return default__TODO_remove_this_argument + + +def generate_cases(): + for status in (PRIVATE, PUBLIC): + for nodefunc in (proj, comp): + for permfunc in (anon, auth, read): + for varyfunc in VARYFUNCS: + if status is PRIVATE and varyfunc in REGFUNCS: continue + should_see = seefunc(status, varyfunc, permfunc) # namefunc wants this + name = namefunc(**locals()) + yield name, varyfunc, nodefunc, status, permfunc, should_see + + +class TestGenerateCases(unittest.TestCase): + + # gc - generate_cases + + def test_gc_generates_cases(self): + assert_equal(len(list(generate_cases())), 144) + + def test_gc_doesnt_create_any_nodes(self): + list(generate_cases()) + assert_equal(len(Node.find()), 0) + + +def possiblyExpectFailure(case): + + # This is a hack to conditionally wrap a failure expectation around *some* + # of the cases we're feeding to node-parameterized. TODO It can be removed + # when we write the code to unfail the tests. + + def test(*a, **kw): # name must start with test or it's ignored + _, _, varyfunc, _, status, permfunc, _ = a + if seefunc(status, varyfunc, permfunc, False): + + # This bit is copied from the unittest/case.py:expectedFailure + # decorator. + + try: + case(*a, **kw) + except Exception: + raise unittest.case._ExpectedFailure(sys.exc_info()) + raise unittest.case._UnexpectedSuccess + else: + case(*a, **kw) + return test + + +class TestSearchSearchAPI(SearchTestCase): + """Exercises the website.search.views.search_search view. + """ + + def search(self, query, category, auth): + url = api_url_for('search_search') + data = {'q': 'category:{} AND {}'.format(category, query)} + return self.app.get(url, data, auth=auth).json['results'] + + @parameterized.expand(generate_cases) + @possiblyExpectFailure + def test(self, ignored, varyfunc, nodefunc, status, permfunc, should_see): + node = nodefunc(status) + auth = permfunc(node) + query, type_, key, expected_name = varyfunc(node) + expected = [(expected_name, type_)] if should_see else [] + results = self.search(query, type_, auth) + assert_equal([(x[key], x['category']) for x in results], expected) diff --git a/tests/test_search/test_permissions/test_nodefuncs.py b/tests/test_search/test_permissions/test_nodefuncs.py new file mode 100644 index 00000000000..7e42825cfeb --- /dev/null +++ b/tests/test_search/test_permissions/test_nodefuncs.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function, unicode_literals + +from nose.tools import assert_equal, ok_ + +from modularodm import Q + +from tests import factories +from tests.base import DbIsolationMixin +from tests.test_search import OsfTestCase +from website.project.model import Node + + +PRIVATE, PUBLIC = range(2) + + +def proj(status=PUBLIC): + project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) + project.update_search() + return project + + +def comp(status=PUBLIC): + project = factories.ProjectFactory(title='Slim Slammity', is_public=status is PUBLIC) + project.update_search() + component = factories.NodeFactory( + title='Flim Flammity', + parent=project, + is_public=status is PUBLIC, + ) + component.update_search() + return component + + +class TestNodeFuncs(DbIsolationMixin, OsfTestCase): + + def test_there_are_no_nodes_to_start_with(self): + assert_equal(Node.find().count(), 0) + + + # proj + + def test_proj_makes_private_project_private(self): + proj(PRIVATE) + ok_(not Node.find_one().is_public) + + def test_proj_makes_public_project_public(self): + proj(PUBLIC) + ok_(Node.find_one().is_public) + + + # comp + + def test_comp_makes_private_component_private(self): + comp(PRIVATE) + ok_(not Node.find_one(Q('parent_node', 'ne', None)).is_public) + + def test_comp_makes_public_component_public(self): + comp(PUBLIC) + ok_(Node.find_one(Q('parent_node', 'ne', None)).is_public) diff --git a/tests/test_search/test_permissions/test_permfuncs.py b/tests/test_search/test_permissions/test_permfuncs.py new file mode 100644 index 00000000000..ff02e6a9a30 --- /dev/null +++ b/tests/test_search/test_permissions/test_permfuncs.py @@ -0,0 +1,73 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import, division, print_function, unicode_literals + +from nose.tools import assert_equal, assert_in, assert_not_in + +from modularodm import Q + +from framework.auth.core import User +from tests import factories +from tests.base import DbIsolationMixin +from tests.test_search import OsfTestCase +from tests.test_search.test_permissions.test_nodefuncs import proj, PUBLIC +from website.util import permissions +from website.project.model import Node + + +def anon(node): + return None + + +def auth(node): + return factories.AuthUserFactory().auth + + +def read(node): + user = factories.AuthUserFactory() + node.add_contributor(user, permissions.READ) + return user.auth + + +class TestPermFuncs(DbIsolationMixin, OsfTestCase): + + @staticmethod + def get_user_id_from_authtuple(authtuple): + return User.find_one(Q('emails', 'eq', authtuple[0]))._id + + + # anon + + def test_anon_returns_none(self): + assert_equal(anon(proj(PUBLIC)), None) + + def test_anon_makes_no_user(self): + anon(proj(PUBLIC)) + assert_equal(len(User.find()), 1) # only the project creator + + + # auth + + def test_auth_returns_authtuple(self): + assert_equal(auth(proj(PUBLIC))[1], 'password') + + def test_auth_creates_a_user(self): + auth(proj(PUBLIC)) + assert_equal(len(User.find()), 2) # project creator + 1 + + def test_auth_user_is_not_a_contributor_on_the_node(self): + user_id = self.get_user_id_from_authtuple(auth(proj(PUBLIC))) + assert_not_in(user_id, Node.find_one().permissions.keys()) + + + # read + + def test_read_returns_authtuple(self): + assert_equal(read(proj(PUBLIC))[1], 'password') + + def test_read_creates_a_user(self): + read(proj(PUBLIC)) + assert_equal(len(User.find()), 2) # project creator + 1 + + def test_read_user_is_a_contributor_on_the_node(self): + user_id = self.get_user_id_from_authtuple(read(proj(PUBLIC))) + assert_in(user_id, Node.find_one().permissions.keys()) diff --git a/tests/test_search/test_permissions.py b/tests/test_search/test_permissions/test_varyfuncs.py similarity index 64% rename from tests/test_search/test_permissions.py rename to tests/test_search/test_permissions/test_varyfuncs.py index a7aa2b5b90f..28ca3ed902d 100644 --- a/tests/test_search/test_permissions.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -2,147 +2,34 @@ from __future__ import absolute_import, division, print_function, unicode_literals import re -import sys -import unittest -import unittest.case -from nose.tools import * # noqa PEP8 asserts +from nose.tools import assert_equal, ok_ -from framework.auth.core import User from modularodm import Q -from nose_parameterized import parameterized from tests import factories from tests.base import DbIsolationMixin -from tests.test_search import OsfTestCase, SearchTestCase +from tests.test_search import OsfTestCase +from tests.test_search.test_permissions.test_nodefuncs import proj, comp from tests.utils import mock_archive from website.files.models.base import File from website.project.model import Node -from website.util import api_url_for, permissions -PRIVATE, PUBLIC = range(2) - - -# nodefuncs - -def proj(status=PUBLIC): - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) - project.update_search() - return project - -def comp(status=PUBLIC): - project = factories.ProjectFactory(title='Slim Slammity', is_public=status is PUBLIC) - project.update_search() - component = factories.NodeFactory( - title='Flim Flammity', - parent=project, - is_public=status is PUBLIC, - ) - component.update_search() - return component - - -class TestNodeFuncs(DbIsolationMixin, OsfTestCase): - - def test_there_are_no_nodes_to_start_with(self): - assert Node.find().count() == 0 - - - # proj - - def test_proj_makes_private_project_private(self): - proj(PRIVATE) - assert not Node.find_one().is_public - - def test_proj_makes_public_project_public(self): - proj(PUBLIC) - assert Node.find_one().is_public - - - # comp - - def test_comp_makes_private_component_private(self): - comp(PRIVATE) - assert not Node.find_one(Q('parent_node', 'ne', None)).is_public - - def test_comp_makes_public_component_public(self): - comp(PUBLIC) - assert Node.find_one(Q('parent_node', 'ne', None)).is_public - - -# permfuncs - -def anon(node): - return None - -def auth(node): - return factories.AuthUserFactory().auth - -def read(node): - user = factories.AuthUserFactory() - node.add_contributor(user, permissions.READ) - return user.auth - - -class TestPermFuncs(DbIsolationMixin, OsfTestCase): - - @staticmethod - def get_user_id_from_authtuple(authtuple): - return User.find_one(Q('emails', 'eq', authtuple[0]))._id - - - # anon - - def test_anon_returns_none(self): - assert_equal(anon(proj(PUBLIC)), None) - - def test_anon_makes_no_user(self): - anon(proj(PUBLIC)) - assert_equal(len(User.find()), 1) # only the project creator - - - # auth - - def test_auth_returns_authtuple(self): - assert_equal(auth(proj(PUBLIC))[1], 'password') - - def test_auth_creates_a_user(self): - auth(proj(PUBLIC)) - assert_equal(len(User.find()), 2) # project creator + 1 - - def test_auth_user_is_not_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(auth(proj(PUBLIC))) - assert_not_in(user_id, Node.find_one().permissions.keys()) - - - # read - - def test_read_returns_authtuple(self): - assert_equal(read(proj(PUBLIC))[1], 'password') - - def test_read_creates_a_user(self): - read(proj(PUBLIC)) - assert_equal(len(User.find()), 2) # project creator + 1 - - def test_read_user_is_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(read(proj(PUBLIC))) - assert_in(user_id, Node.find_one().permissions.keys()) - - -# varyfuncs - def base(node): type_ = 'project' if node.parent_node is None else 'component' return 'flim', type_, 'title', 'Flim Flammity' + def file_on(node): node.get_addon('osfstorage').get_root().append_file('Blim Blammity') return 'blim', 'file', 'name', 'Blim Blammity' + def _register(*a, **kw): mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy return 'flim', 'registration', 'title', 'Flim Flammity' + def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_retraction, **_): retraction_part = '' if not retraction else \ '{}_retraction_of_an_'.format('approved' if autoapprove_retraction else @@ -154,12 +41,14 @@ def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_ret 'complete' if autocomplete else 'incomplete', ).encode('ascii') + def create_regfunc(**kw): def regfunc(node): return _register(node, **kw) regfunc.__name__ = name_regfunc(**kw) return regfunc + def create_regfuncs(): public = set() private = set() @@ -205,6 +94,7 @@ def create_regfuncs(): file_on, ) + tuple(REGFUNCS) + class TestVaryFuncs(DbIsolationMixin, OsfTestCase): # base @@ -367,84 +257,3 @@ def test_aroeuiro_makes_an_approved_retraction_of_an_embargoed_unapproved_incomp assert_equal(reg.retraction.state, 'approved') assert_equal(reg.embargo.state, 'rejected') ok_(not reg.archive_job.done) - - -# gettin' it together - -def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): - return "{}{} {} {} {}".format( - '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', - 'private' if status is PRIVATE else 'public', - 'project' if nodefunc is proj else 'component', - 'shown to' if should_see else 'hidden from', - permfunc.__name__ - ) - -def seefunc(status, varyfunc, permfunc, default__TODO_remove_this_argument=True): - if status is PRIVATE or varyfunc in REGFUNCS_PRIVATE: - return permfunc is read - return default__TODO_remove_this_argument - -def generate_cases(): - for status in (PRIVATE, PUBLIC): - for nodefunc in (proj, comp): - for permfunc in (anon, auth, read): - for varyfunc in VARYFUNCS: - if status is PRIVATE and varyfunc in REGFUNCS: continue - should_see = seefunc(status, varyfunc, permfunc) # namefunc wants this - name = namefunc(**locals()) - yield name, varyfunc, nodefunc, status, permfunc, should_see - - -class TestGenerateCases(unittest.TestCase): - - # gc - generate_cases - - def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 144) - - def test_gc_doesnt_create_any_nodes(self): - list(generate_cases()) - assert_equal(len(Node.find()), 0) - - -def possiblyExpectFailure(case): - - # This is a hack to conditionally wrap a failure expectation around *some* - # of the cases we're feeding to node-parameterized. TODO It can be removed - # when we write the code to unfail the tests. - - def test(*a, **kw): # name must start with test or it's ignored - _, _, varyfunc, _, status, permfunc, _ = a - if seefunc(status, varyfunc, permfunc, False): - - # This bit is copied from the unittest/case.py:expectedFailure - # decorator. - - try: - case(*a, **kw) - except Exception: - raise unittest.case._ExpectedFailure(sys.exc_info()) - raise unittest.case._UnexpectedSuccess - else: - case(*a, **kw) - return test - -class TestSearchSearchAPI(SearchTestCase): - """Exercises the website.search.views.search_search view. - """ - - def search(self, query, category, auth): - url = api_url_for('search_search') - data = {'q': 'category:{} AND {}'.format(category, query)} - return self.app.get(url, data, auth=auth).json['results'] - - @parameterized.expand(generate_cases) - @possiblyExpectFailure - def test(self, ignored, varyfunc, nodefunc, status, permfunc, should_see): - node = nodefunc(status) - auth = permfunc(node) - query, type_, key, expected_name = varyfunc(node) - expected = [(expected_name, type_)] if should_see else [] - results = self.search(query, type_, auth) - assert_equal([(x[key], x['category']) for x in results], expected) From 056b5a88a3a47a70259436e87eacef3fcc61adeb Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 23 Nov 2016 06:13:41 -0500 Subject: [PATCH 54/65] Clean up some names and comments --- .../test_search/test_permissions/__init__.py | 22 ++++++++++--------- .../test_permissions/test_varyfuncs.py | 4 ++++ 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index a661e8bbf70..9ab1942d342 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -1,11 +1,11 @@ # -*- coding: utf-8 -*- """This is a test suite for permissions on the search_search endpoint. It has four parts: - - nodefuncs - functions for different Node types - - permfuncs - functions for different permissions - - varyfuncs - functions for different Node state variants + - nodefuncs - functions that return Nodes + - permfuncs - functions that set permissions on a Node + - varyfuncs - functions that vary the (non-permission) state of a Node - TestSearchSearchAPI - the actual tests against the search_search API, - which are generated from a combination of the above three function types + which are generated from the combinations of the above three function types """ from __future__ import absolute_import, division, print_function, unicode_literals @@ -26,7 +26,7 @@ from website.util import api_url_for -def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): +def determine_test_name(varyfunc, status, nodefunc, should_see, permfunc, **_): return "{}{} {} {} {}".format( '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', 'private' if status is PRIVATE else 'public', @@ -36,7 +36,7 @@ def namefunc(varyfunc, status, nodefunc, should_see, permfunc, **_): ) -def seefunc(status, varyfunc, permfunc, default__TODO_remove_this_argument=True): +def determine_should_see(status, varyfunc, permfunc, default__TODO_remove_this_argument=True): if status is PRIVATE or varyfunc in REGFUNCS_PRIVATE: return permfunc is read return default__TODO_remove_this_argument @@ -47,9 +47,11 @@ def generate_cases(): for nodefunc in (proj, comp): for permfunc in (anon, auth, read): for varyfunc in VARYFUNCS: - if status is PRIVATE and varyfunc in REGFUNCS: continue - should_see = seefunc(status, varyfunc, permfunc) # namefunc wants this - name = namefunc(**locals()) + if status is PRIVATE and varyfunc in REGFUNCS: + # Registration makes a node public, so skip it. + continue + should_see = determine_should_see(status, varyfunc, permfunc) + name = determine_test_name(**locals()) yield name, varyfunc, nodefunc, status, permfunc, should_see @@ -73,7 +75,7 @@ def possiblyExpectFailure(case): def test(*a, **kw): # name must start with test or it's ignored _, _, varyfunc, _, status, permfunc, _ = a - if seefunc(status, varyfunc, permfunc, False): + if determine_should_see(status, varyfunc, permfunc, False): # This bit is copied from the unittest/case.py:expectedFailure # decorator. diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 28ca3ed902d..9833fb6c1d8 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -25,6 +25,10 @@ def file_on(node): return 'blim', 'file', 'name', 'Blim Blammity' +# Registrations are more complicated, because they have multiple possible +# states. We therefore have a second-level generator to programmatically create +# the functions to vary a node according to the different registration states. + def _register(*a, **kw): mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy return 'flim', 'registration', 'title', 'Flim Flammity' From 78de3abc9888a8eeb5fb599e26ee37b84befbe76 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Thu, 24 Nov 2016 08:03:09 -0500 Subject: [PATCH 55/65] Fix the build and clean up a few more things --- tests/test_search/test_permissions/__init__.py | 12 +++++++++--- tests/test_search/test_permissions/test_varyfuncs.py | 7 +++++-- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index 9ab1942d342..797ed7bfd45 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -26,7 +26,7 @@ from website.util import api_url_for -def determine_test_name(varyfunc, status, nodefunc, should_see, permfunc, **_): +def determine_case_name(varyfunc, status, nodefunc, should_see, permfunc, **_): return "{}{} {} {} {}".format( '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', 'private' if status is PRIVATE else 'public', @@ -42,6 +42,11 @@ def determine_should_see(status, varyfunc, permfunc, default__TODO_remove_this_a return default__TODO_remove_this_argument +def want(name): + # filter cases since we can't use nose's usual mechanisms with parameterization + return True + + def generate_cases(): for status in (PRIVATE, PUBLIC): for nodefunc in (proj, comp): @@ -51,8 +56,9 @@ def generate_cases(): # Registration makes a node public, so skip it. continue should_see = determine_should_see(status, varyfunc, permfunc) - name = determine_test_name(**locals()) - yield name, varyfunc, nodefunc, status, permfunc, should_see + name = determine_case_name(**locals()) + if want(name): + yield name, varyfunc, nodefunc, status, permfunc, should_see class TestGenerateCases(unittest.TestCase): diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 9833fb6c1d8..5f384488204 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -15,9 +15,12 @@ from website.project.model import Node +# The return value is: (search query, category, key to test, expected value). +# Check TestSearchSearchAPI for usage. + def base(node): - type_ = 'project' if node.parent_node is None else 'component' - return 'flim', type_, 'title', 'Flim Flammity' + category = 'project' if node.parent_node is None else 'component' + return 'flim', category, 'title', 'Flim Flammity' def file_on(node): From b09234ac796cf0c38e4e7012cc0873ea909adfb5 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sat, 26 Nov 2016 14:31:23 -0500 Subject: [PATCH 56/65] Add tests for searching wiki content --- .../test_search/test_permissions/__init__.py | 2 +- .../test_permissions/test_varyfuncs.py | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index 797ed7bfd45..209e516a329 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -66,7 +66,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 144) + assert_equal(len(list(generate_cases())), 156) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 5f384488204..3c322cefcd6 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -6,11 +6,13 @@ from nose.tools import assert_equal, ok_ from modularodm import Q +from framework.auth import Auth from tests import factories from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase from tests.test_search.test_permissions.test_nodefuncs import proj, comp -from tests.utils import mock_archive +from tests.utils import mock_archive, run_celery_tasks +from website.addons.wiki.model import NodeWikiPage from website.files.models.base import File from website.project.model import Node @@ -28,6 +30,13 @@ def file_on(node): return 'blim', 'file', 'name', 'Blim Blammity' +def wiki_on(node): + category = 'project' if node.parent_node is None else 'component' + with run_celery_tasks(): + node.update_node_wiki('Blim Blammity', 'Blim, blammity.', Auth(node.creator)) + return 'blim', category, 'title', 'Flim Flammity' + + # Registrations are more complicated, because they have multiple possible # states. We therefore have a second-level generator to programmatically create # the functions to vary a node according to the different registration states. @@ -99,6 +108,7 @@ def create_regfuncs(): VARYFUNCS = ( base, file_on, + wiki_on, ) + tuple(REGFUNCS) @@ -120,6 +130,16 @@ def test_fo_makes_a_file_on_a_node(self): assert_equal(File.find_one(Q('is_file', 'eq', True)).name, 'Blim Blammity') + # wo - wiki_on + + def test_wo_makes_a_wiki_on_a_node(self): + project = factories.ProjectFactory() + wiki_on(project) + page = NodeWikiPage.load(project.wiki_pages_current['blim blammity']) + assert_equal(page.page_name, 'Blim Blammity') + assert_equal(page.content, 'Blim, blammity.') + + # regfuncs def Reg(self, func): From 4d956fd40fcfe3a6e803fd8191ac5f10351d538b Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sat, 26 Nov 2016 17:01:29 -0500 Subject: [PATCH 57/65] Rewire nodefuncs ahead of varying parent.is_public --- .../test_search/test_permissions/__init__.py | 42 +++++++------- .../test_permissions/test_nodefuncs.py | 55 ++++++++++++------- .../test_permissions/test_permfuncs.py | 18 +++--- .../test_permissions/test_varyfuncs.py | 6 +- 4 files changed, 66 insertions(+), 55 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index 209e516a329..582a2f3fdf7 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -21,23 +21,22 @@ from tests.test_search.test_permissions.test_varyfuncs import VARYFUNCS, REGFUNCS, REGFUNCS_PRIVATE from tests.test_search.test_permissions.test_varyfuncs import base from tests.test_search.test_permissions.test_permfuncs import anon, auth, read -from tests.test_search.test_permissions.test_nodefuncs import proj, comp, PUBLIC, PRIVATE +from tests.test_search.test_permissions.test_nodefuncs import NODEFUNCS, NODEFUNCS_PRIVATE from website.project.model import Node from website.util import api_url_for -def determine_case_name(varyfunc, status, nodefunc, should_see, permfunc, **_): - return "{}{} {} {} {}".format( +def determine_case_name(nodefunc, permfunc, varyfunc, should_see, **_): + return "{}{} {} {}".format( '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', - 'private' if status is PRIVATE else 'public', - 'project' if nodefunc is proj else 'component', + ' '.join(nodefunc.__name__.split('_')), 'shown to' if should_see else 'hidden from', permfunc.__name__ ) -def determine_should_see(status, varyfunc, permfunc, default__TODO_remove_this_argument=True): - if status is PRIVATE or varyfunc in REGFUNCS_PRIVATE: +def determine_should_see(nodefunc, permfunc, varyfunc, default__TODO_remove_this_argument=True): + if nodefunc in NODEFUNCS_PRIVATE or varyfunc in REGFUNCS_PRIVATE: return permfunc is read return default__TODO_remove_this_argument @@ -48,17 +47,16 @@ def want(name): def generate_cases(): - for status in (PRIVATE, PUBLIC): - for nodefunc in (proj, comp): - for permfunc in (anon, auth, read): - for varyfunc in VARYFUNCS: - if status is PRIVATE and varyfunc in REGFUNCS: - # Registration makes a node public, so skip it. - continue - should_see = determine_should_see(status, varyfunc, permfunc) - name = determine_case_name(**locals()) - if want(name): - yield name, varyfunc, nodefunc, status, permfunc, should_see + for nodefunc in NODEFUNCS: + for permfunc in (anon, auth, read): + for varyfunc in VARYFUNCS: + if nodefunc in NODEFUNCS_PRIVATE and varyfunc in REGFUNCS: + # Registration makes a node public, so skip it. + continue + should_see = determine_should_see(nodefunc, permfunc, varyfunc) + name = determine_case_name(**locals()) + if want(name): + yield name, nodefunc, permfunc, varyfunc, should_see class TestGenerateCases(unittest.TestCase): @@ -80,8 +78,8 @@ def possiblyExpectFailure(case): # when we write the code to unfail the tests. def test(*a, **kw): # name must start with test or it's ignored - _, _, varyfunc, _, status, permfunc, _ = a - if determine_should_see(status, varyfunc, permfunc, False): + _, _, nodefunc, permfunc, varyfunc, _ = a + if determine_should_see(nodefunc, permfunc, varyfunc, False): # This bit is copied from the unittest/case.py:expectedFailure # decorator. @@ -107,8 +105,8 @@ def search(self, query, category, auth): @parameterized.expand(generate_cases) @possiblyExpectFailure - def test(self, ignored, varyfunc, nodefunc, status, permfunc, should_see): - node = nodefunc(status) + def test(self, ignored, nodefunc, permfunc, varyfunc, should_see): + node = nodefunc() auth = permfunc(node) query, type_, key, expected_name = varyfunc(node) expected = [(expected_name, type_)] if should_see else [] diff --git a/tests/test_search/test_permissions/test_nodefuncs.py b/tests/test_search/test_permissions/test_nodefuncs.py index 7e42825cfeb..eeb662ea914 100644 --- a/tests/test_search/test_permissions/test_nodefuncs.py +++ b/tests/test_search/test_permissions/test_nodefuncs.py @@ -11,26 +11,39 @@ from website.project.model import Node -PRIVATE, PUBLIC = range(2) - - -def proj(status=PUBLIC): - project = factories.ProjectFactory(title='Flim Flammity', is_public=status is PUBLIC) +def _project(is_public): + project = factories.ProjectFactory(title='Flim Flammity', is_public=is_public) project.update_search() return project +def public_project(): return _project(True) +def private_project(): return _project(False) + -def comp(status=PUBLIC): - project = factories.ProjectFactory(title='Slim Slammity', is_public=status is PUBLIC) +def _component(is_public): + project = factories.ProjectFactory(title='Slim Slammity', is_public=is_public) project.update_search() component = factories.NodeFactory( title='Flim Flammity', parent=project, - is_public=status is PUBLIC, + is_public=is_public, ) component.update_search() return component +def public_component(): return _component(True) +def private_component(): return _component(False) + + +NODEFUNCS_PRIVATE = [ + private_project, + private_component +] +NODEFUNCS = [ + public_project, + public_component, +] + NODEFUNCS_PRIVATE + class TestNodeFuncs(DbIsolationMixin, OsfTestCase): @@ -38,23 +51,23 @@ def test_there_are_no_nodes_to_start_with(self): assert_equal(Node.find().count(), 0) - # proj + # pp - {public,private}_project - def test_proj_makes_private_project_private(self): - proj(PRIVATE) - ok_(not Node.find_one().is_public) - - def test_proj_makes_public_project_public(self): - proj(PUBLIC) + def test_pp_makes_public_project_public(self): + public_project() ok_(Node.find_one().is_public) + def test_pp_makes_private_project_private(self): + private_project() + ok_(not Node.find_one().is_public) - # comp - def test_comp_makes_private_component_private(self): - comp(PRIVATE) - ok_(not Node.find_one(Q('parent_node', 'ne', None)).is_public) + # pc - {public,private}_component - def test_comp_makes_public_component_public(self): - comp(PUBLIC) + def test_pc_makes_public_component_public(self): + public_component() ok_(Node.find_one(Q('parent_node', 'ne', None)).is_public) + + def test_pc_makes_private_component_private(self): + private_component() + ok_(not Node.find_one(Q('parent_node', 'ne', None)).is_public) diff --git a/tests/test_search/test_permissions/test_permfuncs.py b/tests/test_search/test_permissions/test_permfuncs.py index ff02e6a9a30..444cc702fdf 100644 --- a/tests/test_search/test_permissions/test_permfuncs.py +++ b/tests/test_search/test_permissions/test_permfuncs.py @@ -9,7 +9,7 @@ from tests import factories from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase -from tests.test_search.test_permissions.test_nodefuncs import proj, PUBLIC +from tests.test_search.test_permissions.test_nodefuncs import public_project from website.util import permissions from website.project.model import Node @@ -38,36 +38,36 @@ def get_user_id_from_authtuple(authtuple): # anon def test_anon_returns_none(self): - assert_equal(anon(proj(PUBLIC)), None) + assert_equal(anon(public_project()), None) def test_anon_makes_no_user(self): - anon(proj(PUBLIC)) + anon(public_project()) assert_equal(len(User.find()), 1) # only the project creator # auth def test_auth_returns_authtuple(self): - assert_equal(auth(proj(PUBLIC))[1], 'password') + assert_equal(auth(public_project())[1], 'password') def test_auth_creates_a_user(self): - auth(proj(PUBLIC)) + auth(public_project()) assert_equal(len(User.find()), 2) # project creator + 1 def test_auth_user_is_not_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(auth(proj(PUBLIC))) + user_id = self.get_user_id_from_authtuple(auth(public_project())) assert_not_in(user_id, Node.find_one().permissions.keys()) # read def test_read_returns_authtuple(self): - assert_equal(read(proj(PUBLIC))[1], 'password') + assert_equal(read(public_project())[1], 'password') def test_read_creates_a_user(self): - read(proj(PUBLIC)) + read(public_project()) assert_equal(len(User.find()), 2) # project creator + 1 def test_read_user_is_a_contributor_on_the_node(self): - user_id = self.get_user_id_from_authtuple(read(proj(PUBLIC))) + user_id = self.get_user_id_from_authtuple(read(public_project())) assert_in(user_id, Node.find_one().permissions.keys()) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 3c322cefcd6..7aa381e5055 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -10,7 +10,7 @@ from tests import factories from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase -from tests.test_search.test_permissions.test_nodefuncs import proj, comp +from tests.test_search.test_permissions.test_nodefuncs import public_project, public_component from tests.utils import mock_archive, run_celery_tasks from website.addons.wiki.model import NodeWikiPage from website.files.models.base import File @@ -117,10 +117,10 @@ class TestVaryFuncs(DbIsolationMixin, OsfTestCase): # base def test_base_specifies_project_for_project(self): - assert_equal(base(proj())[1], 'project') + assert_equal(base(public_project())[1], 'project') def test_base_specifies_component_for_component(self): - assert_equal(base(comp())[1], 'component') + assert_equal(base(public_component())[1], 'component') # fo - file_on From 188b42f2b4b11cc198ecda863f1a11df761c012c Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sat, 26 Nov 2016 17:19:50 -0500 Subject: [PATCH 58/65] Add in cases where parent differs from component --- .../test_search/test_permissions/__init__.py | 2 +- .../test_permissions/test_nodefuncs.py | 46 +++++++++++++------ .../test_permissions/test_varyfuncs.py | 6 ++- 3 files changed, 38 insertions(+), 16 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index 582a2f3fdf7..5ab29907487 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -64,7 +64,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 156) + assert_equal(len(list(generate_cases())), 234) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) diff --git a/tests/test_search/test_permissions/test_nodefuncs.py b/tests/test_search/test_permissions/test_nodefuncs.py index eeb662ea914..35553cb7ecb 100644 --- a/tests/test_search/test_permissions/test_nodefuncs.py +++ b/tests/test_search/test_permissions/test_nodefuncs.py @@ -20,8 +20,8 @@ def public_project(): return _project(True) def private_project(): return _project(False) -def _component(is_public): - project = factories.ProjectFactory(title='Slim Slammity', is_public=is_public) +def _component(is_public, parent_is_public): + project = factories.ProjectFactory(title='Slim Slammity', is_public=parent_is_public) project.update_search() component = factories.NodeFactory( title='Flim Flammity', @@ -31,17 +31,21 @@ def _component(is_public): component.update_search() return component -def public_component(): return _component(True) -def private_component(): return _component(False) +def public_component_of_public_project(): return _component(True, True) +def public_component_of_private_project(): return _component(True, False) +def private_component_of_public_project(): return _component(False, True) +def private_component_of_private_project(): return _component(False, False) NODEFUNCS_PRIVATE = [ private_project, - private_component + private_component_of_public_project, + private_component_of_private_project ] NODEFUNCS = [ public_project, - public_component, + public_component_of_public_project, + public_component_of_private_project ] + NODEFUNCS_PRIVATE @@ -62,12 +66,28 @@ def test_pp_makes_private_project_private(self): ok_(not Node.find_one().is_public) - # pc - {public,private}_component + # pcopp - {public,private}_component_of_{public,private}_project - def test_pc_makes_public_component_public(self): - public_component() - ok_(Node.find_one(Q('parent_node', 'ne', None)).is_public) + def test_pcopp_makes_public_component_of_public_project(self): + public_component_of_public_project() + component = Node.find_one(Q('parent_node', 'ne', None)) + ok_(component.is_public) + ok_(component.parent_node.is_public) - def test_pc_makes_private_component_private(self): - private_component() - ok_(not Node.find_one(Q('parent_node', 'ne', None)).is_public) + def test_pcopp_makes_public_component_of_private_project(self): + public_component_of_private_project() + component = Node.find_one(Q('parent_node', 'ne', None)) + ok_(component.is_public) + ok_(not component.parent_node.is_public) + + def test_pcopp_makes_private_component_of_public_project(self): + private_component_of_public_project() + component = Node.find_one(Q('parent_node', 'ne', None)) + ok_(not component.is_public) + ok_(component.parent_node.is_public) + + def test_pcopp_makes_private_component_of_private_project(self): + private_component_of_private_project() + component = Node.find_one(Q('parent_node', 'ne', None)) + ok_(not component.is_public) + ok_(not component.parent_node.is_public) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 7aa381e5055..5f5e807dd0b 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -10,7 +10,9 @@ from tests import factories from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase -from tests.test_search.test_permissions.test_nodefuncs import public_project, public_component +from tests.test_search.test_permissions.test_nodefuncs import ( + public_project, public_component_of_public_project +) from tests.utils import mock_archive, run_celery_tasks from website.addons.wiki.model import NodeWikiPage from website.files.models.base import File @@ -120,7 +122,7 @@ def test_base_specifies_project_for_project(self): assert_equal(base(public_project())[1], 'project') def test_base_specifies_component_for_component(self): - assert_equal(base(public_component())[1], 'component') + assert_equal(base(public_component_of_public_project())[1], 'component') # fo - file_on From dc77f5a1a6b0c8186af41d8f0c8d9e522f7ca940 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Sun, 27 Nov 2016 07:15:59 -0500 Subject: [PATCH 59/65] Make room for previously embargoed registrations --- .../test_permissions/test_varyfuncs.py | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 5f5e807dd0b..94bedbd40c9 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals +import datetime import re from nose.tools import assert_equal, ok_ @@ -43,18 +44,36 @@ def wiki_on(node): # states. We therefore have a second-level generator to programmatically create # the functions to vary a node according to the different registration states. +def _adapt_embargo(embargo): + """Take embargo as (None, True, False) and return {embargo, embargo_end_date} + """ + if embargo is None: # never embargoed + embargo = False + embargo_end_date = None + elif embargo is False: # previously embargoed + embargo = True + embargo_end_date = datetime.datetime.now() - datetime.timedelta(days=7) + else: # presently embargoed + assert embargo is True + embargo = True + embargo_end_date = None + return {'embargo': embargo, 'embargo_end_date': embargo_end_date} + + def _register(*a, **kw): + kw.update(_adapt_embargo(kw.get('embargo'))) mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy return 'flim', 'registration', 'title', 'Flim Flammity' def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_retraction, **_): retraction_part = '' if not retraction else \ - '{}_retraction_of_an_'.format('approved' if autoapprove_retraction else + '{}_retraction_of_'.format('approved' if autoapprove_retraction else 'unapproved') - return '{}{}_{}_{}_registration_of'.format( + return '{}{}{}_{}_{}_registration_of'.format( retraction_part, - 'embargoed' if embargo else 'unembargoed', + '' if not retraction else 'an_' if embargo in (None, True) else 'a_', + 'embargoed' if embargo else 'unembargoed' if embargo is None else 'previously_embargoed', 'approved' if autoapprove else 'unapproved', 'complete' if autocomplete else 'incomplete', ).encode('ascii') @@ -71,13 +90,13 @@ def create_regfuncs(): public = set() private = set() # Default values are listed first for all of these ... - for embargo in (False, True): + for embargo in (None, True): # never embargoed, presently embargoed, XXX previously embargoed for autoapprove in (False, True): for autocomplete in (True, False): for autoapprove_retraction in (None, False, True): retraction = autoapprove_retraction is not None - if retraction and not (autoapprove or embargo): + if retraction and not (autoapprove or embargo is not None): continue # 'Only public or embargoed registrations may be withdrawn.' regfunc = create_regfunc( From 2a79ef7edf48dd61956f7dafc5a9a35c826ae1b6 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 7 Dec 2016 07:35:49 -0500 Subject: [PATCH 60/65] Refactor for clarity I was getting confused with that goofy default argument. --- .../test_search/test_permissions/__init__.py | 25 +++++++++++-------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index 5ab29907487..3ea32d81f81 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -27,22 +27,20 @@ def determine_case_name(nodefunc, permfunc, varyfunc, should_see, **_): - return "{}{} {} {}".format( - '' if varyfunc is base else varyfunc.__name__.replace('_', ' ') + ' ', - ' '.join(nodefunc.__name__.split('_')), - 'shown to' if should_see else 'hidden from', + return "{}{}_{}_{}".format( + '' if varyfunc is base else varyfunc.__name__ + '_', + nodefunc.__name__, + 'is_shown_to' if should_see else 'is_hidden_from', permfunc.__name__ ) -def determine_should_see(nodefunc, permfunc, varyfunc, default__TODO_remove_this_argument=True): - if nodefunc in NODEFUNCS_PRIVATE or varyfunc in REGFUNCS_PRIVATE: - return permfunc is read - return default__TODO_remove_this_argument +def is_private(nodefunc, varyfunc): + return nodefunc in NODEFUNCS_PRIVATE or varyfunc in REGFUNCS_PRIVATE def want(name): - # filter cases since we can't use nose's usual mechanisms with parameterization + # filter cases here since we can't use nose's usual mechanisms with parameterization return True @@ -53,7 +51,7 @@ def generate_cases(): if nodefunc in NODEFUNCS_PRIVATE and varyfunc in REGFUNCS: # Registration makes a node public, so skip it. continue - should_see = determine_should_see(nodefunc, permfunc, varyfunc) + should_see = permfunc is read if is_private(nodefunc, varyfunc) else True name = determine_case_name(**locals()) if want(name): yield name, nodefunc, permfunc, varyfunc, should_see @@ -79,7 +77,12 @@ def possiblyExpectFailure(case): def test(*a, **kw): # name must start with test or it's ignored _, _, nodefunc, permfunc, varyfunc, _ = a - if determine_should_see(nodefunc, permfunc, varyfunc, False): + + # The tests we expect to fail are those where a node is in a private + # state, and a user does have read permission: a private search, in + # other words. + + if is_private(nodefunc, varyfunc) and permfunc is read: # This bit is copied from the unittest/case.py:expectedFailure # decorator. From c89f93290fb7cd1402c7e938105a6d491ba491f9 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 7 Dec 2016 07:55:18 -0500 Subject: [PATCH 61/65] Refactor varyfuncs a bit --- .../test_permissions/test_varyfuncs.py | 66 ++++++++----------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 94bedbd40c9..7b8ba627149 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -44,25 +44,15 @@ def wiki_on(node): # states. We therefore have a second-level generator to programmatically create # the functions to vary a node according to the different registration states. -def _adapt_embargo(embargo): - """Take embargo as (None, True, False) and return {embargo, embargo_end_date} - """ - if embargo is None: # never embargoed - embargo = False - embargo_end_date = None - elif embargo is False: # previously embargoed - embargo = True - embargo_end_date = datetime.datetime.now() - datetime.timedelta(days=7) - else: # presently embargoed - assert embargo is True - embargo = True - embargo_end_date = None - return {'embargo': embargo, 'embargo_end_date': embargo_end_date} - - def _register(*a, **kw): - kw.update(_adapt_embargo(kw.get('embargo'))) - mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy + embargo = kw.get('embargo') # (None, True, False) + kw['embargo'] = False if embargo is None else True # (True, False) + for unwanted in ('regfunc', 'should_be_public', 'private', 'public'): + kw.pop(unwanted, '') + registration = mock_archive(*a, **kw).__enter__() # gooooooofffyyyyyy + if embargo is False and registration.is_embargoed: + registration.terminate_embargo(Auth(registration.creator)) + registration.update_search() return 'flim', 'registration', 'title', 'Flim Flammity' @@ -79,6 +69,23 @@ def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_ret ).encode('ascii') +def want_regfunc(name): # helpful to filter regfuncs during development + return True + + +def determine_whether_it_should_be_public(retraction, embargo, autoapprove_retraction, \ + autocomplete, autoapprove, **kw): + if retraction and embargo: + # Approving a retraction removes embargoes and makes the reg public, + # but only for *completed* registrations. + should_be_public = autoapprove_retraction and autocomplete + elif embargo: + should_be_public = False + else: + should_be_public = (autoapprove or autoapprove_retraction) and autocomplete + return should_be_public + + def create_regfunc(**kw): def regfunc(node): return _register(node, **kw) @@ -95,27 +102,12 @@ def create_regfuncs(): for autocomplete in (True, False): for autoapprove_retraction in (None, False, True): retraction = autoapprove_retraction is not None - if retraction and not (autoapprove or embargo is not None): continue # 'Only public or embargoed registrations may be withdrawn.' - - regfunc = create_regfunc( - embargo=embargo, - retraction=retraction, - autoapprove_retraction=autoapprove_retraction, - autocomplete=autocomplete, - autoapprove=autoapprove, - ) - - if retraction and embargo: - # Approving a retraction removes embargoes and makes the reg public, - # but only for *completed* registrations. - should_be_public = autoapprove_retraction and autocomplete - elif embargo: - should_be_public = False - else: - should_be_public = autoapprove and autocomplete - + regfunc = create_regfunc(**locals()) + if not want_regfunc(regfunc.__name__): + continue + should_be_public = determine_whether_it_should_be_public(**locals()) (public if should_be_public else private).add(regfunc) return public, private From da489a2c92497b539fd6ea44f0fc7eb3395f7dd0 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Wed, 7 Dec 2016 07:37:06 -0500 Subject: [PATCH 62/65] Add in formerly embargoed cases --- .../test_search/test_permissions/__init__.py | 2 +- .../test_permissions/test_nodefuncs.py | 34 ++--- .../test_permissions/test_varyfuncs.py | 127 ++++++++++++++---- 3 files changed, 117 insertions(+), 46 deletions(-) diff --git a/tests/test_search/test_permissions/__init__.py b/tests/test_search/test_permissions/__init__.py index 3ea32d81f81..829197bafa5 100644 --- a/tests/test_search/test_permissions/__init__.py +++ b/tests/test_search/test_permissions/__init__.py @@ -62,7 +62,7 @@ class TestGenerateCases(unittest.TestCase): # gc - generate_cases def test_gc_generates_cases(self): - assert_equal(len(list(generate_cases())), 234) + assert_equal(len(list(generate_cases())), 342) def test_gc_doesnt_create_any_nodes(self): list(generate_cases()) diff --git a/tests/test_search/test_permissions/test_nodefuncs.py b/tests/test_search/test_permissions/test_nodefuncs.py index 35553cb7ecb..97b0218fd91 100644 --- a/tests/test_search/test_permissions/test_nodefuncs.py +++ b/tests/test_search/test_permissions/test_nodefuncs.py @@ -31,21 +31,21 @@ def _component(is_public, parent_is_public): component.update_search() return component -def public_component_of_public_project(): return _component(True, True) -def public_component_of_private_project(): return _component(True, False) -def private_component_of_public_project(): return _component(False, True) -def private_component_of_private_project(): return _component(False, False) +def public_component_of_a_public_project(): return _component(True, True) +def public_component_of_a_private_project(): return _component(True, False) +def private_component_of_a_public_project(): return _component(False, True) +def private_component_of_a_private_project(): return _component(False, False) NODEFUNCS_PRIVATE = [ private_project, - private_component_of_public_project, - private_component_of_private_project + private_component_of_a_public_project, + private_component_of_a_private_project ] NODEFUNCS = [ public_project, - public_component_of_public_project, - public_component_of_private_project + public_component_of_a_public_project, + public_component_of_a_private_project ] + NODEFUNCS_PRIVATE @@ -66,28 +66,28 @@ def test_pp_makes_private_project_private(self): ok_(not Node.find_one().is_public) - # pcopp - {public,private}_component_of_{public,private}_project + # pcoapp - {public,private}_component_of_a_{public,private}_project - def test_pcopp_makes_public_component_of_public_project(self): - public_component_of_public_project() + def test_pcoapp_makes_public_component_of_a_public_project(self): + public_component_of_a_public_project() component = Node.find_one(Q('parent_node', 'ne', None)) ok_(component.is_public) ok_(component.parent_node.is_public) - def test_pcopp_makes_public_component_of_private_project(self): - public_component_of_private_project() + def test_pcoapp_makes_public_component_of_a_private_project(self): + public_component_of_a_private_project() component = Node.find_one(Q('parent_node', 'ne', None)) ok_(component.is_public) ok_(not component.parent_node.is_public) - def test_pcopp_makes_private_component_of_public_project(self): - private_component_of_public_project() + def test_pcoapp_makes_private_component_of_a_public_project(self): + private_component_of_a_public_project() component = Node.find_one(Q('parent_node', 'ne', None)) ok_(not component.is_public) ok_(component.parent_node.is_public) - def test_pcopp_makes_private_component_of_private_project(self): - private_component_of_private_project() + def test_pcoapp_makes_private_component_of_a_private_project(self): + private_component_of_a_private_project() component = Node.find_one(Q('parent_node', 'ne', None)) ok_(not component.is_public) ok_(not component.parent_node.is_public) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 7b8ba627149..707019a8495 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals -import datetime import re from nose.tools import assert_equal, ok_ @@ -12,7 +11,7 @@ from tests.base import DbIsolationMixin from tests.test_search import OsfTestCase from tests.test_search.test_permissions.test_nodefuncs import ( - public_project, public_component_of_public_project + public_project, public_component_of_a_public_project ) from tests.utils import mock_archive, run_celery_tasks from website.addons.wiki.model import NodeWikiPage @@ -60,10 +59,10 @@ def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_ret retraction_part = '' if not retraction else \ '{}_retraction_of_'.format('approved' if autoapprove_retraction else 'unapproved') - return '{}{}{}_{}_{}_registration_of'.format( + return '{}{}{}_{}_{}_registration_of_a'.format( retraction_part, '' if not retraction else 'an_' if embargo in (None, True) else 'a_', - 'embargoed' if embargo else 'unembargoed' if embargo is None else 'previously_embargoed', + 'embargoed' if embargo else 'unembargoed' if embargo is None else 'formerly_embargoed', 'approved' if autoapprove else 'unapproved', 'complete' if autocomplete else 'incomplete', ).encode('ascii') @@ -97,7 +96,7 @@ def create_regfuncs(): public = set() private = set() # Default values are listed first for all of these ... - for embargo in (None, True): # never embargoed, presently embargoed, XXX previously embargoed + for embargo in (None, True, False): # never, currently, formerly for autoapprove in (False, True): for autocomplete in (True, False): for autoapprove_retraction in (None, False, True): @@ -133,7 +132,7 @@ def test_base_specifies_project_for_project(self): assert_equal(base(public_project())[1], 'project') def test_base_specifies_component_for_component(self): - assert_equal(base(public_component_of_public_project())[1], 'component') + assert_equal(base(public_component_of_a_public_project())[1], 'component') # fo - file_on @@ -160,140 +159,212 @@ def Reg(self, func): return Node.find_one(Q('is_registration', 'eq', True)) def test_number_of_regfuncs(self): - assert_equal(len(REGFUNCS), 20) + assert_equal(len(REGFUNCS), 32) def test_number_of_regfunc_tests(self): - is_regfunc_test = lambda n: re.match('test_.*makes_an_.*_registration_of_a_node', n) + is_regfunc_test = lambda n: re.match('test_.*makes_a.*_registration_of_a_node', n) regfunc_tests = filter(is_regfunc_test, self.__class__.__dict__.keys()) assert_equal(len(regfunc_tests), len(REGFUNCS)) # no retraction def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unembargoed_approved_complete_registration_of) + reg = self.Reg(unembargoed_approved_complete_registration_of_a) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(reg.archive_job.done) def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unembargoed_approved_incomplete_registration_of) + reg = self.Reg(unembargoed_approved_incomplete_registration_of_a) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) def test_uucro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(unembargoed_unapproved_complete_registration_of) + reg = self.Reg(unembargoed_unapproved_complete_registration_of_a) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') ok_(reg.archive_job.done) def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(unembargoed_unapproved_incomplete_registration_of) + reg = self.Reg(unembargoed_unapproved_incomplete_registration_of_a) ok_(reg.retraction is None) ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'unapproved') ok_(not reg.archive_job.done) def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(embargoed_approved_complete_registration_of) + reg = self.Reg(embargoed_approved_complete_registration_of_a) ok_(reg.retraction is None) assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(embargoed_approved_incomplete_registration_of) + reg = self.Reg(embargoed_approved_incomplete_registration_of_a) ok_(reg.retraction is None) assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(embargoed_unapproved_complete_registration_of) + reg = self.Reg(embargoed_unapproved_complete_registration_of_a) ok_(reg.retraction is None) assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(embargoed_unapproved_incomplete_registration_of) + reg = self.Reg(embargoed_unapproved_incomplete_registration_of_a) + ok_(reg.retraction is None) + assert_equal(reg.embargo.state, 'unapproved') + ok_(not reg.archive_job.done) + + def test_feacro_makes_a_formerly_embargoed_approved_complete_registration_of_a_node(self): + reg = self.Reg(formerly_embargoed_approved_complete_registration_of_a) + ok_(reg.retraction is None) + assert_equal(reg.embargo.state, 'completed') + ok_(reg.archive_job.done) + + def test_feairo_makes_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): + reg = self.Reg(formerly_embargoed_approved_incomplete_registration_of_a) + ok_(reg.retraction is None) + assert_equal(reg.embargo.state, 'completed') + ok_(not reg.archive_job.done) + + def test_feucro_makes_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): + reg = self.Reg(formerly_embargoed_unapproved_complete_registration_of_a) + ok_(reg.retraction is None) + assert_equal(reg.embargo.state, 'unapproved') + ok_(reg.archive_job.done) + + def test_feuiro_makes_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): + reg = self.Reg(formerly_embargoed_unapproved_incomplete_registration_of_a) ok_(reg.retraction is None) assert_equal(reg.embargo.state, 'unapproved') ok_(not reg.archive_job.done) # unapproved retraction def test_urouacro_makes_an_unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_complete_registration_of) + reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a) assert_equal(reg.retraction.state, 'unapproved') ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(reg.archive_job.done) def test_urouairo_makes_an_unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of) + reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) assert_equal(reg.retraction.state, 'unapproved') ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) def test_uroeacro_makes_an_unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_complete_registration_of) + reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a) assert_equal(reg.retraction.state, 'unapproved') assert_equal(reg.embargo.state, 'approved') ok_(reg.archive_job.done) def test_uroeairo_makes_an_unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of) + reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) assert_equal(reg.retraction.state, 'unapproved') assert_equal(reg.embargo.state, 'approved') ok_(not reg.archive_job.done) def test_uroeucro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of) + reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) assert_equal(reg.retraction.state, 'unapproved') assert_equal(reg.embargo.state, 'unapproved') ok_(reg.archive_job.done) def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of) + reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) + assert_equal(reg.retraction.state, 'unapproved') + assert_equal(reg.embargo.state, 'unapproved') + ok_(not reg.archive_job.done) + + def test_urofeacro_makes_an_unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a_node(self): + reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) + assert_equal(reg.retraction.state, 'unapproved') + assert_equal(reg.embargo.state, 'completed') + ok_(reg.archive_job.done) + + def test_urofeairo_makes_an_unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): + reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) + assert_equal(reg.retraction.state, 'unapproved') + assert_equal(reg.embargo.state, 'completed') + ok_(not reg.archive_job.done) + + def test_urofeucro_makes_an_unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): + reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) + assert_equal(reg.retraction.state, 'unapproved') + assert_equal(reg.embargo.state, 'unapproved') + ok_(reg.archive_job.done) + + def test_urofeuiro_makes_an_unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): + reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) assert_equal(reg.retraction.state, 'unapproved') assert_equal(reg.embargo.state, 'unapproved') ok_(not reg.archive_job.done) # approved retraction def test_arouacro_makes_an_approved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_unembargoed_approved_complete_registration_of) + reg = self.Reg(approved_retraction_of_an_unembargoed_approved_complete_registration_of_a) assert_equal(reg.retraction.state, 'approved') ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(reg.archive_job.done) def test_arouairo_makes_an_approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_unembargoed_approved_incomplete_registration_of) + reg = self.Reg(approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) assert_equal(reg.retraction.state, 'approved') ok_(not reg.embargo) assert_equal(reg.registration_approval.state, 'approved') ok_(not reg.archive_job.done) def test_aroeacro_makes_an_approved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_approved_complete_registration_of) + reg = self.Reg(approved_retraction_of_an_embargoed_approved_complete_registration_of_a) assert_equal(reg.retraction.state, 'approved') assert_equal(reg.embargo.state, 'rejected') ok_(reg.archive_job.done) def test_aroeairo_makes_an_approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_approved_incomplete_registration_of) + reg = self.Reg(approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) assert_equal(reg.retraction.state, 'approved') assert_equal(reg.embargo.state, 'rejected') ok_(not reg.archive_job.done) def test_aroeucro_makes_an_approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_complete_registration_of) + reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) assert_equal(reg.retraction.state, 'approved') assert_equal(reg.embargo.state, 'rejected') ok_(reg.archive_job.done) def test_aroeuiro_makes_an_approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of) + reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(not reg.archive_job.done) + + def test_arofeacro_makes_an_approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(reg.archive_job.done) + + def test_arofeairo_makes_an_approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(not reg.archive_job.done) + + def test_arofeucro_makes_an_approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) + assert_equal(reg.retraction.state, 'approved') + assert_equal(reg.embargo.state, 'rejected') + ok_(reg.archive_job.done) + + def test_arofeuiro_makes_an_approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): + reg = self.Reg(approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) assert_equal(reg.retraction.state, 'approved') assert_equal(reg.embargo.state, 'rejected') ok_(not reg.archive_job.done) From 624575b75baa2c45ce9f8e6c130302fe1fa3914d Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 9 Dec 2016 05:54:12 -0500 Subject: [PATCH 63/65] DRY up regfunc tests --- .../test_permissions/test_varyfuncs.py | 230 +++++++----------- 1 file changed, 92 insertions(+), 138 deletions(-) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 707019a8495..14b799f1c17 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -154,9 +154,35 @@ def test_wo_makes_a_wiki_on_a_node(self): # regfuncs - def Reg(self, func): + def Check(self, func): func(factories.ProjectFactory(title='Flim Flammity')) - return Node.find_one(Q('is_registration', 'eq', True)) + reg = Node.find_one(Q('is_registration', 'eq', True)) + + def check(retraction_state, embargo_state, approval_state, job_done): + if retraction_state is None: + ok_(reg.retraction is None) + else: + ok_(reg.retraction is not None) + assert_equal(reg.retraction.state, retraction_state) + + if embargo_state is None: + ok_(reg.embargo is None) + else: + ok_(reg.embargo is not None) + assert_equal(reg.embargo.state, embargo_state) + + if approval_state is None: + ok_(reg.registration_approval is None) + else: + ok_(reg.registration_approval is not None) + assert_equal(reg.registration_approval.state, approval_state) + + if job_done: + ok_(reg.archive_job.done) + else: + ok_(not reg.archive_job.done) + + return check def test_number_of_regfuncs(self): assert_equal(len(REGFUNCS), 32) @@ -168,203 +194,131 @@ def test_number_of_regfunc_tests(self): # no retraction def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unembargoed_approved_complete_registration_of_a) - ok_(reg.retraction is None) - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'approved') - ok_(reg.archive_job.done) + check = self.Check(unembargoed_approved_complete_registration_of_a) + check(None, None, 'approved', True) def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unembargoed_approved_incomplete_registration_of_a) - ok_(reg.retraction is None) - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'approved') - ok_(not reg.archive_job.done) + check = self.Check(unembargoed_approved_incomplete_registration_of_a) + check(None, None, 'approved', False) def test_uucro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(unembargoed_unapproved_complete_registration_of_a) - ok_(reg.retraction is None) - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'unapproved') - ok_(reg.archive_job.done) + check = self.Check(unembargoed_unapproved_complete_registration_of_a) + check(None, None, 'unapproved', True) def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(unembargoed_unapproved_incomplete_registration_of_a) - ok_(reg.retraction is None) - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'unapproved') - ok_(not reg.archive_job.done) + check = self.Check(unembargoed_unapproved_incomplete_registration_of_a) + check(None, None, 'unapproved', False) def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(embargoed_approved_complete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'approved') - ok_(reg.archive_job.done) + check = self.Check(embargoed_approved_complete_registration_of_a) + check(None, 'approved', None, True) def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(embargoed_approved_incomplete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'approved') - ok_(not reg.archive_job.done) + check = self.Check(embargoed_approved_incomplete_registration_of_a) + check(None, 'approved', None, False) def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(embargoed_unapproved_complete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'unapproved') - ok_(reg.archive_job.done) + check = self.Check(embargoed_unapproved_complete_registration_of_a) + check(None, 'unapproved', None, True) def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(embargoed_unapproved_incomplete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'unapproved') - ok_(not reg.archive_job.done) + check = self.Check(embargoed_unapproved_incomplete_registration_of_a) + check(None, 'unapproved', None, False) def test_feacro_makes_a_formerly_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(formerly_embargoed_approved_complete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'completed') - ok_(reg.archive_job.done) + check = self.Check(formerly_embargoed_approved_complete_registration_of_a) + check(None, 'completed', None, True) def test_feairo_makes_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(formerly_embargoed_approved_incomplete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'completed') - ok_(not reg.archive_job.done) + check = self.Check(formerly_embargoed_approved_incomplete_registration_of_a) + check(None, 'completed', None, False) def test_feucro_makes_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(formerly_embargoed_unapproved_complete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'unapproved') - ok_(reg.archive_job.done) + check = self.Check(formerly_embargoed_unapproved_complete_registration_of_a) + check(None, 'unapproved', None, True) def test_feuiro_makes_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(formerly_embargoed_unapproved_incomplete_registration_of_a) - ok_(reg.retraction is None) - assert_equal(reg.embargo.state, 'unapproved') - ok_(not reg.archive_job.done) + check = self.Check(formerly_embargoed_unapproved_incomplete_registration_of_a) + check(None, 'unapproved', None, False) # unapproved retraction def test_urouacro_makes_an_unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'approved') - ok_(reg.archive_job.done) + check = self.Check(unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a) + check('unapproved', None, 'approved', True) def test_urouairo_makes_an_unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'approved') - ok_(not reg.archive_job.done) + check = self.Check(unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) + check('unapproved', None, 'approved', False) def test_uroeacro_makes_an_unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'approved') - ok_(reg.archive_job.done) + check = self.Check(unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a) + check('unapproved', 'approved', None, True) def test_uroeairo_makes_an_unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'approved') - ok_(not reg.archive_job.done) + check = self.Check(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) + check('unapproved', 'approved', None, False) def test_uroeucro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'unapproved') - ok_(reg.archive_job.done) + check = self.Check(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) + check('unapproved', 'unapproved', None, True) def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'unapproved') - ok_(not reg.archive_job.done) + check = self.Check(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) + check('unapproved', 'unapproved', None, False) def test_urofeacro_makes_an_unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'completed') - ok_(reg.archive_job.done) + check = self.Check(unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) + check('unapproved', 'completed', None, True) def test_urofeairo_makes_an_unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'completed') - ok_(not reg.archive_job.done) + check = self.Check(unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) + check('unapproved', 'completed', None, False) def test_urofeucro_makes_an_unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'unapproved') - ok_(reg.archive_job.done) + check = self.Check(unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) + check('unapproved', 'unapproved', None, True) def test_urofeuiro_makes_an_unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'unapproved') - assert_equal(reg.embargo.state, 'unapproved') - ok_(not reg.archive_job.done) + check = self.Check(unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) + check('unapproved', 'unapproved', None, False) # approved retraction def test_arouacro_makes_an_approved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_unembargoed_approved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'approved') - ok_(reg.archive_job.done) + check = self.Check(approved_retraction_of_an_unembargoed_approved_complete_registration_of_a) + check('approved', None, 'approved', True) def test_arouairo_makes_an_approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - ok_(not reg.embargo) - assert_equal(reg.registration_approval.state, 'approved') - ok_(not reg.archive_job.done) + check = self.Check(approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) + check('approved', None, 'approved', False) def test_aroeacro_makes_an_approved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_approved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(reg.archive_job.done) + check = self.Check(approved_retraction_of_an_embargoed_approved_complete_registration_of_a) + check('approved', 'rejected', None, True) def test_aroeairo_makes_an_approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(not reg.archive_job.done) + check = self.Check(approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) + check('approved', 'rejected', None, False) def test_aroeucro_makes_an_approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(reg.archive_job.done) + check = self.Check(approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) + check('approved', 'rejected', None, True) def test_aroeuiro_makes_an_approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(not reg.archive_job.done) + check = self.Check(approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) + check('approved', 'rejected', None, False) def test_arofeacro_makes_an_approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(reg.archive_job.done) + check = self.Check(approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) + check('approved', 'rejected', None, True) def test_arofeairo_makes_an_approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(not reg.archive_job.done) + check = self.Check(approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) + check('approved', 'rejected', None, False) def test_arofeucro_makes_an_approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(reg.archive_job.done) + check = self.Check(approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) + check('approved', 'rejected', None, True) def test_arofeuiro_makes_an_approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): - reg = self.Reg(approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) - assert_equal(reg.retraction.state, 'approved') - assert_equal(reg.embargo.state, 'rejected') - ok_(not reg.archive_job.done) + check = self.Check(approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) + check('approved', 'rejected', None, False) From 6e2510f4051ea264c73dfbf7bd93b0126f3cac58 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 9 Dec 2016 06:11:06 -0500 Subject: [PATCH 64/65] Use a dict other than locals() This way vim-pyflakes stops yelling quite so much. --- .../test_permissions/test_varyfuncs.py | 142 +++++++++--------- 1 file changed, 69 insertions(+), 73 deletions(-) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index 14b799f1c17..d2f74797cf9 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -1,8 +1,6 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import, division, print_function, unicode_literals -import re - from nose.tools import assert_equal, ok_ from modularodm import Q @@ -112,10 +110,7 @@ def create_regfuncs(): REGFUNCS_PUBLIC, REGFUNCS_PRIVATE = create_regfuncs() REGFUNCS = REGFUNCS_PUBLIC | REGFUNCS_PRIVATE - -locals_dict = locals() -for regfunc in REGFUNCS: - locals_dict[regfunc.__name__] = regfunc +_REGFUNCS_BY_NAME = {regfunc.__name__: regfunc for regfunc in REGFUNCS} VARYFUNCS = ( base, @@ -154,8 +149,9 @@ def test_wo_makes_a_wiki_on_a_node(self): # regfuncs - def Check(self, func): - func(factories.ProjectFactory(title='Flim Flammity')) + def Check(self, name): + regfunc = _REGFUNCS_BY_NAME[name + '_registration_of_a'] + regfunc(factories.ProjectFactory(title='Flim Flammity')) reg = Node.find_one(Q('is_registration', 'eq', True)) def check(retraction_state, embargo_state, approval_state, job_done): @@ -188,137 +184,137 @@ def test_number_of_regfuncs(self): assert_equal(len(REGFUNCS), 32) def test_number_of_regfunc_tests(self): - is_regfunc_test = lambda n: re.match('test_.*makes_a.*_registration_of_a_node', n) + is_regfunc_test = lambda n: n.startswith('test_regfunc_') regfunc_tests = filter(is_regfunc_test, self.__class__.__dict__.keys()) assert_equal(len(regfunc_tests), len(REGFUNCS)) # no retraction - def test_uacro_makes_an_unembargoed_approved_complete_registration_of_a_node(self): - check = self.Check(unembargoed_approved_complete_registration_of_a) + def test_regfunc_uac(self): + check = self.Check('unembargoed_approved_complete') check(None, None, 'approved', True) - def test_uairo_makes_an_unembargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(unembargoed_approved_incomplete_registration_of_a) + def test_regfunc_uai(self): + check = self.Check('unembargoed_approved_incomplete') check(None, None, 'approved', False) - def test_uucro_makes_an_unembargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(unembargoed_unapproved_complete_registration_of_a) + def test_regfunc_uuc(self): + check = self.Check('unembargoed_unapproved_complete') check(None, None, 'unapproved', True) - def test_uuiro_makes_an_unembargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(unembargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_uui(self): + check = self.Check('unembargoed_unapproved_incomplete') check(None, None, 'unapproved', False) - def test_eacro_makes_an_embargoed_approved_complete_registration_of_a_node(self): - check = self.Check(embargoed_approved_complete_registration_of_a) + def test_regfunc_eac(self): + check = self.Check('embargoed_approved_complete') check(None, 'approved', None, True) - def test_eairo_makes_an_embargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(embargoed_approved_incomplete_registration_of_a) + def test_regfunc_eai(self): + check = self.Check('embargoed_approved_incomplete') check(None, 'approved', None, False) - def test_eucro_makes_an_embargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(embargoed_unapproved_complete_registration_of_a) + def test_regfunc_euc(self): + check = self.Check('embargoed_unapproved_complete') check(None, 'unapproved', None, True) - def test_euiro_makes_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(embargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_eui(self): + check = self.Check('embargoed_unapproved_incomplete') check(None, 'unapproved', None, False) - def test_feacro_makes_a_formerly_embargoed_approved_complete_registration_of_a_node(self): - check = self.Check(formerly_embargoed_approved_complete_registration_of_a) + def test_regfunc_feac(self): + check = self.Check('formerly_embargoed_approved_complete') check(None, 'completed', None, True) - def test_feairo_makes_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(formerly_embargoed_approved_incomplete_registration_of_a) + def test_regfunc_feai(self): + check = self.Check('formerly_embargoed_approved_incomplete') check(None, 'completed', None, False) - def test_feucro_makes_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(formerly_embargoed_unapproved_complete_registration_of_a) + def test_regfunc_feuc(self): + check = self.Check('formerly_embargoed_unapproved_complete') check(None, 'unapproved', None, True) - def test_feuiro_makes_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(formerly_embargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_feui(self): + check = self.Check('formerly_embargoed_unapproved_incomplete') check(None, 'unapproved', None, False) # unapproved retraction - def test_urouacro_makes_an_unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_an_unembargoed_approved_complete_registration_of_a) + def test_regfunc_uroauac(self): + check = self.Check('unapproved_retraction_of_an_unembargoed_approved_complete') check('unapproved', None, 'approved', True) - def test_urouairo_makes_an_unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) + def test_regfunc_uroauai(self): + check = self.Check('unapproved_retraction_of_an_unembargoed_approved_incomplete') check('unapproved', None, 'approved', False) - def test_uroeacro_makes_an_unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_an_embargoed_approved_complete_registration_of_a) + def test_regfunc_uroaeac(self): + check = self.Check('unapproved_retraction_of_an_embargoed_approved_complete') check('unapproved', 'approved', None, True) - def test_uroeairo_makes_an_unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) + def test_regfunc_uroaeai(self): + check = self.Check('unapproved_retraction_of_an_embargoed_approved_incomplete') check('unapproved', 'approved', None, False) - def test_uroeucro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) + def test_regfunc_uroaeuc(self): + check = self.Check('unapproved_retraction_of_an_embargoed_unapproved_complete') check('unapproved', 'unapproved', None, True) - def test_uroeuiro_makes_an_unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_uroaeui(self): + check = self.Check('unapproved_retraction_of_an_embargoed_unapproved_incomplete') check('unapproved', 'unapproved', None, False) - def test_urofeacro_makes_an_unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) + def test_regfunc_uroafeac(self): + check = self.Check('unapproved_retraction_of_a_formerly_embargoed_approved_complete') check('unapproved', 'completed', None, True) - def test_urofeairo_makes_an_unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) + def test_regfunc_uroafeai(self): + check = self.Check('unapproved_retraction_of_a_formerly_embargoed_approved_incomplete') check('unapproved', 'completed', None, False) - def test_urofeucro_makes_an_unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) + def test_regfunc_uroafeuc(self): + check = self.Check('unapproved_retraction_of_a_formerly_embargoed_unapproved_complete') check('unapproved', 'unapproved', None, True) - def test_urofeuiro_makes_an_unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_uroafeui(self): + check = self.Check('unapproved_retraction_of_a_formerly_embargoed_unapproved_incomplete') check('unapproved', 'unapproved', None, False) # approved retraction - def test_arouacro_makes_an_approved_retraction_of_an_unembargoed_approved_complete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_an_unembargoed_approved_complete_registration_of_a) + def test_regfunc_aroauac(self): + check = self.Check('approved_retraction_of_an_unembargoed_approved_complete') check('approved', None, 'approved', True) - def test_arouairo_makes_an_approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_an_unembargoed_approved_incomplete_registration_of_a) + def test_regfunc_aroauai(self): + check = self.Check('approved_retraction_of_an_unembargoed_approved_incomplete') check('approved', None, 'approved', False) - def test_aroeacro_makes_an_approved_retraction_of_an_embargoed_approved_complete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_an_embargoed_approved_complete_registration_of_a) + def test_regfunc_aroaeac(self): + check = self.Check('approved_retraction_of_an_embargoed_approved_complete') check('approved', 'rejected', None, True) - def test_aroeairo_makes_an_approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_an_embargoed_approved_incomplete_registration_of_a) + def test_regfunc_aroaeai(self): + check = self.Check('approved_retraction_of_an_embargoed_approved_incomplete') check('approved', 'rejected', None, False) - def test_aroeucro_makes_an_approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_an_embargoed_unapproved_complete_registration_of_a) + def test_regfunc_aroaeuc(self): + check = self.Check('approved_retraction_of_an_embargoed_unapproved_complete') check('approved', 'rejected', None, True) - def test_aroeuiro_makes_an_approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_an_embargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_aroaeui(self): + check = self.Check('approved_retraction_of_an_embargoed_unapproved_incomplete') check('approved', 'rejected', None, False) - def test_arofeacro_makes_an_approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_a_formerly_embargoed_approved_complete_registration_of_a) + def test_regfunc_aroafeac(self): + check = self.Check('approved_retraction_of_a_formerly_embargoed_approved_complete') check('approved', 'rejected', None, True) - def test_arofeairo_makes_an_approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_a_formerly_embargoed_approved_incomplete_registration_of_a) + def test_regfunc_aroafeai(self): + check = self.Check('approved_retraction_of_a_formerly_embargoed_approved_incomplete') check('approved', 'rejected', None, False) - def test_arofeucro_makes_an_approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_a_formerly_embargoed_unapproved_complete_registration_of_a) + def test_regfunc_aroafeuc(self): + check = self.Check('approved_retraction_of_a_formerly_embargoed_unapproved_complete') check('approved', 'rejected', None, True) - def test_arofeuiro_makes_an_approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a_node(self): - check = self.Check(approved_retraction_of_a_formerly_embargoed_unapproved_incomplete_registration_of_a) + def test_regfunc_aroafeui(self): + check = self.Check('approved_retraction_of_a_formerly_embargoed_unapproved_incomplete') check('approved', 'rejected', None, False) From c5e5800ec45a4b660c9e3aac3bcd3f31a42c3b22 Mon Sep 17 00:00:00 2001 From: Chad Whitacre <chad@zetaweb.com> Date: Fri, 9 Dec 2016 06:43:51 -0500 Subject: [PATCH 65/65] Make unembargoed parallel to unretracted --- .../test_permissions/test_varyfuncs.py | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/test_search/test_permissions/test_varyfuncs.py b/tests/test_search/test_permissions/test_varyfuncs.py index d2f74797cf9..00ffc3c8d08 100644 --- a/tests/test_search/test_permissions/test_varyfuncs.py +++ b/tests/test_search/test_permissions/test_varyfuncs.py @@ -57,10 +57,10 @@ def name_regfunc(embargo, autoapprove, autocomplete, retraction, autoapprove_ret retraction_part = '' if not retraction else \ '{}_retraction_of_'.format('approved' if autoapprove_retraction else 'unapproved') - return '{}{}{}_{}_{}_registration_of_a'.format( + return '{}{}{}{}_{}_registration_of_a'.format( retraction_part, '' if not retraction else 'an_' if embargo in (None, True) else 'a_', - 'embargoed' if embargo else 'unembargoed' if embargo is None else 'formerly_embargoed', + 'embargoed_' if embargo else '' if embargo is None else 'formerly_embargoed_', 'approved' if autoapprove else 'unapproved', 'complete' if autocomplete else 'incomplete', ).encode('ascii') @@ -189,20 +189,20 @@ def test_number_of_regfunc_tests(self): assert_equal(len(regfunc_tests), len(REGFUNCS)) # no retraction - def test_regfunc_uac(self): - check = self.Check('unembargoed_approved_complete') + def test_regfunc_ac(self): + check = self.Check('approved_complete') check(None, None, 'approved', True) - def test_regfunc_uai(self): - check = self.Check('unembargoed_approved_incomplete') + def test_regfunc_ai(self): + check = self.Check('approved_incomplete') check(None, None, 'approved', False) - def test_regfunc_uuc(self): - check = self.Check('unembargoed_unapproved_complete') + def test_regfunc_uc(self): + check = self.Check('unapproved_complete') check(None, None, 'unapproved', True) - def test_regfunc_uui(self): - check = self.Check('unembargoed_unapproved_incomplete') + def test_regfunc_ui(self): + check = self.Check('unapproved_incomplete') check(None, None, 'unapproved', False) def test_regfunc_eac(self): @@ -238,12 +238,12 @@ def test_regfunc_feui(self): check(None, 'unapproved', None, False) # unapproved retraction - def test_regfunc_uroauac(self): - check = self.Check('unapproved_retraction_of_an_unembargoed_approved_complete') + def test_regfunc_uroaac(self): + check = self.Check('unapproved_retraction_of_an_approved_complete') check('unapproved', None, 'approved', True) - def test_regfunc_uroauai(self): - check = self.Check('unapproved_retraction_of_an_unembargoed_approved_incomplete') + def test_regfunc_uroaai(self): + check = self.Check('unapproved_retraction_of_an_approved_incomplete') check('unapproved', None, 'approved', False) def test_regfunc_uroaeac(self): @@ -279,12 +279,12 @@ def test_regfunc_uroafeui(self): check('unapproved', 'unapproved', None, False) # approved retraction - def test_regfunc_aroauac(self): - check = self.Check('approved_retraction_of_an_unembargoed_approved_complete') + def test_regfunc_aroaac(self): + check = self.Check('approved_retraction_of_an_approved_complete') check('approved', None, 'approved', True) - def test_regfunc_aroauai(self): - check = self.Check('approved_retraction_of_an_unembargoed_approved_incomplete') + def test_regfunc_aroaai(self): + check = self.Check('approved_retraction_of_an_approved_incomplete') check('approved', None, 'approved', False) def test_regfunc_aroaeac(self):