diff --git a/slp_abacus/tests/integration/__init__.py b/slp_abacus/tests/integration/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/slp_abacus/tests/integration/test_abacus_processor.py b/slp_abacus/tests/integration/test_abacus_processor.py new file mode 100644 index 00000000..6c91b515 --- /dev/null +++ b/slp_abacus/tests/integration/test_abacus_processor.py @@ -0,0 +1,75 @@ +import io + +import pytest +from pytest import mark, param +from starlette.datastructures import UploadFile + +from sl_util.sl_util.file_utils import get_byte_data +from sl_util.tests.util.file_utils import generate_temporary_file +from slp_abacus import AbacusProcessor +from slp_abacus.slp_abacus.validate.abacus_validator import MAX_SIZE, MIN_SIZE +from slp_abacus.tests.resources import test_resource_paths +from slp_base import LoadingDiagramFileError +from slp_base.slp_base.errors import ErrorCode, DiagramFileNotValidError + +SAMPLE_ID = 'id' +SAMPLE_NAME = 'name' +SAMPLE_FILE_INVALID_FORMAT = test_resource_paths.abacus_bad_file_format +SAMPLE_FILE_INVALID_EXTENSION = test_resource_paths.abacus_bad_file_extension +SAMPLE_DEFAULT_MAPPING = test_resource_paths.abacus_default_mapping + +class TestAbacusProcessor: + def test_no_abacus_file_format(self): + # GIVEN a valid ABACUS file + abacus_file = open(SAMPLE_FILE_INVALID_FORMAT, 'rb') + + # AND a valid default mapping file + default_mapping_file = get_byte_data(SAMPLE_DEFAULT_MAPPING) + + # WHEN ABACUS is processing + # THEN raises LoadingDiagramFileError + with pytest.raises(LoadingDiagramFileError) as error: + AbacusProcessor(SAMPLE_ID, SAMPLE_NAME, abacus_file, [default_mapping_file]).process() + + # AND the error details are correct + assert ErrorCode.DIAGRAM_LOADING_ERROR == error.value.error_code + assert "Source file cannot be loaded" == error.value.title + assert "JSONDecodeError" == error.value.detail + assert "Expecting value: line 1 column 1 (char 0)" == error.value.message + + @mark.parametrize('source', [ + param(generate_temporary_file(MIN_SIZE - 1, "test_min_size.txt"), id='file too small'), + param(generate_temporary_file(MAX_SIZE + 1, "test_max_size.txt"), id='file too big')]) + def test_abacus_file_sizes(self, source): + # GIVEN a valid default mapping file + default_mapping_file = get_byte_data(SAMPLE_DEFAULT_MAPPING) + + # WHEN ABACUS is processing + # THEN raises DiagramFileNotValidError + with pytest.raises(DiagramFileNotValidError) as error: + upload_file = UploadFile(filename="source.json", file=io.BytesIO(source)) + AbacusProcessor(SAMPLE_ID, SAMPLE_NAME, upload_file, [default_mapping_file]).process() + + # AND the error details are correct + assert ErrorCode.DIAGRAM_NOT_VALID == error.value.error_code + assert "Abacus file is not valid" == error.value.title + assert "Provided diag_file is not valid. Invalid size" == error.value.detail + assert "Provided diag_file is not valid. Invalid size" == error.value.message + + def test_no_abacus_valid_extension(self): + # GIVEN a valid ABACUS file + abacus_file = open(SAMPLE_FILE_INVALID_EXTENSION, 'rb') + + # AND a valid default mapping file + default_mapping_file = get_byte_data(SAMPLE_DEFAULT_MAPPING) + + # WHEN ABACUS is processing + # THEN raises DiagramFileNotValidError + with pytest.raises(DiagramFileNotValidError) as error: + AbacusProcessor(SAMPLE_ID, SAMPLE_NAME, abacus_file, [default_mapping_file]).process() + + # AND the error details are correct + assert ErrorCode.DIAGRAM_NOT_VALID == error.value.error_code + assert "Abacus file is not valid" == error.value.title + assert "Invalid content type for diag_file" == error.value.detail + assert "Invalid content type for diag_file" == error.value.message diff --git a/slp_abacus/tests/resources/abacus/aws_minimal.drawio b/slp_abacus/tests/resources/abacus/aws_minimal.drawio new file mode 100644 index 00000000..2225960e --- /dev/null +++ b/slp_abacus/tests/resources/abacus/aws_minimal.drawio @@ -0,0 +1 @@ +7VbbcpswEP0aP8bDNTiPMdhJ22TaxnGSN48MMqgRiBHCxv36rkBgbmmSmXSmDxljrD0Su9LZ3WMmphsXVxyl0S0LMJ0YWlBMTG9iGLpl6PAjkWOFXGhWBYScBGrRCViR31iBmkJzEuCss1AwRgVJu6DPkgT7ooMhztmhu2zHaDdqikI8AFY+okP0kQQiqtCZ4Zzwa0zCqI6sn19UMzGqF6uTZBEK2KEFmYuJ6XLGRDWKCxdTSV7NS/Xc8oXZZmMcJ+ItD9jEeVjPsuKeRhuP/VqHj0/emfKyRzRXB758XAHgUpYHat/iWJORMpKIklB7DhfEc7WJDTOutKaG3QP6ttMF9KElfXSBvu10Ab3vXu/F1/sbbAEDq+Ne68XXWhuEy5yzXFCSYLcpPQ3AkKOAQEpcRhkHLGEJsDePREzB0mF4iIjAqxT5ktUDtA1gO5YIVfy6UduKeOkVylsgiMWVjzITmC/2uEpItYZSlGZk2zzFsZ/zjOzxHc4q5xKFQkzlOC5C2bNTdMisachZnpbb/wKxRmc3MNz4sjA2iArpSHD2jOuDTgwTPktZfPMdobRHwB5zQaCvLikJpX/BZDikLIp3pUdghSThTWl5pqaYGAsRoCzCgTrSsBfqwoaouGhBqjeuMIux4EdYomYbxVFCZZjKPpzaXq+xqN3yNYiU1ISN71M3wkA15HhzFuvrrw/2z6fn4/333Ea338748swYNOegI0lc6le7vBTkkTiEqJRs4e5TAunjQg5ZnOZQOhmMPSTQFmV4oxuzAr7TNAmHVP5VON7Or92h1xqyOxshd/YB3I7uf8jtHQ4JVP6n5n1qXkvzeFUVI2KnW85ifvlPxa4J0Yid/jFiZ1n/ndiZr4vdaO11/gdq3m/QFtMfLCOiTJ63ZUKw+NXE+FgWWLdyRyrHnGLf6CUesrW0Z7ZpvdwOb1RW473JNM5LFWin0xlk0zmf2sN0XpjvziaYp3fWcq715m8u/gA= \ No newline at end of file diff --git a/slp_abacus/tests/resources/abacus/invalid-file-extension.png b/slp_abacus/tests/resources/abacus/invalid-file-extension.png new file mode 100644 index 00000000..34889161 Binary files /dev/null and b/slp_abacus/tests/resources/abacus/invalid-file-extension.png differ diff --git a/slp_abacus/tests/resources/test_resource_paths.py b/slp_abacus/tests/resources/test_resource_paths.py index 8987f9e4..0b11b909 100644 --- a/slp_abacus/tests/resources/test_resource_paths.py +++ b/slp_abacus/tests/resources/test_resource_paths.py @@ -10,3 +10,6 @@ wrong_mxgraphmodel_abacus = f'{abacus}/wrong_mxgraphmodel.abacus' wrong_root_abacus = f'{abacus}/wrong_root.abacus' not_xml = f'{abacus}/not_xml.abacus' +abacus_bad_file_format = f'{abacus}/aws_minimal.drawio' +abacus_bad_file_extension = f'{abacus}/invalid-file-extension.png' +abacus_default_mapping = f'{path}/mapping/iriusrisk-abacus-mapping.yaml' diff --git a/slp_cft/tests/integration/test_cft_processor.py b/slp_cft/tests/integration/test_cft_processor.py index 235affcd..3f406dbd 100644 --- a/slp_cft/tests/integration/test_cft_processor.py +++ b/slp_cft/tests/integration/test_cft_processor.py @@ -36,7 +36,6 @@ OTM_EXPECTED_RESULT = test_resource_paths.otm_expected_result ALTSOURCE_COMPONENTS_OTM_EXPECTED = test_resource_paths.altsource_components_otm_expected - class TestCloudformationProcessor: def test_altsource_components(self): # GIVEN a valid CFT file with altsource resources @@ -759,7 +758,6 @@ def test_invalid_resources_mapping_file(self): @pytest.mark.parametrize('cft_file_size', [FILE_MAX_SIZE + 1, FILE_MIN_SIZE - 1]) def test_min_max_cloudformation_file_sizes(self, cft_file_size): # GIVEN a max file size limit and a valid CFT file - max_file_size_allowed_in_bytes = 1024 * 1024 cloudformation_file = generate_temporary_file(cft_file_size, "test_max_size.txt") # AND a valid CFT mapping file @@ -781,7 +779,7 @@ def test_min_max_mapping_file_sizes(self, mapping_file_size): # GIVEN a valid CFT file with altsource resources cloudformation_file = get_byte_data(SAMPLE_VALID_CFT_FILE) - # AND a invalid size CFT mapping file + # AND an invalid size CFT mapping file mapping_file = generate_temporary_file(mapping_file_size, "test_mapping_sizes.txt") # WHEN the CFT file is processed diff --git a/tests/integration/api/controllers/diagram/abacus/__init__.py b/tests/integration/api/controllers/diagram/abacus/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/integration/api/controllers/diagram/abacus/test_otm_controller_diagram_abacus.py b/tests/integration/api/controllers/diagram/abacus/test_otm_controller_diagram_abacus.py new file mode 100644 index 00000000..58e6b056 --- /dev/null +++ b/tests/integration/api/controllers/diagram/abacus/test_otm_controller_diagram_abacus.py @@ -0,0 +1,98 @@ +import json + +import responses +from fastapi.testclient import TestClient + +from sl_util.sl_util.file_utils import get_byte_data +from slp_base.slp_base.otm_validator import OTMValidator +from slp_base.slp_base.provider_type import application_json +from slp_base.slp_base.schema import Schema +from startleft.startleft.api import fastapi_server +from tests.integration.api.controllers.diagram.test_otm_controller_diagram import get_url +from tests.resources import test_resource_paths + +webapp = fastapi_server.webapp +client = TestClient(webapp) + +SAMPLE_ID = 'id' +SAMPLE_NAME = 'name' +SAMPLE_VALID_FILE = test_resource_paths.abacus_example +SAMPLE_DEFAULT_MAPPING = test_resource_paths.abacus_default_mapping +SAMPLE_CUSTOM_MAPPING = test_resource_paths.abacus_custom_mapping + +OTM_SCHEMA_FILENAME = OTMValidator.schema_filename + + +class TestOTMControllerDiagramAbacus: + @responses.activate + def test_create_otm_ok_default_mapping(self): + # GIVEN a source file + diag_file = get_byte_data(SAMPLE_VALID_FILE) + + # AND a valid default mapping file + default_mapping_file = get_byte_data(SAMPLE_DEFAULT_MAPPING) + + # WHEN processing + file = {'diag_file': (SAMPLE_VALID_FILE, diag_file), + 'default_mapping_file': (SAMPLE_DEFAULT_MAPPING, default_mapping_file)} + body = {'diag_type': 'ABACUS', 'id': SAMPLE_ID, 'name': SAMPLE_NAME} + response = client.post(get_url(), files=file, data=body) + + # THEN the OTM is returned inside the response as valid JSON + assert response.status_code == 201 + assert response.headers.get('content-type') == application_json + otm = json.loads(response.text) + + # AND the OTM is valid according to the OTM schema + schema: Schema = Schema.from_package('otm', OTM_SCHEMA_FILENAME) + schema.validate(otm) + assert schema.valid, f"OTM Schema is not valid: {schema.errors}" + + # AND the OTM contains expected data + assert len(otm['representations']) == 1 + assert len(otm['trustZones']) == 1 + assert len(otm['dataflows']) == 0 + components = otm['components'] + assert len(components) == 8 + assert components[0]['type'] == 'compact-server-side-web-application' + assert components[1]['type'] == 'CD-MSG-BROKER' + assert components[2]['type'] == 'back-end-server' + assert components[3]['type'] == 'other-database' + assert components[4]['type'] == 'CD-CONTENT-DELIVERY-NETWORK' + assert components[5]['type'] == 'compact-server-side-web-application' + assert components[6]['type'] == 'compact-server-side-web-application' + assert components[7]['type'] == 'web-client' + + def test_create_otm_ok_custom_mapping(self): + # GIVEN a source file + diag_file = get_byte_data(SAMPLE_VALID_FILE) + + # AND a valid default mapping file + default_mapping_file = get_byte_data(SAMPLE_DEFAULT_MAPPING) + + # AND a valid custom mapping file + custom_mapping_file = get_byte_data(SAMPLE_CUSTOM_MAPPING) + + # WHEN processing + file = {'diag_file': (SAMPLE_VALID_FILE, diag_file), + 'default_mapping_file': (SAMPLE_DEFAULT_MAPPING, default_mapping_file), + 'custom_mapping_file': (SAMPLE_CUSTOM_MAPPING, custom_mapping_file)} + body = {'diag_type': 'ABACUS', 'id': SAMPLE_ID, 'name': SAMPLE_NAME} + response = client.post(get_url(), files=file, data=body) + + # THEN the OTM is returned inside the response as valid JSON + assert response.status_code == 201 + assert response.headers.get('content-type') == application_json + otm = json.loads(response.text) + assert len(otm['representations']) == 1 + assert len(otm['trustZones']) == 2 + assert len(otm['dataflows']) == 0 + components = otm['components'] + assert len(components) == 7 + assert components[0]['type'] == 'CD-V2-SST-POC-WEBPAGE' + assert components[1]['type'] == 'CD-V2-SST-POC-INTEGRATOR' + assert components[2]['type'] == 'back-end-server' + assert components[3]['type'] == 'other-database' + assert components[4]['type'] == 'CD-V2-SST-POC-WEBPAGE' + assert components[5]['type'] == 'CD-V2-SST-POC-WEBPAGE' + assert components[6]['type'] == 'web-client' diff --git a/tests/integration/api/controllers/diagram/drawio/test_otm_controller_diagram_drawio.py b/tests/integration/api/controllers/diagram/drawio/test_otm_controller_diagram_drawio.py index 35a309f6..bf909fed 100644 --- a/tests/integration/api/controllers/diagram/drawio/test_otm_controller_diagram_drawio.py +++ b/tests/integration/api/controllers/diagram/drawio/test_otm_controller_diagram_drawio.py @@ -3,6 +3,8 @@ import pytest import responses from fastapi.testclient import TestClient +from slp_base.slp_base.provider_type import application_json +from tests.integration.api.controllers.diagram.test_otm_controller_diagram import get_url from tests.resources import test_resource_paths @@ -13,16 +15,8 @@ terraform_aws_simple_components, invalid_extension_mtmt_file webapp = fastapi_server.webapp - client = TestClient(webapp) -json_mime = 'application/json' - - -def get_url(): - return diag_create_otm_controller.PREFIX + diag_create_otm_controller.URL - - class TestOTMControllerDiagramDrawio: @responses.activate @@ -44,7 +38,7 @@ def test_create_otm_multi_page_error(self): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'LoadingDiagramFileError' @@ -78,7 +72,7 @@ def test_create_otm_ok(self, diagram_file_path): # Then assert response.status_code == 201 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json otm = json.loads(response.text) assert len(otm['trustZones']) > 0 assert len(otm['components']) > 0 @@ -107,7 +101,7 @@ def test_custom_mapping_file_override_mapping_file(self, custom_mapping_file_pat # Then the OTM is returned inside the response as JSON assert response.status_code == diag_create_otm_controller.RESPONSE_STATUS_CODE - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json otm = json.loads(response.text) assert otm['otmVersion'] == '0.2.0' @@ -134,7 +128,7 @@ def test_diagram_file_invalid_extensions(self, filepath): # AND the error details are correct assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' diff --git a/tests/integration/api/controllers/diagram/lucid/test_otm_controller_diagram_lucid.py b/tests/integration/api/controllers/diagram/lucid/test_otm_controller_diagram_lucid.py index 9c5316ea..dd1c5037 100644 --- a/tests/integration/api/controllers/diagram/lucid/test_otm_controller_diagram_lucid.py +++ b/tests/integration/api/controllers/diagram/lucid/test_otm_controller_diagram_lucid.py @@ -4,6 +4,7 @@ import responses from fastapi.testclient import TestClient from pytest import mark +from slp_base.slp_base.provider_type import application_json, application_octet_stream from sl_util.sl_util.file_utils import get_byte_data from slp_base.slp_base.errors import DiagramFileNotValidError, MappingFileNotValidError, LoadingMappingFileError, \ @@ -11,24 +12,14 @@ from slp_base.tests.util.otm import validate_and_compare_otm from startleft.startleft.api import fastapi_server from startleft.startleft.api.controllers.diagram import diag_create_otm_controller +from tests.integration.api.controllers.diagram.test_otm_controller_diagram import get_url from tests.resources import test_resource_paths from tests.resources.test_resource_paths import visio_aws_with_tz_and_vpc, default_visio_mapping webapp = fastapi_server.webapp - client = TestClient(webapp) - yaml_mime = 'text/yaml' - -def get_url(): - return diag_create_otm_controller.PREFIX + diag_create_otm_controller.URL - - -octet_stream = 'application/octet-stream' -json_mime = 'application/json' - - class TestOTMControllerDiagramLucid: @responses.activate @@ -56,7 +47,7 @@ def test_create_otm_ok_lucid_aws_with_tz(self): # Then the OTM is returned inside the response as JSON assert response.status_code == diag_create_otm_controller.RESPONSE_STATUS_CODE - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json otm = json.loads(response.text) # and the otm is as expected @@ -88,7 +79,7 @@ def test_create_otm_ok_lucid_aws_with_tz_and_vpc(self): # Then the OTM is returned inside the response as JSON assert response.status_code == diag_create_otm_controller.RESPONSE_STATUS_CODE - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json otm = json.loads(response.text) # and the otm is as expected @@ -102,7 +93,7 @@ def test_response_on_validating_diagram_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a DiagramFileNotValidError @@ -116,7 +107,7 @@ def test_response_on_validating_diagram_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'DiagramFileNotValidError' @@ -132,7 +123,7 @@ def test_response_on_loading_diagram_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -146,7 +137,7 @@ def test_response_on_loading_diagram_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'LoadingDiagramFileError' @@ -162,7 +153,7 @@ def test_response_on_validating_mapping_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -177,7 +168,7 @@ def test_response_on_validating_mapping_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'MappingFileNotValidError' @@ -193,7 +184,7 @@ def test_response_on_loading_mapping_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -208,7 +199,7 @@ def test_response_on_loading_mapping_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'LoadingMappingFileError' @@ -224,7 +215,7 @@ def test_response_on_otm_result_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -238,7 +229,7 @@ def test_response_on_otm_result_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'OTMResultError' @@ -254,7 +245,7 @@ def test_response_on_otm_building_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -268,7 +259,7 @@ def test_response_on_otm_building_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'OTMBuildingError' @@ -290,7 +281,7 @@ def test_response_on_invalid_diagram_file(self, diagram_source, detail): # And the request files diagram_source = bytes(diagram_source) if isinstance(diagram_source, bytearray) else diagram_source - diagram_file = (visio_aws_with_tz_and_vpc, diagram_source, octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, diagram_source, application_octet_stream) mapping_file = ('default_mapping_file', open(default_visio_mapping, 'rb'), yaml_mime) # When I do post on diagram endpoint @@ -300,7 +291,7 @@ def test_response_on_invalid_diagram_file(self, diagram_source, detail): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'DiagramFileNotValidError' @@ -322,7 +313,7 @@ def test_response_on_invalid_mapping_file(self, mapping_source, msg): # And the request files mapping_source = bytes(mapping_source) if isinstance(mapping_source, bytearray) else mapping_source - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = ('default_mapping_file', mapping_source, yaml_mime) # When I do post on diagram endpoint @@ -332,7 +323,7 @@ def test_response_on_invalid_mapping_file(self, mapping_source, msg): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'MappingFileNotValidError' diff --git a/tests/integration/api/controllers/diagram/visio/test_otm_controller_diagram_visio.py b/tests/integration/api/controllers/diagram/visio/test_otm_controller_diagram_visio.py index 215f9174..b552b11c 100644 --- a/tests/integration/api/controllers/diagram/visio/test_otm_controller_diagram_visio.py +++ b/tests/integration/api/controllers/diagram/visio/test_otm_controller_diagram_visio.py @@ -4,6 +4,7 @@ import responses from fastapi.testclient import TestClient from pytest import mark +from slp_base.slp_base.provider_type import application_octet_stream, application_json from sl_util.sl_util.file_utils import get_byte_data from slp_base.slp_base.errors import DiagramFileNotValidError, MappingFileNotValidError, LoadingMappingFileError, \ @@ -11,27 +12,17 @@ from slp_base.tests.util.otm import validate_and_compare_otm from startleft.startleft.api import fastapi_server from startleft.startleft.api.controllers.diagram import diag_create_otm_controller +from tests.integration.api.controllers.diagram.test_otm_controller_diagram import get_url from tests.resources import test_resource_paths from tests.resources.test_resource_paths import visio_aws_with_tz_and_vpc, default_visio_mapping, \ default_visio_mapping_legacy, custom_vpc_mapping, custom_vpc_mapping_legacy, \ visio_create_otm_ok_only_default_mapping webapp = fastapi_server.webapp - client = TestClient(webapp) - VALIDATION_EXCLUDED_REGEX = r"root\[\'dataflows'\]\[.+?\]\['name'\]" - - -def get_url(): - return diag_create_otm_controller.PREFIX + diag_create_otm_controller.URL - - -octet_stream = 'application/octet-stream' -json_mime = 'application/json' yaml_mime = 'text/yaml' - class TestOTMControllerDiagramVisio: @mark.parametrize('mapping', [default_visio_mapping, default_visio_mapping_legacy]) @@ -57,7 +48,7 @@ def test_create_otm_ok_only_default_mapping(self, mapping): # Then the OTM is returned inside the response as JSON assert response.status_code == diag_create_otm_controller.RESPONSE_STATUS_CODE - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json otm = json.loads(response.text) result, expected = validate_and_compare_otm(otm, expected_otm, VALIDATION_EXCLUDED_REGEX) @@ -93,7 +84,7 @@ def test_create_otm_ok_both_mapping_files(self, default_mapping, custom_mapping) # Then the OTM is returned inside the response as JSON assert response.status_code == diag_create_otm_controller.RESPONSE_STATUS_CODE - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json otm = json.loads(response.text) # and the otm is as expected @@ -107,7 +98,7 @@ def test_response_on_validating_diagram_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a DiagramFileNotValidError @@ -121,7 +112,7 @@ def test_response_on_validating_diagram_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'DiagramFileNotValidError' @@ -137,7 +128,7 @@ def test_response_on_loading_diagram_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -151,7 +142,7 @@ def test_response_on_loading_diagram_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'LoadingDiagramFileError' @@ -167,7 +158,7 @@ def test_response_on_validating_mapping_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -182,7 +173,7 @@ def test_response_on_validating_mapping_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'MappingFileNotValidError' @@ -198,7 +189,7 @@ def test_response_on_loading_mapping_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -213,7 +204,7 @@ def test_response_on_loading_mapping_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'LoadingMappingFileError' @@ -229,7 +220,7 @@ def test_response_on_otm_result_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -243,7 +234,7 @@ def test_response_on_otm_result_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'OTMResultError' @@ -259,7 +250,7 @@ def test_response_on_otm_building_error(self, mock_load_source_data): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_file = (default_visio_mapping, open(default_visio_mapping, 'rb'), yaml_mime) # And the mocked method throwing a LoadingDiagramFileError @@ -273,7 +264,7 @@ def test_response_on_otm_building_error(self, mock_load_source_data): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'OTMBuildingError' @@ -295,7 +286,7 @@ def test_response_on_invalid_diagram_file(self, diagram_source, detail): # And the request files diagram_source = bytes(diagram_source) if isinstance(diagram_source, bytearray) else diagram_source - diagram_file = (visio_aws_with_tz_and_vpc, diagram_source, octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, diagram_source, application_octet_stream) mapping_file = ('default_mapping_file', open(default_visio_mapping, 'rb'), yaml_mime) # When I do post on diagram endpoint @@ -305,7 +296,7 @@ def test_response_on_invalid_diagram_file(self, diagram_source, detail): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'DiagramFileNotValidError' @@ -326,7 +317,7 @@ def test_response_on_invalid_mapping_file(self, mapping_source, msg): project_id: str = 'project_A_id' # And the request files - diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), octet_stream) + diagram_file = (visio_aws_with_tz_and_vpc, open(visio_aws_with_tz_and_vpc, 'rb'), application_octet_stream) mapping_source = bytes(mapping_source) if isinstance(mapping_source, bytearray) else mapping_source mapping_file = ('default_mapping_file', mapping_source, yaml_mime) @@ -337,7 +328,7 @@ def test_response_on_invalid_mapping_file(self, mapping_source, msg): # Then the error is returned inside the response as JSON assert response.status_code == 400 - assert response.headers.get('content-type') == json_mime + assert response.headers.get('content-type') == application_json body_response = json.loads(response.text) assert body_response['status'] == '400' assert body_response['error_type'] == 'MappingFileNotValidError' diff --git a/tests/resources/abacus/abacus_merged.json b/tests/resources/abacus/abacus_merged.json new file mode 100644 index 00000000..484e2be9 --- /dev/null +++ b/tests/resources/abacus/abacus_merged.json @@ -0,0 +1,264 @@ +{ + "EEID": 258635, + "Description": "This is a project used for Irius Risk and Abacus integration purposes", + "Name": "POC00012023", + "BaselineElementEEID": 258635, + "Created": "2023-04-25T19:09:26Z", + "CreatedBy": "username", + "Modified": "2023-05-03T12:39:25Z", + "ModifiedBy": "username", + "ComponentTypeEEID": 153, + "ComponentTypeName": "Project", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": 59571, + "OutConnections": [ + { + "EEID": 258636, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258636, + "Created": "2023-04-25T19:10:03Z", + "CreatedBy": "username", + "Modified": "2023-04-25T19:10:03Z", + "ModifiedBy": "username", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258631, + "SinkComponentName": "SST PoC Webpage" + }, + { + "EEID": 258642, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258642, + "Created": "2023-04-25T19:19:05Z", + "CreatedBy": "username", + "Modified": "2023-04-25T19:19:05Z", + "ModifiedBy": "username", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258639, + "SinkComponentName": "SST PoC Integrator" + }, + { + "EEID": 258646, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258646, + "Created": "2023-04-25T19:20:28Z", + "CreatedBy": "username", + "Modified": "2023-04-25T19:20:28Z", + "ModifiedBy": "username", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258643, + "SinkComponentName": "SST PoC Backend" + }, + { + "EEID": 258650, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258650, + "Created": "2023-04-25T19:22:10Z", + "CreatedBy": "username", + "Modified": "2023-04-25T19:22:10Z", + "ModifiedBy": "username", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258647, + "SinkComponentName": "SST PoC Database" + }, + { + "EEID": 258665, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258665, + "Created": "2023-04-25T19:48:54Z", + "CreatedBy": "username", + "Modified": "2023-04-25T19:48:54Z", + "ModifiedBy": "username", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258662, + "SinkComponentName": "SST PoC Static Content" + }, + { + "EEID": 258636, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258636, + "Created": "2023-04-25T19:10:03Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T19:10:03Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258631, + "SinkComponentName": "SST PoC Webpage" + }, + { + "EEID": 258642, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258642, + "Created": "2023-04-25T19:19:05Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T19:19:05Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258639, + "SinkComponentName": "SST PoC Integrator" + }, + { + "EEID": 258646, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258646, + "Created": "2023-04-25T19:20:28Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T19:20:28Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258643, + "SinkComponentName": "SST PoC Backend" + }, + { + "EEID": 258650, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258650, + "Created": "2023-04-25T19:22:10Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T19:22:10Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258647, + "SinkComponentName": "SST PoC Database" + }, + { + "EEID": 258665, + "Description": "", + "Name": "Impacts", + "BaselineElementEEID": 258665, + "Created": "2023-04-25T19:48:54Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T19:48:54Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 173, + "ConnectionTypeName": "Impacts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258635, + "SourceComponentName": "POC00012023", + "SinkComponentEEID": 258662, + "SinkComponentName": "SST PoC Static Content" + }, + { + "EEID": 259247, + "Description": "", + "Name": "Hosts", + "BaselineElementEEID": 259247, + "Created": "2023-04-25T21:00:34Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T21:00:34Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 13890, + "ConnectionTypeName": "Hosts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": 259251, + "SourceComponentEEID": 259244, + "SourceComponentName": "Azure - IFA - Zona 1 (PoC Irius Risk)", + "SinkComponentEEID": 258631, + "SinkComponentName": "SST PoC Webpage" + }, + { + "EEID": 259258, + "Description": "", + "Name": "Hosts", + "BaselineElementEEID": 259258, + "Created": "2023-04-25T21:01:08Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T21:01:08Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 13890, + "ConnectionTypeName": "Hosts", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": 259262, + "SourceComponentEEID": 259255, + "SourceComponentName": "Azure - IFA - Zona 2 (PoC Irius Risk)", + "SinkComponentEEID": 258631, + "SinkComponentName": "SST PoC Webpage" + }, + { + "EEID": 258632, + "Description": "", + "Name": "Requires", + "BaselineElementEEID": 258632, + "Created": "2023-04-25T19:07:36Z", + "CreatedBy": "Gabriel.Rensi.Silva", + "Modified": "2023-04-25T19:07:36Z", + "ModifiedBy": "Gabriel.Rensi.Silva", + "ConnectionTypeEEID": 141, + "ConnectionTypeName": "Requires", + "ArchitectureEEID": 5, + "ArchitectureName": "F1RST", + "ParentEEID": -1, + "SourceComponentEEID": 258631, + "SourceComponentName": "SST PoC Webpage", + "SinkComponentEEID": 51534, + "SinkComponentName": "Angular v12.0.0" + } + ] +} \ No newline at end of file diff --git a/tests/resources/abacus/custom_abacus_mapping.yaml b/tests/resources/abacus/custom_abacus_mapping.yaml new file mode 100644 index 00000000..2ad2f2d3 --- /dev/null +++ b/tests/resources/abacus/custom_abacus_mapping.yaml @@ -0,0 +1,9 @@ +trustzones: + - label: SST PoC Static Content + type: 2ab4effa-40b7-4cd2-ba81-8247d29a6f2d + +components: + - label: SST PoC Integrator + type: CD-V2-SST-POC-INTEGRATOR + - label: SST PoC Webpage + type: CD-V2-SST-POC-WEBPAGE \ No newline at end of file diff --git a/tests/resources/abacus/default_abacus_mapping.yaml b/tests/resources/abacus/default_abacus_mapping.yaml new file mode 100644 index 00000000..170ed52f --- /dev/null +++ b/tests/resources/abacus/default_abacus_mapping.yaml @@ -0,0 +1,18 @@ +trustzones: + - label: Public Cloud + type: b61d6911-338d-46a8-9f39-8dcd24abfe91 + default: true + +components: + - label: SST PoC Integrator + type: CD-MSG-BROKER + - label: SST PoC Webpage + type: compact-server-side-web-application + - label: SST PoC Database + type: other-database + - label: SST PoC Static Content + type: CD-CONTENT-DELIVERY-NETWORK + - label: SST PoC Backend + type: back-end-server + - label: Angular v12.0.0 + type: web-client diff --git a/tests/resources/test_resource_paths.py b/tests/resources/test_resource_paths.py index 04824edf..a25f5fec 100644 --- a/tests/resources/test_resource_paths.py +++ b/tests/resources/test_resource_paths.py @@ -153,3 +153,8 @@ lean_ix_drawio = f'{path}/drawio/lean_ix.drawio.xml' custom_drawio_mapping = f'{path}/drawio/custom_drawio_mapping.yaml' invalid_extension_mtmt_file = f'{path}/drawio/invalid-extension-mtmt-mobile-api.tm7' + +# ABACUS +abacus_example = f'{path}/abacus/abacus_merged.json' +abacus_default_mapping = f'{path}/abacus/default_abacus_mapping.yaml' +abacus_custom_mapping = f'{path}/abacus/custom_abacus_mapping.yaml'