def test_node_json_validation(self): node = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': 'http://example.com/1', 'type': 'Assertion', 'schema:location': { '@context': 'https://w3id.org/openbadges/extensions/geoCoordinatesExtension/context.json', 'type': ['Extension', 'extensions:GeoCoordinates'], 'description': 'That place in the woods where we built the fort', 'schema:geo': { 'schema:latitude': 44.580900, 'schema:longitude': -123.301815 } } } loader = CachableDocumentLoader(use_cache=True) loader.session.cache.remove_old_entries(datetime.datetime.utcnow()) loader.contexts = set() options = {'jsonld_options': {'documentLoader': loader}} set_up_context_mock() loader(OPENBADGES_CONTEXT_V2_URI) schema_url = list(GeoLocation.validation_schema)[0] responses.add(responses.GET, GeoLocation.context_url, status=200, json=GeoLocation.context_json) loader(GeoLocation.context_url) responses.add(responses.GET, schema_url, status=200, json=GeoLocation.validation_schema[schema_url]) loader.session.get(schema_url) state = INITIAL_STATE task = add_task(INTAKE_JSON, data=json.dumps(node), node_id=node['id']) result, message, actions = task_named(INTAKE_JSON)(state, task, **options) state = main_reducer(state, actions[0]) result, message, actions = task_named(actions[1]['name'])( state, actions[1], **options) # JSONLD_COMPACT_DATE state = main_reducer(state, actions[0]) # ADD_NODE task_meta = actions[1] # VALIDATE_EXTENSION_NODE result, message, actions = validate_extension_node(state, task_meta) self.assertTrue(result, "A valid expression of the extension should pass") self.assertIn('validated on node', message) self.assertEqual(len(actions), 0) del state['graph'][0]['schema:location']['schema:geo'][ 'schema:latitude'] result, message, actions = validate_extension_node(state, task_meta) self.assertFalse( result, "A required property not present should be detected by JSON-schema." )
def load_mocks(self): loader = CachableDocumentLoader(use_cache=True) loader.session.cache.remove_old_entries(datetime.datetime.utcnow()) loader.contexts = set() self.options = {'jsonld_options': {'documentLoader': loader}} set_up_context_mock() loader(OPENBADGES_CONTEXT_V2_URI) schema_url = list(ExampleExtension.validation_schema)[0] responses.add(responses.GET, ExampleExtension.context_url, status=200, json=ExampleExtension.context_json) loader(ExampleExtension.context_url) responses.add(responses.GET, schema_url, status=200, json=ExampleExtension.validation_schema[schema_url]) loader.session.get(schema_url) self.state = INITIAL_STATE task = add_task(INTAKE_JSON, data=json.dumps(self.first_node), node_id=self.first_node['id']) result, message, actions = task_named(INTAKE_JSON)(self.state, task, **self.options) self.state = main_reducer(self.state, actions[0]) result, message, actions = task_named(actions[1]['name'])( self.state, actions[1], **self.options) # JSONLD_COMPACT_DATE self.state = main_reducer(self.state, actions[0]) # ADD_NODE self.validation_task = actions[1] # VALIDATE_EXTENSION_NODE
def test_queue_validation_on_unknown_extension(self): set_up_context_mock() self.set_up_test_extension() first_node_json = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': 'http://example.org/assertion', 'extensions:exampleExtension': { '@context': self.extension_context_url, 'type': ['Extension', 'extensions:UnknownExtension'], 'unknownProperty': 'I\'m a property, short and sweet' }, 'evidence': 'http://example.org/evidence' } state = INITIAL_STATE task_meta = add_task( INTAKE_JSON, data=json.dumps(first_node_json), node_id=first_node_json['id']) result, message, actions = task_named(INTAKE_JSON)(state, task_meta) for action in actions: state = main_reducer(state, action) # Compact JSON result, message, actions = task_named(state['tasks'][0]['name'])(state, state['tasks'][0]) self.assertEqual(len(actions), 3) state = main_reducer(state, actions[0]) validation_action = actions[1] result, message, actions = validate_extension_node(state, validation_action) self.assertTrue(result)
def test_upgrade_1_1_badgeclass_with_multiple_alignments(self): setUpContextCache() data = json.loads(test_components['1_1_basic_badgeclass']) data['alignment'] = [{ 'name': 'Target 1 Name', 'description': 'Target 1 Description', 'url': 'http://example.org/target-1' }, { 'name': 'Target 2 Name', 'url': 'http://example.org/target-2' }] state = INITIAL_STATE task = add_task(INTAKE_JSON, node_id='https://example.org/robotics-badge.json', data=json.dumps(data)) result, message, actions = task_named(INTAKE_JSON)(state, task) for action in actions: state = main_reducer(state, action) for task in state.get('tasks'): result, message, actions = task_named(task['name'])(state, task) for action in actions: state = main_reducer(state, action) # Test alignment object upgrades self.assertEqual(len(state['graph'][0]['alignment']), 2) self.assertEqual(state['graph'][0]['alignment'][0]['targetUrl'], data['alignment'][0]['url'])
def test_upgrade_1_1_issuer(self): setUpContextCache() data = json.loads(test_components['1_1_basic_issuer']) data['type'] = 'IssuerOrg' # Test alias that was accepted in v1.1 context json_data = json.dumps(data) state = INITIAL_STATE task = add_task(INTAKE_JSON, node_id='https://example.org/organization.json', data=json_data) result, message, actions = task_named(INTAKE_JSON)(state, task) for action in actions: state = main_reducer(state, action) for task in state.get('tasks'): result, message, actions = task_named(task['name'])(state, task) for action in actions: state = main_reducer(state, action) self.assertTrue(result) self.assertEqual(state['graph'][0]['type'], OBClasses.Issuer)
def test_extension_discovered_jsonld_compact(self): """ Ensure an extension node is properly discovered and that the task runs without error. """ node = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': 'http://example.com/1', 'type': 'Assertion', 'schema:location': { '@context': GeoLocation.context_url, 'type': ['Extension', 'extensions:GeoCoordinates'], 'description': 'That place in the woods where we built the fort', 'schema:geo': { 'schema:latitude': 44.580900, 'schema:longitude': -123.301815 } } } state = INITIAL_STATE set_up_context_mock() responses.add(responses.GET, GeoLocation.context_url, body=json.dumps(GeoLocation.context_json), status=200, content_type='application/ld+json') schema_url = 'https://w3id.org/openbadges/extensions/geoCoordinatesExtension/schema.json' responses.add(responses.GET, schema_url, body=json.dumps( GeoLocation.validation_schema[schema_url]), status=200, content_type='application/ld+json') compact_task = add_task(JSONLD_COMPACT_DATA, data=json.dumps(node), jsonld_options=jsonld_no_cache, context_urls=[GeoLocation.context_url]) result, message, actions = task_named(JSONLD_COMPACT_DATA)( state, compact_task) self.assertTrue(result, "JSON-LD Compact is successful.") self.assertIn(VALIDATE_EXTENSION_NODE, [i.get('name') for i in actions], "Validation task queued.") state = main_reducer(state, actions[0]) # ADD_NODE validate_task = [ i for i in actions if i.get('name') == VALIDATE_EXTENSION_NODE ][0] self.assertIsNotNone(validate_task['node_json']) result, message, actions = task_named(VALIDATE_EXTENSION_NODE)( state, validate_task) self.assertTrue(result, "Validation task is successful.")
def test_upgrade_1_1_assertion(self): setUpContextCache() json_data = test_components['1_1_basic_assertion'] state = INITIAL_STATE task = add_task( INTAKE_JSON, node_id='https://example.org/beths-robotics-badge.json', data=json_data) result, message, actions = task_named(INTAKE_JSON)(state, task) for action in actions: state = main_reducer(state, action) for task in state.get('tasks'): result, message, actions = task_named(task['name'])(state, task) for action in actions: state = main_reducer(state, action) result, message, actions = task_named(UPGRADE_1_1_NODE)(state, task) self.assertTrue(result) self.assertEqual(len(actions), 0) # Test timestamp upgrading state['graph'][0]['issuedOn'] = 1500423730 result, message, actions = task_named(UPGRADE_1_1_NODE)(state, task) self.assertTrue(result) self.assertEqual(len(actions), 1) self.assertEqual(actions[0]['data']['issuedOn'], '2017-07-19T00:22:10+00:00') self.assertEqual(len(actions[0]['data'].keys()), 1, "There is a patch made of one prop") state['graph'][0]['issuedOn'] = '1500423730.5' result, message, actions = task_named(UPGRADE_1_1_NODE)(state, task) self.assertTrue(result) self.assertEqual(len(actions), 1) state = main_reducer(state, actions[0]) state['graph'][0]['issuedOn'] = '2016-05-15' result, message, actions = task_named(UPGRADE_1_1_NODE)(state, task) self.assertTrue(result) self.assertEqual(len(actions), 1) state = main_reducer(state, actions[0])
def test_json_0_5_assertion_input(self): assertion_data = json.dumps(self.assertion_data) state = INITIAL_STATE action = store_input(assertion_data) state = main_reducer(state, action) self.assertEqual(state['input']['value'], assertion_data) task_meta = add_task(DETECT_INPUT_TYPE) result, message, actions = run_task(state, task_meta) self.assertTrue(result, "Task completes successfully") self.assertIn(REPORT_MESSAGE, [a.get('type') for a in actions])
def test_upgrade_1_0_assertion(self): json_data = test_components['1_0_basic_assertion'] state = INITIAL_STATE task = add_task(INTAKE_JSON, node_id='http://a.com/instance', data=json_data) result, message, actions = task_named(INTAKE_JSON)(state, task) for action in actions: state = main_reducer(state, action) task = state.get('tasks')[0] result, message, actions = task_named(task['name'])(state, task) self.assertTrue(result) self.assertEqual(len(actions), 2) for action in actions: state = main_reducer(state, action) self.assertEqual(len(state.get('tasks')), 3) modified_data = json.loads(state.get('tasks')[1]['data']) self.assertEqual(modified_data['@context'], OPENBADGES_CONTEXT_V1_URI) self.assertEqual(modified_data['id'], modified_data['verify']['url']) self.assertEqual(modified_data['type'], OBClasses.Assertion)
def test_json_1_0_assertion_input(self): assertion_data = test_components['1_0_basic_assertion'] state = INITIAL_STATE action = store_input(assertion_data) state = main_reducer(state, action) self.assertEqual(state['input']['value'], assertion_data) task_meta = add_task(DETECT_INPUT_TYPE) result, message, actions = run_task(state, task_meta) self.assertTrue(result) self.assertIn(SET_VALIDATION_SUBJECT, [a.get('type') for a in actions]) self.assertIn(FETCH_HTTP_NODE, [a.get('name') for a in actions])
def test_upgrade_1_1_badgeclass(self): setUpContextCache() json_data = test_components['1_1_basic_badgeclass'] state = INITIAL_STATE task = add_task(INTAKE_JSON, node_id='https://example.org/robotics-badge.json', data=json_data) result, message, actions = task_named(INTAKE_JSON)(state, task) for action in actions: state = main_reducer(state, action) for task in state.get('tasks'): result, message, actions = task_named(task['name'])(state, task) for action in actions: state = main_reducer(state, action) # Test criteria class upgrade state['graph'][0]['alignment'] = { 'url': 'http://somewhere.overtherainbow.net/wayuphigh', 'name': "Knowledge of children's songs" } result, message, actions = task_named(UPGRADE_1_1_NODE)(state, task) self.assertTrue(result) self.assertEqual(len(actions), 1)
def test_queue_validation_on_unknown_extension(self): set_up_context_mock() extension_schema = { "$schema": "http://json-schema.org/draft-04/schema#", "title": "1.1 Open Badge Example Extension for testing: Unknown Extension", "description": "An extension that allows you to add a single string unknownProperty to an extension object for unknown reasons.", "type": "object", "properties": { "unknownProperty": { "type": "string" } }, "required": ["unknownProperty"] } extension_schema_url = 'http://example.org/unkownSchema' extension_context = { '@context': { "obi": "https://w3id.org/openbadges#", "extensions": "https://w3id.org/openbadges/extensions#", 'unknownProperty': 'http://schema.org/unknownProperty' }, "obi:validation": [ { "obi:validatesType": "extensions:UnknownExtension", "obi:validationSchema": extension_schema_url } ] } extension_context_url = 'http://example.org/unknownExtensionContext' first_node_json = { '@context': OPENBADGES_CONTEXT_V2_URI, 'id': 'http://example.org/assertion', 'extensions:exampleExtension': { '@context': extension_context_url, 'type': ['Extension', 'extensions:UnknownExtension'], 'unknownProperty': 'I\'m a property, short and sweet' }, 'evidence': 'http://example.org/evidence' } responses.add( responses.GET, extension_context_url, json=extension_context ) responses.add( responses.GET, extension_schema_url, json=extension_schema ) state = INITIAL_STATE task_meta = add_task( INTAKE_JSON, data=json.dumps(first_node_json), node_id=first_node_json['id']) result, message, actions = task_named(INTAKE_JSON)(state, task_meta) for action in actions: state = main_reducer(state, action) # Compact JSON result, message, actions = task_named(state['tasks'][0]['name'])(state, state['tasks'][0]) self.assertEqual(len(actions), 3) state = main_reducer(state, actions[0]) validation_action = actions[1] result, message, actions = validate_extension_node(state, validation_action) self.assertTrue(result)