def test_add_rule_to_policy(mock): # Should raise an exception if the rule does not exist rule_uri = 'https://example.com#nonexistant' policy_uri = 'https://example.com#policy' db_access.create_policy(policy_uri) with pytest.raises(ValueError): db_access.add_rule_to_policy(rule_uri, policy_uri) # Should raise an exception if the policy does not exist rule_uri = 'https://example.com#rule' rule_type = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' db_access.create_rule(rule_uri, rule_type, rule_label) db_access.delete_policy(policy_uri) with pytest.raises(ValueError): db_access.add_rule_to_policy(rule_uri, policy_uri) # Should add a rule to a policy db_access.create_policy(policy_uri) db_access.add_rule_to_policy(rule_uri, policy_uri) query_str = 'SELECT COUNT(1) FROM POLICY_HAS_RULE WHERE RULE_URI = ? AND POLICY_URI = ?' rule_assigned = db_access.query_db(query_str, (rule_uri, policy_uri), one=True)[0] assert rule_assigned # Should raise an exception if the rule is already included in the policy with pytest.raises(ValueError): db_access.add_rule_to_policy(rule_uri, policy_uri)
def test_get_policy(mock): # Should raise an exception when the policy doesn't exist policy_uri = 'https://example.com#policy' with pytest.raises(ValueError): db_access.get_policy(policy_uri) # Should get all the attributes of the policy db_access.create_policy(policy_uri) policy_type = 'http://creativecommons.org/ns#License' db_access.set_policy_attribute(policy_uri, 'TYPE', policy_type) rule_uri = 'http://example.com#rule' rule_type_uri = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' db_access.create_rule(rule_uri, rule_type_uri, rule_label) db_access.add_rule_to_policy(rule_uri, policy_uri) policy = db_access.get_policy(policy_uri) expected_policy_attributes = [ 'URI', 'TYPE', 'LABEL', 'JURISDICTION', 'LEGAL_CODE', 'HAS_VERSION', 'LANGUAGE', 'SEE_ALSO', 'SAME_AS', 'COMMENT', 'LOGO', 'CREATED', 'STATUS', 'RULES' ] assert all(attr in policy for attr in expected_policy_attributes) assert policy['URI'] == policy_uri assert policy['TYPE'] == policy_type assert policy['RULES'] == [rule_uri]
def test_delete_rule(mock): # Should not be able to delete if the rule is still used in any policies policy_uri = 'https://example.com#policy' db_access.create_policy(policy_uri) rule_uri = 'http://example.com#rule' rule_type = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' db_access.create_rule(rule_uri, rule_type, rule_label) assignor_uri = 'http://example.com#assignor' db_access.create_party(assignor_uri) db_access.add_assignor_to_rule(assignor_uri, rule_uri) assignee_uri = 'http://example.com#assignee' db_access.create_party(assignee_uri) db_access.add_assignee_to_rule(assignee_uri, rule_uri) action_uri = 'http://www.w3.org/ns/odrl/2/distribute' db_access.add_action_to_rule(action_uri, rule_uri) db_access.add_rule_to_policy(rule_uri, policy_uri) with pytest.raises(ValueError): db_access.delete_rule(rule_uri) # Should delete the rule db_access.remove_rule_from_policy(rule_uri, policy_uri) db_access.delete_rule(rule_uri) assert not db_access.rule_exists(rule_uri) # Should also remove any actions from the rule assert not db_access.rule_has_action(rule_uri, action_uri) # Should also remove any assignors from the rule assert not db_access.rule_has_assignor(assignor_uri, rule_uri) # Should also remove any assignees from the rule assert not db_access.rule_has_assignee(assignee_uri, rule_uri)
def test_get_all_policies(mock): policy1_uri = 'https://example.com#policy1' policy2_uri = 'https://example.com#policy2' db_access.create_policy(policy1_uri) db_access.create_policy(policy2_uri) # Should retrieve every policy assert db_access.get_all_policies() == [policy1_uri, policy2_uri]
def test_policy_exists(mock): # Should return true if the policy exists uri = 'https://example.com#test' db_access.create_policy(uri) assert db_access.policy_exists(uri) # Should return false if the policy doesn't exist nonexistent_uri = 'https://example.com#nonexistent' assert not db_access.policy_exists(nonexistent_uri)
def test_create_policy(mock): # Should store a new policy entry in the database new_policy_uri = 'https://example.com#test' db_access.create_policy(new_policy_uri) assert db_access.policy_exists(new_policy_uri) # Should reject duplicate policies with pytest.raises(ValueError): db_access.create_policy(new_policy_uri)
def test_remove_rule_from_policy(mock): # Should remove a rule from a policy policy_uri = 'https://example.com#policy' db_access.create_policy(policy_uri) rule_uri = 'https://example.com#rule' rule_type = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' db_access.create_rule(rule_uri, rule_type, rule_label) db_access.add_rule_to_policy(rule_uri, policy_uri) db_access.remove_rule_from_policy(rule_uri, policy_uri) assert not db_access.policy_has_rule(policy_uri, rule_uri)
def test_policy_has_rule(mock): # Should return false if the policy does not have the rule policy_uri = 'https://example.com#policy' rule_uri = 'http://example.com#rule' assert not db_access.policy_has_rule(policy_uri, rule_uri) # Should return true if the policy has the rule db_access.create_policy(policy_uri) rule_type = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' db_access.create_rule(rule_uri, rule_type, rule_label) db_access.add_rule_to_policy(rule_uri, policy_uri) assert db_access.policy_has_rule(policy_uri, rule_uri)
def test_get_policies_for_rule(mock): rule_uri = 'https://example.com#rule' rule_type = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' db_access.create_rule(rule_uri, rule_type, rule_label) policy1 = 'https://example.com#policy1' db_access.create_policy(policy1) db_access.add_rule_to_policy(rule_uri, policy1) policy2 = 'https://example.com#policy2' db_access.create_policy(policy2) db_access.add_rule_to_policy(rule_uri, policy2) policies = db_access.get_policies_for_rule(rule_uri) assert {'URI': policy1, 'LABEL': None} in policies assert {'URI': policy2, 'LABEL': None} in policies
def test_set_policy_attribute(mock): # Should set a valid attribute for an existing policy uri = 'https://example.com#test' new_policy_type = 'http://creativecommons.org/ns#License' db_access.create_policy(uri) db_access.set_policy_attribute(uri, 'TYPE', new_policy_type) stored_policy_type = db_access.query_db( 'SELECT TYPE FROM POLICY WHERE URI = ?', (uri, ), one=True)[0] assert stored_policy_type == new_policy_type # Should reject attribute change for a policy that does not exist with pytest.raises(ValueError): db_access.set_policy_attribute('https://example.com#nonexistent', 'TYPE', new_policy_type) # Should reject changing attribute that is not permitted with pytest.raises(ValueError): db_access.set_policy_attribute(uri, 'NONEXISTENT', new_policy_type)
def test_get_rules_for_policy(mock): # Should return a list of URIs for all Rules assigned to a Policy policy_uri = 'https://example.com#policy' db_access.create_policy(policy_uri) rule_type = 'http://www.w3.org/ns/odrl/2/permission' rule_label = 'Rule' rule1_uri = 'https://example.com#rule1' rule2_uri = 'https://example.com#rule2' db_access.create_rule(rule1_uri, rule_type, rule_label) db_access.create_rule(rule2_uri, rule_type, rule_label) db_access.add_rule_to_policy(rule1_uri, policy_uri) db_access.add_rule_to_policy(rule2_uri, policy_uri) assert db_access.get_rules_for_policy(policy_uri) == [rule1_uri, rule2_uri] # Shouldn't include any other Rules rule3_uri = 'https://example.com#rule3' db_access.create_rule(rule3_uri, rule_type, rule_label) assert db_access.get_rules_for_policy(policy_uri) == [rule1_uri, rule2_uri]
def test_get_policies_using_action(mock): action_uri = 'http://www.w3.org/ns/odrl/2/acceptTracking' rule1_uri = 'https://example.com#rule1' rule1_type = 'http://www.w3.org/ns/odrl/2/permission' rule1_label = 'Rule1' db_access.create_rule(rule1_uri, rule1_type, rule1_label) db_access.add_action_to_rule(action_uri, rule1_uri) rule2_uri = 'https://example.com#rule2' rule2_type = 'http://www.w3.org/ns/odrl/2/permission' rule2_label = 'Rule2' db_access.create_rule(rule2_uri, rule2_type, rule2_label) db_access.add_action_to_rule(action_uri, rule2_uri) policy1_uri = 'http://example.com#policy1' policy2_uri = 'http://example.com#policy2' policy3_uri = 'http://example.com#policy3' db_access.create_policy(policy1_uri) db_access.create_policy(policy2_uri) db_access.create_policy(policy3_uri) db_access.add_rule_to_policy(rule1_uri, policy1_uri) db_access.add_rule_to_policy(rule2_uri, policy2_uri) db_access.add_rule_to_policy(rule2_uri, policy3_uri) policies = db_access.get_policies_using_action(action_uri) assert all(policy['URI'] in [policy1_uri, policy2_uri, policy3_uri] for policy in policies)
def test_delete_policy(mock): # Should remove an existing policy policy_uri = 'https://example.com#policy' db_access.create_policy(policy_uri) db_access.delete_policy(policy_uri) assert not db_access.policy_exists(policy_uri)
def create_policy(policy_uri, attributes=None, rules=None): """ Creates an entire policy with the given URI, attributes and Rules. Will attempt to use Rule Type and Actions whether they are given by URI or Label. If there is an error at any point, will rollback all changes to database to avoid leaving partially created policies. :param policy_uri: :param attributes: Dictionary of optional attributes of the policy. Permitted attributes: type, label, jurisdiction, legal_code, has_version, language, see_also same_as, comment, logo, status :param rules: List of Rules. Each Rule should be a Dictionary containing the following elements: TYPE_URI*: string (i.e. 'http://www.w3.org/ns/odrl/2/duty') TYPE_LABEL*: string (i.e. 'duty') * At least one of TYPE_URI or TYPE_LABEL should be provided, but both are not required ASSIGNORS: List of Assignors. Each Assignor should be a Dictionary containing a URI, LABEL and COMMENT. ASSIGNEES: List of Assignees. Each Assignee should be a Dictionary containing a URI, LABEL and COMMENT. ACTIONS: List of strings (URIs or labels) :return: """ if not is_valid_uri(policy_uri): raise ValueError('Not a valid URI: ' + policy_uri) permitted_rule_types = [] try: db_access.create_policy(policy_uri) if attributes: for attr_name, attr_value in attributes.items(): db_access.set_policy_attribute(policy_uri, attr_name, attr_value) if rules: for rule in rules: rule_uri = _conf.BASE_URI + 'rules/' + str(uuid4()) if 'TYPE_URI' in rule: rule_type = rule['TYPE_URI'] elif 'TYPE_LABEL' in rule: if not permitted_rule_types: permitted_rule_types = db_access.get_permitted_rule_types( ) rule_type = get_rule_type_uri(rule['TYPE_LABEL'], permitted_rule_types) if not rule_type: raise ValueError('Cannot create policy - Rule type ' + rule['TYPE_LABEL'] + ' is not permitted') else: raise ValueError( 'Cannot create policy - no Rule type provided') db_access.create_rule(rule_uri, rule_type) for action in rule['ACTIONS']: if action: if is_valid_uri(action): action_uri = action else: permitted_actions = db_access.get_all_actions() action_uri = get_action_uri( action, permitted_actions) if not action_uri: raise ValueError( 'Cannot create policy - Action ' + action + ' is not permitted') db_access.add_action_to_rule(action_uri, rule_uri) if 'ASSIGNORS' in rule: for assignor in rule['ASSIGNORS']: if not db_access.party_exists(assignor['URI']): db_access.create_party(assignor['URI'], assignor['LABEL'], assignor['COMMENT']) db_access.add_assignor_to_rule(assignor['URI'], rule_uri) if 'ASSIGNEES' in rule: for assignee in rule['ASSIGNEES']: if not db_access.party_exists(assignee['URI']): db_access.create_party(assignee['URI'], assignee['LABEL'], assignee['COMMENT']) db_access.add_assignee_to_rule(assignee['URI'], rule_uri) db_access.add_rule_to_policy(rule_uri, policy_uri) except Exception as error: db_access.rollback_db() raise error db_access.commit_db()