blob: 2ec53133a0ec59d4ba99a1ebf1f8d8f3abcddc29 [file]
import pytest
from aiohttp import web
from app.service.app_svc import AppService
from app.service.auth_svc import AuthService, CONFIG_API_KEY_RED
from app.service.file_svc import FileSvc
from app.service.data_svc import DataService
from app.service.event_svc import EventService
from app.service.contact_svc import ContactService
from app.utility.base_service import BaseService
from app.utility.base_world import BaseWorld
from app.api.v2.handlers.fact_api import FactApi
from app.api.v2.responses import json_request_validation_middleware
from app.api.v2.security import authentication_required_middleware_factory
from app.objects.secondclass.c_fact import WILDCARD_STRING
from app.service.knowledge_svc import KnowledgeService
cakr = 'abc123'
headers = {'key': cakr, 'Content-Type': 'application/json'}
@pytest.fixture
def base_world():
BaseWorld.apply_config(
name='main',
config={
CONFIG_API_KEY_RED: cakr,
'users': {
'red': {'reduser': 'redpass'},
'blue': {'blueuser': 'bluepass'}
},
'crypt_salt': 'thisisdefinitelynotkosher', # Salt for file service instantiation
'encryption_key': 'andneitheristhis', # fake encryption key for file service instantiation
}
)
yield BaseWorld
BaseWorld.clear_config()
@pytest.fixture
async def knowledge_webapp(base_world, data_svc):
app_svc = AppService(web.Application())
app_svc.add_service('auth_svc', AuthService())
app_svc.add_service('knowledge_svc', KnowledgeService())
app_svc.add_service('data_svc', DataService())
app_svc.add_service('event_svc', EventService())
app_svc.add_service('contact_svc', ContactService())
app_svc.add_service('file_svc', FileSvc()) # This needs to be done this way, or it we won't have a valid BaseWorld
services = app_svc.get_services()
app = web.Application(
middlewares=[
authentication_required_middleware_factory(services['auth_svc']),
json_request_validation_middleware
]
)
FactApi(services).add_routes(app)
await app_svc.register_contacts()
return app
async def test_display_facts(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
fact_data = {
'trait': 'demo',
'value': 'test'
}
await client.post('/facts', json=fact_data, headers=headers)
resp = await client.get('/facts', json=fact_data, headers=headers)
data = await resp.json()
response = data['found']
assert len(response) == 1
assert response[0]['trait'] == 'demo'
assert response[0]['value'] == 'test'
assert response[0]['source'] == WILDCARD_STRING
async def test_display_operation_facts(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
op_id_test = 'this_is_a_valid_operation_id'
fact_data = {
'trait': 'demo',
'value': 'test',
'source': op_id_test
}
await client.post('/facts', json=fact_data, headers=headers)
resp = await client.get(f'/facts/{op_id_test}', headers=headers)
data = await resp.json()
response = data['found']
assert len(response) == 1
assert response[0]['trait'] == 'demo'
assert response[0]['value'] == 'test'
assert response[0]['source'] == op_id_test
async def test_display_relationships(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
op_id_test = 'this_is_a_valid_operation_id'
fact_data_a = {
'trait': 'a',
'value': '1',
}
fact_data_b = {
'trait': 'b',
'value': '2'
}
relationship_data = {
'source': fact_data_a,
'edge': 'gamma',
'target': fact_data_b,
'origin': op_id_test
}
await client.post('/relationships', json=relationship_data, headers=headers)
resp = await client.get('/relationships', json=relationship_data, headers=headers)
data = await resp.json()
response = data['found']
assert len(response) == 1
assert response[0]['source']['trait'] == 'a'
assert response[0]['source']['value'] == '1'
assert response[0]['edge'] == 'gamma'
assert response[0]['origin'] == 'this_is_a_valid_operation_id'
assert response[0]['source']['source'] == 'this_is_a_valid_operation_id'
async def test_display_operation_relationships(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
op_id_test = 'this_is_a_valid_operation_id'
fact_data_a = {
'trait': 'a',
'value': '1',
'source': op_id_test
}
fact_data_b = {
'trait': 'b',
'value': '2',
'source': op_id_test
}
relationship_data = {
'source': fact_data_a,
'edge': 'gamma',
'target': fact_data_b,
'origin': op_id_test
}
await client.post('/relationships', json=relationship_data, headers=headers)
resp = await client.get(f'/relationships/{op_id_test}', headers=headers)
data = await resp.json()
response = data['found']
assert len(response) == 1
assert response[0]['source']['trait'] == fact_data_a['trait']
assert response[0]['source']['value'] == fact_data_a['value']
assert response[0]['target']['trait'] == fact_data_b['trait']
assert response[0]['target']['value'] == fact_data_b['value']
assert response[0]['edge'] == relationship_data['edge']
assert response[0]['origin'] == op_id_test
assert response[0]['source']['source'] == op_id_test
assert response[0]['target']['source'] == op_id_test
async def test_remove_fact(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
fact_data = {
'trait': 'demo',
'value': 'test'
}
init = await client.post('/facts', json=fact_data, headers=headers)
pre = await init.json()
subs = await client.delete('/facts', json=fact_data, headers=headers)
post = await subs.json()
tmp = await client.get('/facts', json=fact_data, headers=headers)
cur = await tmp.json()
current = cur['found']
start = pre['added']
end = post['removed']
assert len(start) == 1
assert len(end) == 1
assert len(current) == 0
assert start == end
async def test_remove_relationship(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
op_id_test = 'this_is_a_valid_operation_id'
fact_data_a = {
'trait': 'a',
'value': '1',
}
fact_data_b = {
'trait': 'b',
'value': '2'
}
relationship_data = {
'source': fact_data_a,
'edge': 'alpha',
'target': fact_data_b,
'origin': op_id_test
}
init = await client.post('/relationships', json=relationship_data, headers=headers)
pre = await init.json()
subs = await client.delete('/relationships', json=dict(edge='alpha'), headers=headers)
post = await subs.json()
resp = await client.get('/relationships', json=relationship_data, headers=headers)
cur = await resp.json()
start = pre['added']
end = post['removed']
current = cur['found']
assert len(start) == 1
assert len(end) == 1
assert len(current) == 0
assert start == end
async def test_add_fact(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
fact_data = {
'trait': 'demo',
'value': 'test'
}
resp = await client.post('/facts', json=fact_data, headers=headers)
data = await resp.json()
response = data['added']
assert len(response) == 1
assert response[0]['trait'] == 'demo'
assert response[0]['value'] == 'test'
tmp = await client.get('/facts', json=fact_data, headers=headers)
cur = await tmp.json()
current = cur['found']
assert current == response
async def test_add_fact_to_operation(knowledge_webapp, aiohttp_client, test_operation, setup_empty_operation, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
fact_data = {
'trait': 'demo',
'value': 'test',
'source': test_operation['id']
}
resp = await client.post('/facts', json=fact_data, headers=headers)
data = await resp.json()
response = data['added']
assert len(response) == 1
assert response[0]['trait'] == 'demo'
assert response[0]['value'] == 'test'
assert response[0]['source'] == test_operation['id']
tmp = await client.get('/facts', json=fact_data, headers=headers)
cur = await tmp.json()
current = cur['found']
assert current == response
data_svc = BaseService.get_service('data_svc')
file_svc = BaseService.get_service('file_svc')
matched_operations = await data_svc.locate('operations', {'id': test_operation['id']})
report = await matched_operations[0].report(file_svc, data_svc)
assert response[0] in report['facts']
async def test_add_fact_to_finished_operation(knowledge_webapp, aiohttp_client, setup_finished_operation,
finished_operation_payload, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
op_id = finished_operation_payload['id']
matched_operations = await BaseService.get_service('data_svc').locate('operations', {'id': op_id})
assert await matched_operations[0].is_finished()
fact_data = {
'trait': 'demo',
'value': 'test',
'source': op_id
}
resp = await client.post('/facts', json=fact_data, headers=headers)
data = await resp.json()
assert 'error' in data
assert 'Cannot add fact to finished operation.' in data['error']
async def test_add_relationship(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
fact_data_a = {
'trait': 'a',
'value': '1',
}
fact_data_b = {
'trait': 'b',
'value': '2'
}
relationship_data = {
'source': fact_data_a,
'edge': 'tango',
'target': fact_data_b
}
expected_response = f"{fact_data_a['trait']}({fact_data_a['value']}) : " \
f"tango : {fact_data_b['trait']}({fact_data_b['value']})"
resp = await client.post('/relationships', json=relationship_data, headers=headers)
data = await resp.json()
response = data['added']
assert len(response) == 1
assert response[0]['source']['trait'] == fact_data_a['trait']
assert response[0]['target']['value'] == fact_data_b['value']
assert response[0]['edge'] == 'tango'
assert response[0]['source']['relationships'] == response[0]['target']['relationships']
assert response[0]['source']['relationships'][0] == expected_response
resp = await client.get('/relationships', json=relationship_data, headers=headers)
cur = await resp.json()
current = cur['found']
assert current == response
async def test_patch_fact(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
fact_data = {
'trait': 'domain.user.name',
'value': 'thomas'
}
patch_data = {
"criteria": {
"trait": "domain.user.name",
"value": "thomas"},
"updates": {
"value": "jacobson"
}
}
await client.post('/facts', json=fact_data, headers=headers)
resp = await client.patch('/facts', json=patch_data, headers=headers)
message = await resp.json()
patched = message['updated']
assert len(patched) == 1
assert patched[0]['value'] == 'jacobson'
tmp = await client.get('/facts', json=dict(trait='domain.user.name'), headers=headers)
cur = await tmp.json()
current = cur['found']
assert len(current) == 1
assert patched == current
async def test_patch_relationship(knowledge_webapp, aiohttp_client, fire_event_mock):
client = await aiohttp_client(knowledge_webapp)
relationship_data = {
"source": {
"trait": "domain.user.name",
"value": "bobross"
},
"edge": "has_password",
"target": {
"trait": "domain.user.password",
"value": "12345"
}
}
patch_data = {
"criteria": {
"edge": "has_password",
"source": {
"value": "bobross"
}
},
"updates": {
"target": {
"value": "54321"
},
"edge": "has_admin_password"
}
}
await client.post('/relationships', json=relationship_data, headers=headers)
resp = await client.patch('/relationships', json=patch_data, headers=headers)
message = await resp.json()
patched = message['updated']
assert len(patched) == 1
assert patched[0]['target']['value'] == '54321'
assert patched[0]['source']['value'] == 'bobross'
assert patched[0]['edge'] == 'has_admin_password'
tmp = await client.get('/relationships', json=dict(edge='has_admin_password'), headers=headers)
cur = await tmp.json()
current = cur['found']
assert len(current) == 1
assert patched == current