class TestResource(TestCase): """ Test /search REST API """ def setUp(self): super(TestResource, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.create_objects() def create_objects(self): """Create objects to be searched. Creates five Requirements and makes relationships. 0 1 2 3 4 |---| |---| | |-------|-------| """ self.objects = [ self.object_generator.generate_object(all_models.Requirement)[1].id for _ in xrange(5) ] self.objects = all_models.Requirement.eager_query().filter( all_models.Requirement.id.in_(self.objects) ).all() for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]: self.object_generator.generate_relationship( self.objects[src], self.objects[dst] ) def search(self, *args, **kwargs): res, _ = self.api.search(*args, **kwargs) return res.json["results"]["entries"] def test_search_all(self): """Test search for all objects of a type.""" res, _ = self.api.search("Requirement") self.assertEqual(len(res.json["results"]["entries"]), 5) def test_search_query(self): """Test search with query by title.""" entries = self.search("Requirement", query=self.objects[0].title) self.assertEqual({entry["id"] for entry in entries}, {self.objects[0].id}) def test_search_relevant(self): """Test search with 'relevant to' single object.""" relevant_objects = "Requirement:{}".format(self.objects[0].id) entries = self.search("Requirement", relevant_objects=relevant_objects) self.assertEqual({entry["id"] for entry in entries}, {self.objects[i].id for i in [1, 2]}) def test_search_relevant_multi(self): """Test search with 'relevant to' multiple objects.""" ids = ",".join("Requirement:{}".format(self.objects[i].id) for i in (0, 3)) entries = self.search("Requirement", relevant_objects=ids) self.assertEqual({entry["id"] for entry in entries}, {self.objects[2].id})
class TestResource(TestCase): """ Test /search REST API """ def setUp(self): super(TestResource, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.create_objects() def create_objects(self): """Create objects to be searched. Creates five Requirements and makes relationships. 0 1 2 3 4 |---| |---| | |-------|-------| """ self.objects = [ self.object_generator.generate_object(all_models.Requirement)[1].id for _ in xrange(5) ] self.objects = all_models.Requirement.eager_query().filter( all_models.Requirement.id.in_(self.objects)).all() for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]: self.object_generator.generate_relationship( self.objects[src], self.objects[dst]) def search(self, *args, **kwargs): res, _ = self.api.search(*args, **kwargs) return res.json["results"]["entries"] def test_search_all(self): """Test search for all objects of a type.""" res, _ = self.api.search("Requirement") self.assertEqual(len(res.json["results"]["entries"]), 5) def test_search_query(self): """Test search with query by title.""" entries = self.search("Requirement", query=self.objects[0].title) self.assertEqual({entry["id"] for entry in entries}, {self.objects[0].id}) def test_search_relevant(self): """Test search with 'relevant to' single object.""" relevant_objects = "Requirement:{}".format(self.objects[0].id) entries = self.search("Requirement", relevant_objects=relevant_objects) self.assertEqual({entry["id"] for entry in entries}, {self.objects[i].id for i in [1, 2]}) def test_search_relevant_multi(self): """Test search with 'relevant to' multiple objects.""" ids = ",".join("Requirement:{}".format(self.objects[i].id) for i in (0, 3)) entries = self.search("Requirement", relevant_objects=ids) self.assertEqual({entry["id"] for entry in entries}, {self.objects[2].id})
class TestWorkflowTypesBase(TestCase): """ Base class for /search REST API test """ def setUp(self): """Create API instance """ super(TestWorkflowTypesBase, self).setUp() self.api = Api() def _get_search_ids(self, types, query): """Make request and return entries in format dict(type->list_of_ids)""" response, _ = self.api.search(types=types, query=query, counts=False) entries = response.json['results']['entries'] ret = defaultdict(set) for entry in entries: ret[entry['type']].add(entry['id']) return dict(ret) def _get_count_ids(self, types, query): """Make request and return entries in format dict(type->number_of_ids)""" response, _ = self.api.search(types=types, query=query, counts=True) return response.json['results']['counts'] def _convert_expected_to_dict(self, type_, expected): """Convert list of (type, title) to dict (type -> list_of_ids)""" ret = defaultdict(set) for _, key in expected: ret[type_].add(self.objects[key]) return dict(ret) @staticmethod # pylint: disable=invalid-name def _convert_expected_dict_to_counts(expected): """Convert dict(type->list_of_ids) to dict(type->count_of_ids)""" return dict((k, len(v)) for k, v in expected.iteritems())
class TestStatus(TestCase): """ Test /search REST API status code """ def setUp(self): super(TestStatus, self).setUp() self.api = Api() def test_search_existing_type(self): """Test search for existing type""" res, _ = self.api.search(types="Requirement") self.assert200(res) def test_search_non_existing_type(self): """Test search for non existing type""" res, _ = self.api.search(types="Requirementsss") self.assert200(res) def test_search_multiple_types(self): """Test search for multiple types""" res, _ = self.api.search(types="Requirement,Requirement") self.assert200(res) def test_counts_existing_type(self): """Test counts for existing type""" res, _ = self.api.search(types="Requirement", counts=True) self.assert200(res) def test_counts_non_existing_type(self): """Test counts for non existing type""" res, _ = self.api.search(types="Requirementsss", counts=True) self.assert200(res) def test_counts_multiple_types(self): """Test counts for multiple types""" res, _ = self.api.search(types="Requirement,Requirement", counts=True) self.assert200(res) # pylint: disable=invalid-name def test_search_fail_with_terms_none(self): """Test search to fail with BadRequest (400 Error) when terms are None.""" query = '/search?types={}&counts_only={}'.format("Requirement", False) response = self.api.client.get(query) self.assert400(response) self.assertEqual(response.json['message'], 'Query parameter "q" ' 'specifying search terms must be provided.')
class TestStatus(TestCase): """ Test /search REST API status code """ def setUp(self): super(TestStatus, self).setUp() self.api = Api() def test_search_existing_type(self): """Test search for existing type""" res, _ = self.api.search(types="Requirement") self.assert200(res) def test_search_non_existing_type(self): """Test search for non existing type""" res, _ = self.api.search(types="Requirementsss") self.assert200(res) def test_search_multiple_types(self): """Test search for multiple types""" res, _ = self.api.search(types="Requirement,Requirement") self.assert200(res) def test_counts_existing_type(self): """Test counts for existing type""" res, _ = self.api.search(types="Requirement", counts=True) self.assert200(res) def test_counts_non_existing_type(self): """Test counts for non existing type""" res, _ = self.api.search(types="Requirementsss", counts=True) self.assert200(res) def test_counts_multiple_types(self): """Test counts for multiple types""" res, _ = self.api.search(types="Requirement,Requirement", counts=True) self.assert200(res) # pylint: disable=invalid-name def test_search_fail_with_terms_none(self): """Test search to fail with BadRequest (400 Error) when terms are None.""" query = '/search?types={}&counts_only={}'.format("Requirement", False) response = self.api.client.get(query) self.assert400(response) self.assertEqual( response.json['message'], 'Query parameter "q" ' 'specifying search terms must be provided.')
class TestCreator(TestCase): """ TestCreator """ def setUp(self): super(TestCreator, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("creator", "Creator"), ("admin", "Administrator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): """Permissions to admin page.""" for role, code in (("creator", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_creator_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["creator"]) creator_id = self.users["creator"].id audit_id = factories.AuditFactory().id all_errors = [] base_models = { "Control", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Project", "AccessGroup", "Metric", "ProductGroup", "TechnologyEnvironment" } for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post(model, { table_singular: { "title": model_singular, "context": None, "documents_reference_url": "ref", "link": "https://example.com", # ignored except for Document "contact": { "type": "Person", "id": creator_id, }, "audit": { # this is ignored on everything but Issues "id": audit_id, "type": "Audit", } }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue # Test GET when not owner obj_id = response.json.get(table_singular).get("id") response = self.api.get(model, obj_id) if response.status_code != 403: # we are not onwers yet all_errors.append( "{} can retrieve object if not owner".format( model_singular)) continue response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if collection: all_errors.append( "{} can retrieve object if not owner (collection)". format(model_singular)) continue # Test GET when owner acr = all_models.AccessControlRole.query.filter_by( object_type=model_singular, name="Admin").first() factories.AccessControlListFactory(object_id=obj_id, object_type=model_singular, ac_role=acr, person_id=creator_id) response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if not collection: all_errors.append( "{} cannot retrieve object even if owner (collection)". format(model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_creator_search(self): """Test if creator can see the correct object while using the search api""" self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": { "title": "Admin regulation", "context": None }, }) self.api.set_user(self.users['creator']) acr_id = all_models.AccessControlRole.query.filter_by( object_type="Policy", name="Admin").first().id response = self.api.post( all_models.Policy, { "policy": { "title": "Creator Policy", "context": None, "access_control_list": [ acl_helper.get_acl_json(acr_id, self.users["creator"].id) ], }, }) response.json.get("policy").get("id") response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 1) self.assertEqual(entries[0]["type"], "Policy") response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual(response.json["results"]["counts"].get("Regulation"), None) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_creator_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['creator']) creator_count = self._get_count("Person") self.assertEqual(admin_count, creator_count) def test_relationships_access(self): """Check if creator cannot access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation", "context": None }, }) _, obj_1 = self.generator.generate( all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation 2", "context": None }, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": { "source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None }, }) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['creator']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 0) def test_revision_access(self): """Check if creator can access the right revision objects.""" def gen(title, extra_data=None): """Generates requirement.""" requirement_content = {"title": title, "context": None} if extra_data: requirement_content.update(**extra_data) return self.generator.generate( all_models.Requirement, "requirement", {"requirement": requirement_content})[1] def check(obj, expected): """Check that how many revisions of an object current user can see.""" response = self.api.get_query( all_models.Revision, "resource_type={}&resource_id={}".format(obj.type, obj.id)) self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json['revisions_collection']['revisions']), expected) self.api.set_user(self.users["admin"]) obj_1 = gen("Test Requirement 1") self.api.set_user(self.users["creator"]) acr_id = all_models.AccessControlRole.query.filter_by( object_type="Requirement", name="Admin").first().id linked_acl = { "access_control_list": [acl_helper.get_acl_json(acr_id, self.users["creator"].id)], } check(obj_1, 0) obj_2 = gen("Test Requirement 2", linked_acl) obj2_acl = obj_2.access_control_list[0] check(obj_2, 1) check(obj2_acl, 1) @ddt.data("creator", "admin") def test_count_type_in_accordion(self, glob_role): """Return count of Persons in DB for side accordion.""" self.api.set_user(self.users[glob_role]) ocordion_api_person_count_link = ( "/search?" "q=&types=Program%2CWorkflow_All%2C" "Audit%2CAssessment%2CIssue%2CRegulation%2C" "Policy%2CStandard%2CContract%2CClause%2CRequirement%2CControl%2C" "Objective%2CPerson%2COrgGroup%2CVendor%2CAccessGroup%2CSystem%2C" "Process%2CDataAsset%2CProduct%2CProject%2CFacility%2C" "Market%2CRisk%2CThreat&counts_only=true&" "extra_columns=Workflow_All%3DWorkflow%2C" "Workflow_Active%3DWorkflow%2CWorkflow_Draft%3D" "Workflow%2CWorkflow_Inactive%3DWorkflow&contact_id=1&" "extra_params=Workflow%3Astatus%3DActive%3BWorkflow_Active" "%3Astatus%3DActive%3BWorkflow_Inactive%3Astatus%3D" "Inactive%3BWorkflow_Draft%3Astatus%3DDraft") resp = self.api.client.get(ocordion_api_person_count_link) self.assertIn("Person", resp.json["results"]["counts"]) self.assertEqual(all_models.Person.query.count(), resp.json["results"]["counts"]["Person"]) @ddt.data( ("/api/revisions?resource_type={}&resource_id={}", 1), ("/api/revisions?source_type={}&source_id={}", 0), ("/api/revisions?destination_type={}&destination_id={}", 1), ) @ddt.unpack def test_changelog_access(self, link, revision_count): """Test accessing changelog under GC user who is assigned to object""" with factories.single_commit(): audit = factories.AuditFactory() asmnt = factories.AssessmentFactory(audit=audit) asmnt_id = asmnt.id factories.RelationshipFactory(source=audit, destination=asmnt) verifier_role = all_models.AccessControlRole.query.filter_by( object_type="Assessment", name="Verifiers", ).first() factories.AccessControlListFactory( person=self.users["creator"], ac_role=verifier_role, object=asmnt, ) self.api.set_user(self.users["creator"]) response = self.api.client.get(link.format("Assessment", asmnt_id)) self.assert200(response) self.assertEqual( len( response.json.get("revisions_collection", {}).get("revisions")), revision_count) @ddt.data(all_models.ControlCategory, all_models.ControlAssertion) def test_permissions_for_categories(self, category_model): """Test get collection for {0}.""" self.api.set_user(self.users["creator"]) resp = self.api.get_collection(category_model, None) plural_name = category_model._inflector.table_plural key_name = "{}_collection".format(plural_name) self.assertIn(key_name, resp.json) self.assertIn(plural_name, resp.json[key_name]) collection = resp.json[key_name][plural_name] self.assertTrue(collection, "Collection shouldn't be empty")
class TestCreator(TestCase): """ TestCreator """ def setUp(self): super(TestCreator, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("creator", "Creator"), ("admin", "Administrator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): """Permissions to admin page.""" for role, code in (("creator", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_creator_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["creator"]) creator_id = self.users["creator"].id audit_id = factories.AuditFactory().id all_errors = [] base_models = set([ "Control", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Project", "AccessGroup", "Metric" ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post(model, { table_singular: { "title": model_singular, "context": None, "documents_reference_url": "ref", "link": "https://example.com", # ignored except for Document "contact": { "type": "Person", "id": creator_id, }, "audit": { # this is ignored on everything but Issues "id": audit_id, "type": "Audit", } }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue # Test GET when not owner obj_id = response.json.get(table_singular).get("id") response = self.api.get(model, obj_id) if response.status_code != 403: # we are not onwers yet all_errors.append( "{} can retrieve object if not owner".format(model_singular)) continue response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if collection: all_errors.append( "{} can retrieve object if not owner (collection)" .format(model_singular)) continue # Test GET when owner acr = all_models.AccessControlRole.query.filter_by( object_type=model_singular, name="Admin" ).first() factories.AccessControlListFactory( object_id=obj_id, object_type=model_singular, ac_role=acr, person_id=creator_id ) response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if not collection: all_errors.append( "{} cannot retrieve object even if owner (collection)" .format(model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_creator_search(self): """Test if creator can see the correct object while using the search api""" self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": {"title": "Admin regulation", "context": None}, }) self.api.set_user(self.users['creator']) acr_id = all_models.AccessControlRole.query.filter_by( object_type="Policy", name="Admin" ).first().id response = self.api.post(all_models.Policy, { "policy": { "title": "Creator Policy", "context": None, "access_control_list": [ acl_helper.get_acl_json(acr_id, self.users["creator"].id)], }, }) response.json.get("policy").get("id") response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 1) self.assertEqual(entries[0]["type"], "Policy") response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual( response.json["results"]["counts"].get("Regulation"), None) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_creator_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['creator']) creator_count = self._get_count("Person") self.assertEqual(admin_count, creator_count) def test_relationships_access(self): """Check if creator cannot access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation", "context": None}, }) _, obj_1 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation 2", "context": None}, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": {"source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None}, } ) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['creator']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 0) def test_revision_access(self): """Check if creator can access the right revision objects.""" def gen(title, extra_data=None): """Generates section.""" section_content = {"title": title, "context": None} if extra_data: section_content.update(**extra_data) return self.generator.generate(all_models.Section, "section", { "section": section_content })[1] def check(obj, expected): """Check that how many revisions of an object current user can see.""" response = self.api.get_query( all_models.Revision, "resource_type={}&resource_id={}".format(obj.type, obj.id) ) self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json['revisions_collection']['revisions']), expected ) self.api.set_user(self.users["admin"]) obj_1 = gen("Test Section 1") self.api.set_user(self.users["creator"]) acr_id = all_models.AccessControlRole.query.filter_by( object_type="Section", name="Admin" ).first().id linked_acl = { "access_control_list": [ acl_helper.get_acl_json(acr_id, self.users["creator"].id)], } check(obj_1, 0) obj_2 = gen("Test Section 2", linked_acl) obj2_acl = obj_2.access_control_list[0] check(obj_2, 1) check(obj2_acl, 1) @ddt.data("creator", "admin") def test_count_type_in_accordion(self, glob_role): """Return count of Persons in DB for side accordion.""" self.api.set_user(self.users[glob_role]) ocordion_api_person_count_link = ( "/search?" "q=&types=Program%2CWorkflow_All%2C" "Audit%2CAssessment%2CIssue%2CRegulation%2C" "Policy%2CStandard%2CContract%2CClause%2CSection%2CControl%2C" "Objective%2CPerson%2COrgGroup%2CVendor%2CAccessGroup%2CSystem%2C" "Process%2CDataAsset%2CProduct%2CProject%2CFacility%2C" "Market%2CRisk%2CThreat&counts_only=true&" "extra_columns=Workflow_All%3DWorkflow%2C" "Workflow_Active%3DWorkflow%2CWorkflow_Draft%3D" "Workflow%2CWorkflow_Inactive%3DWorkflow&contact_id=1&" "extra_params=Workflow%3Astatus%3DActive%3BWorkflow_Active" "%3Astatus%3DActive%3BWorkflow_Inactive%3Astatus%3D" "Inactive%3BWorkflow_Draft%3Astatus%3DDraft" ) resp = self.api.client.get(ocordion_api_person_count_link) self.assertIn("Person", resp.json["results"]["counts"]) self.assertEqual(all_models.Person.query.count(), resp.json["results"]["counts"]["Person"]) @ddt.data( ("/api/revisions?resource_type={}&resource_id={}", 1), ("/api/revisions?source_type={}&source_id={}", 0), ("/api/revisions?destination_type={}&destination_id={}", 1), ) @ddt.unpack def test_changelog_access(self, link, revision_count): """Test accessing changelog under GC user who is assigned to object""" with factories.single_commit(): audit = factories.AuditFactory() asmnt = factories.AssessmentFactory(audit=audit) asmnt_id = asmnt.id factories.RelationshipFactory(source=audit, destination=asmnt) verifier_role = all_models.AccessControlRole.query.filter_by( object_type="Assessment", name="Verifiers", ).first() factories.AccessControlListFactory( person=self.users["creator"], ac_role=verifier_role, object=asmnt, ) self.api.set_user(self.users["creator"]) response = self.api.client.get(link.format("Assessment", asmnt_id)) self.assert200(response) self.assertEqual( len(response.json.get("revisions_collection", {}).get("revisions")), revision_count ) @ddt.data(all_models.ControlCategory, all_models.ControlAssertion) def test_permissions_for_categories(self, category_model): """Test get collection for {0}.""" self.api.set_user(self.users["creator"]) resp = self.api.get_collection(category_model, None) plural_name = category_model._inflector.table_plural key_name = "{}_collection".format(plural_name) self.assertIn(key_name, resp.json) self.assertIn(plural_name, resp.json[key_name]) collection = resp.json[key_name][plural_name] self.assertTrue(collection, "Collection shouldn't be empty")
class TestReader(TestCase): """ Test reader role """ def setUp(self): super(TestReader, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("reader", "Reader"), ("admin", "Administrator"), ("creator", "Creator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): """Only admin can use admin section""" for role, code in (("reader", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_reader_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["reader"]) all_errors = [] base_models = set([ "Control", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Project", "AccessGroup", "Metric" ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post( model, { table_singular: { "title": model_singular, "context": None, "documents_reference_url": "ref", "link": "https://example.com", # ignored except for Document "contact": { "type": "Person", "id": self.users["reader"].id, }, }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue obj_id = response.json.get(table_singular).get("id") # Test GET when owner response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if not collection: all_errors.append( "{} cannot retrieve object even if owner (collection)". format(model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_reader_search(self): """ Test if reader can see the correct object while using search api """ self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": { "title": "Admin regulation", "context": None }, }) self.api.set_user(self.users['reader']) response = self.api.post(all_models.Policy, { "policy": { "title": "reader Policy", "context": None }, }) response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 2) response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual(response.json["results"]["counts"]["Regulation"], 1) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_reader_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['reader']) reader_count = self._get_count("Person") self.assertEqual(admin_count, reader_count) def test_relationships_access(self): """Check if reader can access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation", "context": None }, }) _, obj_1 = self.generator.generate( all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation 2", "context": None }, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": { "source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None }, }) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['reader']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 1) def test_creation_of_mappings(self): """Check if reader can't create mappings""" self.generator.api.set_user(self.users["admin"]) _, control = self.generator.generate(all_models.Control, "control", { "control": { "title": "Test Control", "context": None }, }) self.generator.api.set_user(self.users['reader']) _, program = self.generator.generate(all_models.Program, "program", { "program": { "title": "Test Program", "context": None }, }) response, _ = self.generator.generate( all_models.Relationship, "relationship", { "relationship": { "destination": { "id": program.id, "type": "Program" }, "source": { "id": control.id, "type": "Control" }, "context": { "id": program.context.id, "type": "context" } }, }) self.assertEqual(response.status_code, 403) @ddt.data("creator", "reader") def test_unmap_people(self, user_role): """Test that global reader/creator can't unmap people from program""" user = self.users[user_role] with factories.single_commit(): program = factories.ProgramFactory() mapped_person = factories.ObjectPersonFactory( personable=program, person=user, context=program.context) self.api.set_user(user) db.session.add(mapped_person) response = self.api.delete(mapped_person) self.assertEqual(response.status_code, 403) def test_read_evidence_revision(self): """Global Read can read Evidence revision content""" user = self.users["reader"] link = "google.com" evidence = factories.EvidenceUrlFactory(link=link) evidence_id = evidence.id self.api.set_user(user) resp = self.api.client.get( "/api/revisions?resource_type={}&resource_id={}".format( evidence.type, evidence_id)) rev_content = resp.json["revisions_collection"]["revisions"][0][ "content"] self.assertTrue(rev_content) self.assertEquals(link, rev_content["link"])
class TestReader(TestCase): """ Test reader role """ def setUp(self): super(TestReader, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("reader", "Reader"), ("admin", "Administrator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): for role, code in (("reader", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_reader_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["reader"]) all_errors = [] base_models = set([ "Control", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Project", "AccessGroup", ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post( model, { table_singular: { "title": model_singular, "context": None, "reference_url": "ref", "contact": { "type": "Person", "id": self.users["reader"].id, }, }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue obj_id = response.json.get(table_singular).get("id") # Test GET when owner response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if len(collection) == 0: all_errors.append( "{} cannot retrieve object even if owner (collection)". format(model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_reader_search(self): """ Test if reader can see the correct object while using search api """ self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": { "title": "Admin regulation", "context": None }, }) self.api.set_user(self.users['reader']) response = self.api.post(all_models.Policy, { "policy": { "title": "reader Policy", "context": None }, }) response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 2) response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual(response.json["results"]["counts"]["Regulation"], 1) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_reader_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['reader']) reader_count = self._get_count("Person") self.assertEqual(admin_count, reader_count) def test_relationships_access(self): """Check if reader can access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation", "context": None }, }) _, obj_1 = self.generator.generate( all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation 2", "context": None }, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": { "source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None }, }) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['reader']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 1) def test_creation_of_mappings(self): """Check if reader can't create mappings""" self.generator.api.set_user(self.users["admin"]) _, control = self.generator.generate(all_models.Control, "control", { "control": { "title": "Test Control", "context": None }, }) self.generator.api.set_user(self.users['reader']) _, program = self.generator.generate(all_models.Program, "program", { "program": { "title": "Test Program", "context": None }, }) response, _ = self.generator.generate( all_models.Relationship, "relationship", { "relationship": { "destination": { "id": program.id, "type": "Program" }, "source": { "id": control.id, "type": "Control" }, "context": { "id": program.context.id, "type": "context" } }, }) self.assertEqual(response.status_code, 403)
class TestCreator(TestCase): """ TestCreator """ def setUp(self): super(TestCreator, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("creator", "Creator"), ("admin", "Administrator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): for role, code in (("creator", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_creator_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["creator"]) audit_id = factories.AuditFactory().id all_errors = [] base_models = set([ "Control", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Project", "AccessGroup" ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post(model, { table_singular: { "title": model_singular, "context": None, "reference_url": "ref", "contact": { "type": "Person", "id": self.users["creator"].id, }, "audit": { # this is ignored on everything but Issues "id": audit_id, "type": "Audit", } }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue # Test GET when not owner obj_id = response.json.get(table_singular).get("id") response = self.api.get(model, obj_id) if response.status_code != 403: # we are not onwers yet all_errors.append( "{} can retrieve object if not owner".format(model_singular)) continue response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if len(collection) != 0: all_errors.append( "{} can retrieve object if not owner (collection)" .format(model_singular)) continue # Become an owner response = self.api.post(all_models.ObjectOwner, {"object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": model_singular, "id": obj_id }, "context": None}}) if response.status_code != 201: all_errors.append("{} can't create owner {}.".format( model_singular, response.status)) continue # Test GET when owner response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if len(collection) == 0: all_errors.append( "{} cannot retrieve object even if owner (collection)" .format(model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_creator_search(self): """Test if creator can see the correct object while using the search api""" self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": {"title": "Admin regulation", "context": None}, }) self.api.set_user(self.users['creator']) response = self.api.post(all_models.Policy, { "policy": {"title": "Creator Policy", "context": None}, }) obj_id = response.json.get("policy").get("id") self.api.post(all_models.ObjectOwner, {"object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": "Policy", "id": obj_id, }, "context": None}}) response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 1) self.assertEqual(entries[0]["type"], "Policy") response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual( response.json["results"]["counts"].get("Regulation"), None) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_creator_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['creator']) creator_count = self._get_count("Person") self.assertEqual(admin_count, creator_count) def test_creator_cannot_be_owner(self): """Test if creator cannot become owner of the object he has not created""" self.api.set_user(self.users['admin']) _, obj = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation", "context": None}, }) self.api.set_user(self.users['creator']) response = self.api.post(all_models.ObjectOwner, {"object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": "Regulation", "id": obj.id, }, "context": None}}) self.assertEqual(response.status_code, 403) def test_relationships_access(self): """Check if creator cannot access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation", "context": None}, }) _, obj_1 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation 2", "context": None}, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": {"source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None}, } ) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['creator']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 0) def test_revision_access(self): """Check if creator can access the right revision objects.""" def gen(title): return self.generator.generate(all_models.Section, "section", { "section": {"title": title, "context": None}, })[1] def check(obj, expected): """Check that how many revisions of an object current user can see.""" response = self.api.get_query( all_models.Revision, "resource_type={}&resource_id={}".format(obj.type, obj.id) ) self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json['revisions_collection']['revisions']), expected ) self.api.set_user(self.users["admin"]) obj_1 = gen("Test Section 1") obj_2 = gen("Test Section 2") self.api.post(all_models.ObjectOwner, {"object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": "Section", "id": obj_2.id, }, "context": None}}) self.api.set_user(self.users["creator"]) check(obj_1, 0) check(obj_2, 2)
class TestMultipleTypes(TestCase): """ Test /search REST API """ def setUp(self): """Create indexable objects which provide required set of fulltext attrs Fulltext attributes are: title, name, email, notes, description, slug """ super(TestMultipleTypes, self).setUp() self.api = Api() self.objects = dict() with factories.single_commit(): # Create Requirements requirements = [factories.RequirementFactory(title=title, description=desc, notes=notes) for title, desc, notes in (('t01', 'd01', 'n01'), ('t02', 'd02', 'n02'), ('t11', 'd11', 'n11'), )] self.objects['Requirement'] = dict((i.title, i.id) for i in requirements) # Create people people = [factories.PersonFactory(name=name, email=email) for name, email in (('n01', '*****@*****.**'), ('n02', '*****@*****.**'), ('n11', '*****@*****.**'), )] self.objects['Person'] = dict((i.name, i.id) for i in people) # Create regulations (regulations represented as directives) regulations = [factories.RegulationFactory(title=title, notes=notes, description=desc) for title, notes, desc in (('t01r', 'n01', 'd01'), ('t02r', 'n02-qq1', 'd02'), ('t11r', 'n11', 'd11'), )] self.objects['Regulation'] = dict((i.title, i.id) for i in regulations) # Create standards (standards represented as directives) standards = [factories.StandardFactory(title=title, notes=notes, description=desc) for title, notes, desc in (('t01s', 'n01-qq1', 'd01'), ('t02s', 'n02', 'd02'), ('t11s', 'n11', 'd11'), ('t21s', 'n21', 'd11'), )] self.objects['Standard'] = dict((i.title, i.id) for i in standards) def _get_search_ids(self, types, query, extra_params): """Make request and return entries in format dict(type->list_of_ids)""" response, _ = self.api.search(types=types, query=query, counts=False, extra_params=extra_params) entries = response.json['results']['entries'] ret = defaultdict(set) for entry in entries: ret[entry['type']].add(entry['id']) return dict(ret) def _get_count_ids(self, types, query, extra_params, extra_columns=None): """Make request and return entries in format dict(type->number_of_ids)""" response, _ = self.api.search(types=types, query=query, counts=True, extra_params=extra_params, extra_columns=extra_columns) return response.json['results']['counts'] def _convert_expected_to_dict(self, expected): """Convert list of (type, title) to dict (type -> list_of_ids)""" ret = defaultdict(set) for type_, key in expected: ret[type_].add(self.objects[type_][key]) return dict(ret) @staticmethod # pylint: disable=invalid-name def _convert_expected_dict_to_counts(expected): """Convert dict(type->list_of_ids) to dict(type->count_of_ids)""" return dict((k, len(v)) for k, v in expected.iteritems()) @ddt.data( # search for Requirements by title ("Requirement", "t0", None, (('Requirement', 't01'), ('Requirement', 't02'), )), # search for Requirements by description ("Requirement", "d1", None, (('Requirement', 't11'), )), # search for Requirements by slug ("Requirement", "REQUIREMENT", None, (('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search for people by name ("Person", "n0", None, (('Person', 'n01'), ('Person', 'n02'), )), # search for people by email ("Person", "e1", None, (('Person', 'n11'), )), # search for regulations by notes ("Regulation", "n0", None, (('Regulation', 't01r'), ('Regulation', 't02r'), )), # search for regulations by title ("Regulation", "t1", None, (('Regulation', 't11r'), )), # search for Requirements and Reguklations by title ("Requirement,Regulation", "t0", None, (('Requirement', 't01'), ('Requirement', 't02'), ('Regulation', 't01r'), ('Regulation', 't02r'), )), # search for subtypes of the same base type # Regulation and Standard are both represented as Directive model ("Regulation,Standard", "-qq1", None, (('Regulation', 't02r'), ('Standard', 't01s'), )), # search with empty types ("", "", None, ()), # search with non-existing type ("qwe", "", None, ()), # search for 2 types, one does not exist ("Requirement,qwe", "t0", None, (('Requirement', 't01'), ('Requirement', 't02'), )), # search for empty text ("Requirement", "", None, (('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search for added empty extra_params ("Requirement", "", "", (('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search by title using extra_params ("Requirement", "", "Requirement:title=t01", (('Requirement', 't01'), )), # search by title using extra_params where model name is lowercase ("Requirement", "", "requirement:title=t01", (('Requirement', 't01'), )), # search by title using extra_params where model name is lowercase ("Regulation", "", "Requirement:title=t01", (('Regulation', 't01r'), ('Regulation', 't02r'), ('Regulation', 't11r'), )), # search nonexisting type by title using extra_params ("Requirement", "", "qwe:title=t01", (('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search in multiple models, one by title using extra_params # filter uses AND operation to search indexed fields and extra_params # for single model. # There is no such Requirement where indexed fields contain "d0" and # title is "t01", so only regulations will be returned where indexed # fields contain "n0" ("Requirement,Regulation", "d0", "Requirement:title=t11", (('Regulation', 't01r'), ('Regulation', 't02r'), )), # search for subtypes of the same base type based on extra_params # Regulation and Standard are both represented as Directive model # ensure that extra_params for Regulation will not return Standard # with the same notes ("Regulation,Standard", "-qq1", "Regulation:description=d02", (('Regulation', 't02r'), # contains "-qq1" and description = "d02" ('Standard', 't01s'), # contains "-qq1" )), ) @ddt.unpack def test_search(self, types, query, extra_params, expected): """Test search of objects for types={0}, q={1}, extra_params={2}""" exp_search = self._convert_expected_to_dict(expected) response_search = self._get_search_ids(types, query, extra_params) self.assertEqual(response_search, exp_search) exp_count = self._convert_expected_dict_to_counts(exp_search) response_count = self._get_count_ids(types, query, extra_params) self.assertEqual(response_count, exp_count) @ddt.data( ("Standard", "", "Standard:title=t01s;SS:description=d11", "SS=Standard", { "Standard": 1, "SS": 2 }), # Add "Standard_ALL" column for which extra_params is not defined ("Standard", "", "SS:description=d11", "SS=Standard,Standard_All=Standard", { "SS": 2, "Standard_All": 4 }), # types can contain column name from extra_columns # ensure that it is also handled correctly ("Standard_All", "", "SS:description=d11", "SS=Standard,Standard_All=Standard", { "Standard_All": 4, "SS": 2 }), ) @ddt.unpack # pylint: disable=too-many-arguments def test_count_with_extra_coloumns(self, types, query, extra_params, extra_columns, expected): """Test extra_columns types={0}, q={1}, extra_params={2}, extra_columns={3} """ response_count = self._get_count_ids(types, query, extra_params, extra_columns) self.assertEqual(response_count, expected)
class TestReader(TestCase): """ Test reader role """ def setUp(self): super(TestReader, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("reader", "Reader"), ("admin", "Administrator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): return for role, code in (("reader", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_reader_can_crud(self): return """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["reader"]) all_errors = [] base_models = set([ "Control", "Assessment", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Issue", "Project", "AccessGroup", ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post(model, { table_singular: { "title": model_singular, "context": None, "reference_url": "ref", "contact": { "type": "Person", "id": self.users["reader"].id, }, }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue obj_id = response.json.get(table_singular).get("id") # Test GET when owner response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if len(collection) == 0: all_errors.append( "{} cannot retrieve object even if owner (collection)".format( model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_reader_search(self): return """ Test if reader can see the correct object while using search api """ self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": {"title": "Admin regulation", "context": None}, }) self.api.set_user(self.users['reader']) response = self.api.post(all_models.Policy, { "policy": {"title": "reader Policy", "context": None}, }) obj_id = response.json.get("policy").get("id") self.api.post(all_models.ObjectOwner, {"object_owner": { "person": { "id": self.users['reader'].id, "type": "Person", }, "ownable": { "type": "Policy", "id": obj_id, }, "context": None}}) response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 2) response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual(response.json["results"]["counts"]["Regulation"], 1) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_reader_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['reader']) reader_count = self._get_count("Person") self.assertEqual(admin_count, reader_count) def test_relationships_access(self): """Check if reader can access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation", "context": None}, }) _, obj_1 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": {"title": "Test regulation 2", "context": None}, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": {"source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None}, } ) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['reader']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 1) def test_creation_of_mappings(self): self.generator.api.set_user(self.users["admin"]) _, control = self.generator.generate(all_models.Control, "control", { "control": {"title": "Test Control", "context": None}, }) self.generator.api.set_user(self.users['reader']) _, program = self.generator.generate(all_models.Program, "program", { "program": {"title": "Test Program", "context": None}, }) response, _ = self.generator.generate( all_models.Relationship, "relationship", { "relationship": {"destination": { "id": program.id, "type": "Program" }, "source": { "id": control.id, "type": "Control" }, "context": { "id": program.context.id, "type": "context" }}, }) self.assertEqual(response.status_code, 403)
class TestMultipleTypes(TestCase): """ Test /search REST API """ def setUp(self): """Create indexable objects which provide required set of fulltext attrs Fulltext attributes are: title, name, email, notes, description, slug """ super(TestMultipleTypes, self).setUp() self.api = Api() self.objects = dict() with factories.single_commit(): # Create Requirements requirements = [ factories.RequirementFactory(title=title, description=desc, notes=notes) for title, desc, notes in ( ('t01', 'd01', 'n01'), ('t02', 'd02', 'n02'), ('t11', 'd11', 'n11'), ) ] self.objects['Requirement'] = dict( (i.title, i.id) for i in requirements) # Create people people = [ factories.PersonFactory(name=name, email=email) for name, email in ( ('n01', '*****@*****.**'), ('n02', '*****@*****.**'), ('n11', '*****@*****.**'), ) ] self.objects['Person'] = dict((i.name, i.id) for i in people) # Create regulations (regulations represented as directives) regulations = [ factories.RegulationFactory(title=title, notes=notes, description=desc) for title, notes, desc in ( ('t01r', 'n01', 'd01'), ('t02r', 'n02-qq1', 'd02'), ('t11r', 'n11', 'd11'), ) ] self.objects['Regulation'] = dict( (i.title, i.id) for i in regulations) # Create standards (standards represented as directives) standards = [ factories.StandardFactory(title=title, notes=notes, description=desc) for title, notes, desc in ( ('t01s', 'n01-qq1', 'd01'), ('t02s', 'n02', 'd02'), ('t11s', 'n11', 'd11'), ('t21s', 'n21', 'd11'), ) ] self.objects['Standard'] = dict((i.title, i.id) for i in standards) def _get_search_ids(self, types, query, extra_params): """Make request and return entries in format dict(type->list_of_ids)""" response, _ = self.api.search(types=types, query=query, counts=False, extra_params=extra_params) entries = response.json['results']['entries'] ret = defaultdict(set) for entry in entries: ret[entry['type']].add(entry['id']) return dict(ret) def _get_count_ids(self, types, query, extra_params, extra_columns=None): """Make request and return entries in format dict(type->number_of_ids)""" response, _ = self.api.search(types=types, query=query, counts=True, extra_params=extra_params, extra_columns=extra_columns) return response.json['results']['counts'] def _convert_expected_to_dict(self, expected): """Convert list of (type, title) to dict (type -> list_of_ids)""" ret = defaultdict(set) for type_, key in expected: ret[type_].add(self.objects[type_][key]) return dict(ret) @staticmethod # pylint: disable=invalid-name def _convert_expected_dict_to_counts(expected): """Convert dict(type->list_of_ids) to dict(type->count_of_ids)""" return dict((k, len(v)) for k, v in expected.iteritems()) @ddt.data( # search for Requirements by title ("Requirement", "t0", None, ( ('Requirement', 't01'), ('Requirement', 't02'), )), # search for Requirements by description ("Requirement", "d1", None, (('Requirement', 't11'), )), # search for Requirements by slug ("Requirement", "REQUIREMENT", None, ( ('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search for people by name ("Person", "n0", None, ( ('Person', 'n01'), ('Person', 'n02'), )), # search for people by email ("Person", "e1", None, (('Person', 'n11'), )), # search for regulations by notes ("Regulation", "n0", None, ( ('Regulation', 't01r'), ('Regulation', 't02r'), )), # search for regulations by title ("Regulation", "t1", None, (('Regulation', 't11r'), )), # search for Requirements and Reguklations by title ("Requirement,Regulation", "t0", None, ( ('Requirement', 't01'), ('Requirement', 't02'), ('Regulation', 't01r'), ('Regulation', 't02r'), )), # search for subtypes of the same base type # Regulation and Standard are both represented as Directive model ("Regulation,Standard", "-qq1", None, ( ('Regulation', 't02r'), ('Standard', 't01s'), )), # search with empty types ("", "", None, ()), # search with non-existing type ("qwe", "", None, ()), # search for 2 types, one does not exist ("Requirement,qwe", "t0", None, ( ('Requirement', 't01'), ('Requirement', 't02'), )), # search for empty text ("Requirement", "", None, ( ('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search for added empty extra_params ("Requirement", "", "", ( ('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search by title using extra_params ("Requirement", "", "Requirement:title=t01", (('Requirement', 't01'), )), # search by title using extra_params where model name is lowercase ("Requirement", "", "requirement:title=t01", (('Requirement', 't01'), )), # search by title using extra_params where model name is lowercase ("Regulation", "", "Requirement:title=t01", ( ('Regulation', 't01r'), ('Regulation', 't02r'), ('Regulation', 't11r'), )), # search nonexisting type by title using extra_params ("Requirement", "", "qwe:title=t01", ( ('Requirement', 't01'), ('Requirement', 't02'), ('Requirement', 't11'), )), # search in multiple models, one by title using extra_params # filter uses AND operation to search indexed fields and extra_params # for single model. # There is no such Requirement where indexed fields contain "d0" and # title is "t01", so only regulations will be returned where indexed # fields contain "n0" ("Requirement,Regulation", "d0", "Requirement:title=t11", ( ('Regulation', 't01r'), ('Regulation', 't02r'), )), # search for subtypes of the same base type based on extra_params # Regulation and Standard are both represented as Directive model # ensure that extra_params for Regulation will not return Standard # with the same notes ( "Regulation,Standard", "-qq1", "Regulation:description=d02", ( ('Regulation', 't02r'), # contains "-qq1" and description = "d02" ('Standard', 't01s'), # contains "-qq1" )), ) @ddt.unpack def test_search(self, types, query, extra_params, expected): """Test search of objects for types={0}, q={1}, extra_params={2}""" exp_search = self._convert_expected_to_dict(expected) response_search = self._get_search_ids(types, query, extra_params) self.assertEqual(response_search, exp_search) exp_count = self._convert_expected_dict_to_counts(exp_search) response_count = self._get_count_ids(types, query, extra_params) self.assertEqual(response_count, exp_count) @ddt.data( ("Standard", "", "Standard:title=t01s;SS:description=d11", "SS=Standard", { "Standard": 1, "SS": 2 }), # Add "Standard_ALL" column for which extra_params is not defined ("Standard", "", "SS:description=d11", "SS=Standard,Standard_All=Standard", { "SS": 2, "Standard_All": 4 }), # types can contain column name from extra_columns # ensure that it is also handled correctly ("Standard_All", "", "SS:description=d11", "SS=Standard,Standard_All=Standard", { "Standard_All": 4, "SS": 2 }), ) @ddt.unpack # pylint: disable=too-many-arguments def test_count_with_extra_coloumns(self, types, query, extra_params, extra_columns, expected): """Test extra_columns types={0}, q={1}, extra_params={2}, extra_columns={3} """ response_count = self._get_count_ids(types, query, extra_params, extra_columns) self.assertEqual(response_count, expected)
class TestCreator(TestCase): """ TestCreator """ def setUp(self): super(TestCreator, self).setUp() self.generator = Generator() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("creator", "Creator"), ("admin", "Administrator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user def test_admin_page_access(self): for role, code in (("creator", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.tc.get("/admin").status_code, code) def test_creator_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["creator"]) all_errors = [] base_models = set([ "Control", "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "Clause", "System", "Process", "Issue", "Project", "AccessGroup" ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response = self.api.post( model, { table_singular: { "title": model_singular, "context": None, "reference_url": "ref", "contact": { "type": "Person", "id": self.users["creator"].id, }, }, }) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue # Test GET when not owner obj_id = response.json.get(table_singular).get("id") response = self.api.get(model, obj_id) if response.status_code != 403: # we are not onwers yet all_errors.append( "{} can retrieve object if not owner".format( model_singular)) continue response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if len(collection) != 0: all_errors.append( "{} can retrieve object if not owner (collection)". format(model_singular)) continue # Become an owner response = self.api.post( all_models.ObjectOwner, { "object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": model_singular, "id": obj_id }, "context": None } }) if response.status_code != 201: all_errors.append("{} can't create owner {}.".format( model_singular, response.status)) continue # Test GET when owner response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if len(collection) == 0: all_errors.append( "{} cannot retrieve object even if owner (collection)". format(model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_creator_search(self): """Test if creator can see the correct object while using the search api""" self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": { "title": "Admin regulation", "context": None }, }) self.api.set_user(self.users['creator']) response = self.api.post(all_models.Policy, { "policy": { "title": "Creator Policy", "context": None }, }) obj_id = response.json.get("policy").get("id") self.api.post( all_models.ObjectOwner, { "object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": "Policy", "id": obj_id, }, "context": None } }) response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 1) self.assertEqual(entries[0]["type"], "Policy") response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual(response.json["results"]["counts"].get("Regulation"), None) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_creator_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['creator']) creator_count = self._get_count("Person") self.assertEqual(admin_count, creator_count) def test_creator_cannot_be_owner(self): """Test if creator cannot become owner of the object he has not created""" self.api.set_user(self.users['admin']) _, obj = self.generator.generate(all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation", "context": None }, }) self.api.set_user(self.users['creator']) response = self.api.post( all_models.ObjectOwner, { "object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": "Regulation", "id": obj.id, }, "context": None } }) self.assertEqual(response.status_code, 403) def test_relationships_access(self): """Check if creator cannot access relationship objects""" self.api.set_user(self.users['admin']) _, obj_0 = self.generator.generate(all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation", "context": None }, }) _, obj_1 = self.generator.generate( all_models.Regulation, "regulation", { "regulation": { "title": "Test regulation 2", "context": None }, }) response, rel = self.generator.generate( all_models.Relationship, "relationship", { "relationship": { "source": { "id": obj_0.id, "type": "Regulation" }, "destination": { "id": obj_1.id, "type": "Regulation" }, "context": None }, }) relationship_id = rel.id self.assertEqual(response.status_code, 201) self.api.set_user(self.users['creator']) response = self.api.get_collection(all_models.Relationship, relationship_id) self.assertEqual(response.status_code, 200) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 0) def test_revision_access(self): """Check if creator can access the right revision objects.""" def gen(title): return self.generator.generate(all_models.Section, "section", { "section": { "title": title, "context": None }, })[1] def check(obj, expected): """Check that how many revisions of an object current user can see.""" response = self.api.get_query( all_models.Revision, "resource_type={}&resource_id={}".format(obj.type, obj.id)) self.assertEqual(response.status_code, 200) self.assertEqual( len(response.json['revisions_collection']['revisions']), expected) self.api.set_user(self.users["admin"]) obj_1 = gen("Test Section 1") obj_2 = gen("Test Section 2") self.api.post( all_models.ObjectOwner, { "object_owner": { "person": { "id": self.users['creator'].id, "type": "Person", }, "ownable": { "type": "Section", "id": obj_2.id, }, "context": None } }) self.api.set_user(self.users["creator"]) check(obj_1, 0) check(obj_2, 2)
class TestResource(TestCase): """ Test /search REST API """ def setUp(self): super(TestResource, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.create_objects() def create_objects(self): """Create objects to be searched. Creates five controls and makes relationships. 0 1 2 3 4 |---| |---| | |-------|-------| """ self.objects = [ self.object_generator.generate_object(Control)[1].id for _ in xrange(5) ] self.objects = Control.eager_query().filter( Control.id.in_(self.objects)).all() for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]: self.object_generator.generate_relationship( self.objects[src], self.objects[dst]) def search(self, *args, **kwargs): res, _ = self.api.search(*args, **kwargs) return res.json["results"]["entries"] def test_search_all(self): """Test search for all objects of a type.""" res, _ = self.api.search("Control") self.assertEqual(len(res.json["results"]["entries"]), 5) def test_search_query(self): """Test search with query by title.""" entries = self.search("Control", query=self.objects[0].title) self.assertEqual({entry["id"] for entry in entries}, {self.objects[0].id}) def test_search_relevant(self): """Test search with 'relevant to' single object.""" relevant_objects = "Control:{}".format(self.objects[0].id) entries = self.search("Control", relevant_objects=relevant_objects) self.assertEqual({entry["id"] for entry in entries}, {self.objects[i].id for i in [1, 2]}) def test_search_relevant_multi(self): """Test search with 'relevant to' multiple objects.""" ids = ",".join("Control:{}".format(self.objects[i].id) for i in (0, 3)) entries = self.search("Control", relevant_objects=ids) self.assertEqual({entry["id"] for entry in entries}, {self.objects[2].id}) def test_search_fail_with_terms_none(self): """Test search to fail with BadRequest (400 Error) when terms are None.""" query = '/search?types={}&counts_only={}'.format("Control", False) response = self.api.client.get(query) self.assert400(response) self.assertEqual( response.json['message'], 'Query parameter "q" ' 'specifying search terms must be provided.')
class TestReader(TestCase): """ Test reader role """ def setUp(self): super(TestReader, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.init_users() def init_users(self): """ Init users needed by the test cases """ users = [("reader", "Reader"), ("admin", "Administrator"), ("creator", "Creator")] self.users = {} for (name, role) in users: _, user = self.object_generator.generate_person( data={"name": name}, user_role=role) self.users[name] = user self.users["external"] = self.object_generator.generate_person( data={"email": "*****@*****.**"})[1] def test_admin_page_access(self): """Only admin can use admin requirement""" for role, code in (("reader", 403), ("admin", 200)): self.api.set_user(self.users[role]) self.assertEqual(self.api.client.get("/admin").status_code, code) def test_reader_can_crud(self): """ Test Basic create/read,update/delete operations """ self.api.set_user(self.users["reader"]) all_errors = [] base_models = set([ "DataAsset", "Contract", "Policy", "Regulation", "Standard", "Document", "Facility", "Market", "Objective", "OrgGroup", "Vendor", "Product", "System", "Process", "Project", "AccessGroup", "Metric", "TechnologyEnvironment", "ProductGroup", "KeyReport", "AccountBalance", ]) for model_singular in base_models: try: model = get_model(model_singular) table_singular = model._inflector.table_singular table_plural = model._inflector.table_plural # Test POST creation response, _ = self.object_generator.generate_object( model, data={ table_singular: { "title": model_singular, "context": None, "documents_reference_url": "ref", "link": "https://example.com", # only for Document "contact": { "type": "Person", "id": self.users["reader"].id, } }, } ) if response.status_code != 201: all_errors.append("{} post creation failed {} {}".format( model_singular, response.status, response.data)) continue obj_id = response.json.get(table_singular).get("id") # Test GET when owner response = self.api.get(model, obj_id) if response.status_code != 200: all_errors.append("{} can't GET object {}".format( model_singular, response.status)) continue # Test GET collection when owner response = self.api.get_collection(model, obj_id) collection = response.json.get( "{}_collection".format(table_plural)).get(table_plural) if not collection: all_errors.append( "{} cannot retrieve object even if owner (collection)".format( model_singular)) continue except: all_errors.append("{} exception thrown".format(model_singular)) raise self.assertEqual(all_errors, []) def test_reader_search(self): """ Test if reader can see the correct object while using search api """ self.api.set_user(self.users['admin']) self.api.post(all_models.Regulation, { "regulation": {"title": "Admin regulation", "context": None}, }) self.api.set_user(self.users['reader']) response = self.api.post(all_models.Policy, { "policy": {"title": "reader Policy", "context": None}, }) response, _ = self.api.search("Regulation,Policy") entries = response.json["results"]["entries"] self.assertEqual(len(entries), 2) response, _ = self.api.search("Regulation,Policy", counts=True) self.assertEqual(response.json["results"]["counts"]["Policy"], 1) self.assertEqual(response.json["results"]["counts"]["Regulation"], 1) def _get_count(self, obj): """ Return the number of counts for the given object from search """ response, _ = self.api.search(obj, counts=True) return response.json["results"]["counts"].get(obj) def test_reader_should_see_users(self): """ Test if creator can see all the users in the system """ self.api.set_user(self.users['admin']) admin_count = self._get_count("Person") self.api.set_user(self.users['reader']) reader_count = self._get_count("Person") self.assertEqual(admin_count, reader_count) def test_relationships_access(self): """Check if reader can access relationship objects""" self.api.set_user(self.users['admin']) _, first_regulation = self.object_generator.generate_object( all_models.Regulation, data={"regulation": {"title": "Test regulation", "context": None}} ) _, second_regulation = self.object_generator.generate_object( all_models.Regulation, data={"regulation": {"title": "Test regulation 2", "context": None}} ) response, rel = self.object_generator.generate_relationship( first_regulation, second_regulation ) self.assertStatus(response, 201) self.api.set_user(self.users['reader']) response = self.api.get_collection(all_models.Relationship, rel.id) self.assert200(response) num = len(response.json["relationships_collection"]["relationships"]) self.assertEqual(num, 1) def test_creation_of_mappings(self): """Check if reader can't create mappings""" self.object_generator.api.set_user(self.users["external"]) _, control = self.object_generator.generate_object( all_models.Control, data={"control": {"title": "Test Control", "context": None}} ) self.object_generator.api.set_user(self.users['reader']) _, program = self.object_generator.generate_object( all_models.Program, data={"program": {"title": "Test Program", "context": None}} ) response, _ = self.object_generator.generate_relationship( control, program, program.context ) self.assert403(response) @ddt.data("creator", "reader") def test_unmap_people(self, user_role): """Test that global reader/creator can't unmap people from program""" user = self.users[user_role] with factories.single_commit(): program = factories.ProgramFactory() mapped_person = factories.ObjectPersonFactory( personable=program, person=user, context=program.context ) self.api.set_user(user) db.session.add(mapped_person) response = self.api.delete(mapped_person) self.assert403(response) def test_read_evidence_revision(self): """Global Read can read Evidence revision content""" user = self.users["reader"] link = "google.com" evidence = factories.EvidenceUrlFactory(link=link) evidence_id = evidence.id self.api.set_user(user) resp = self.api.client.get( "/api/revisions?resource_type={}&resource_id={}".format(evidence.type, evidence_id)) rev_content = resp.json["revisions_collection"]["revisions"][0]["content"] self.assertTrue(rev_content) self.assertEquals(link, rev_content["link"])
class TestResource(TestCase): """ Test /search REST API """ def setUp(self): super(TestResource, self).setUp() self.api = Api() self.object_generator = ObjectGenerator() self.create_objects() def create_objects(self): """Create objects to be searched. Creates five controls and makes relationships. 0 1 2 3 4 |---| |---| | |-------|-------| """ self.objects = [ self.object_generator.generate_object(Control)[1].id for _ in xrange(5) ] self.objects = Control.eager_query().filter( Control.id.in_(self.objects) ).all() for src, dst in [(0, 1), (0, 2), (2, 3), (2, 4)]: self.object_generator.generate_relationship( self.objects[src], self.objects[dst] ) def search(self, *args, **kwargs): res, _ = self.api.search(*args, **kwargs) return res.json["results"]["entries"] def test_search_all(self): """Test search for all objects of a type.""" res, _ = self.api.search("Control") self.assertEqual(len(res.json["results"]["entries"]), 5) def test_search_query(self): """Test search with query by title.""" entries = self.search("Control", query=self.objects[0].title) self.assertEqual({entry["id"] for entry in entries}, {self.objects[0].id}) def test_search_relevant(self): """Test search with 'relevant to' single object.""" relevant_objects = "Control:{}".format(self.objects[0].id) entries = self.search("Control", relevant_objects=relevant_objects) self.assertEqual({entry["id"] for entry in entries}, {self.objects[i].id for i in [1, 2]}) def test_search_relevant_multi(self): """Test search with 'relevant to' multiple objects.""" ids = ",".join("Control:{}".format(self.objects[i].id) for i in (0, 3)) entries = self.search("Control", relevant_objects=ids) self.assertEqual({entry["id"] for entry in entries}, {self.objects[2].id}) def test_search_fail_with_terms_none(self): """Test search to fail with BadRequest (400 Error) when terms are None.""" query = '/search?types={}&counts_only={}'.format("Control", False) response = self.api.client.get(query) self.assert400(response) self.assertEqual(response.json['message'], 'Query parameter "q" ' 'specifying search terms must be provided.')