Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature/OPT-1032] to dev #335

Merged
merged 1 commit into from
Oct 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions slp_drawio/slp_drawio/load/diagram_dataflow_loader.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
from typing import List

from slp_drawio.slp_drawio.load.drawio_dict_utils import get_mx_cell_dataflows, get_dataflow_tags
from slp_drawio.slp_drawio.objects.diagram_objects import DiagramDataflow


class DiagramDataflowLoader:

def __init__(self, source: dict):
self.source: dict = source
self._source: dict = source

def load(self) -> [DiagramDataflow]:
return []

result: List[DiagramDataflow] = []

mx_cell_dataflows = get_mx_cell_dataflows(self._source)
for mx_cell in mx_cell_dataflows:
if all(key in mx_cell for key in ['source', 'target']):
result.append(DiagramDataflow(
dataflow_id=mx_cell.get('id'),
name=f'{mx_cell.get("id")}-dataflow',
source_node=mx_cell.get('source'),
destination_node=mx_cell.get('target'),
tags=get_dataflow_tags(mx_cell.get('id'), self._source)
))

return result
21 changes: 16 additions & 5 deletions slp_drawio/slp_drawio/load/drawio_dict_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,32 @@ def __is_mx_cell_dataflow(mx_cell):


def __is_mx_cell_component(mx_cell: Dict):
if 'mxGeometry' not in mx_cell:
mx_geometry = mx_cell.get('mxGeometry', {})
if not all(key in mx_geometry for key in ['height', 'width']):
return False
return not __is_mx_cell_dataflow(mx_cell)


def __get_mx_cell_from_source(source):
def __get_mx_cells(source) -> List[Dict]:
return source.get("mxfile", {}).get("diagram", {}).get("mxGraphModel", {}).get("root", {}).get("mxCell", [])


def get_mx_cell_components(source) -> List[Dict]:
return list(filter(lambda c: __is_mx_cell_component(c), __get_mx_cell_from_source(source)))
return list(filter(lambda c: __is_mx_cell_component(c), __get_mx_cells(source)))


def get_mx_cell_dataflows(source) -> List[Dict]:
return list(filter(lambda c: __is_mx_cell_dataflow(c), __get_mx_cells(source)))


def get_dataflow_tags(dataflow_id: str, source) -> List[str]:
tags: List[str] = []

for mx_cell in __get_mx_cells(source):
if dataflow_id == mx_cell.get('parent') and 'value' in mx_cell:
tags.append(mx_cell['value'])

def get_mxcell_dataflows(source) -> List[Dict]:
return list(filter(lambda c: __is_mx_cell_dataflow(c), __get_mx_cell_from_source(source)))
return tags


def is_multiple_pages(source):
Expand Down
16 changes: 14 additions & 2 deletions slp_drawio/slp_drawio/objects/diagram_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,20 @@ def __str__(self) -> str:

@auto_repr
class DiagramDataflow:
def __init__(self, id: str):
self.otm = Dataflow(dataflow_id=id, name='', source_node=None, destination_node=None)
def __init__(self,
dataflow_id: str,
name: str = '',
source_node: str = None,
destination_node: str = None,
tags: List[str] = None
):
self.otm = Dataflow(
dataflow_id=dataflow_id,
name=name,
source_node=source_node,
destination_node=destination_node,
tags=tags
)


@auto_repr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@
},
"id":"pt2kyrPXSm7H56EBWWGj-2",
"style":"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;",
"edge":"1",
"parent":"1",
"source":"pt2kyrPXSm7H56EBWWGj-1"
"source":"pt2kyrPXSm7H56EBWWGj-1",
"edge":"1"
},
{
"mxGeometry":{
Expand All @@ -46,8 +46,8 @@
},
"id":"pt2kyrPXSm7H56EBWWGj-4",
"style":"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;",
"edge":"1",
"parent":"1"
"parent":"1",
"edge":"1"
},
{
"mxGeometry":{
Expand All @@ -60,8 +60,8 @@
"id":"pt2kyrPXSm7H56EBWWGj-1",
"value":"",
"style":"outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;",
"vertex":"1",
"parent":"1"
"parent":"1",
"vertex":"1"
},
{
"mxGeometry":{
Expand All @@ -88,9 +88,9 @@
},
"id":"pt2kyrPXSm7H56EBWWGj-5",
"style":"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;",
"edge":"1",
"parent":"1",
"target":"pt2kyrPXSm7H56EBWWGj-1"
"target":"pt2kyrPXSm7H56EBWWGj-1",
"edge":"1"
},
{
"mxGeometry":{
Expand All @@ -99,10 +99,28 @@
},
"id":"pt2kyrPXSm7H56EBWWGj-6",
"style":"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;",
"edge":"1",
"parent":"1",
"source":"pt2kyrPXSm7H56EBWWGj-1",
"target":"pt2kyrPXSm7H56EBWWGj-7"
"target":"pt2kyrPXSm7H56EBWWGj-7",
"edge":"1"
},
{
"mxGeometry":{
"mxPoint":{
"y":"1",
"as":"offset"
},
"x":"-0.0044",
"y":"1",
"relative":"1",
"as":"geometry"
},
"id":"m2HWG3bc47D113dpYQm--1",
"value":"Dataflow Info",
"style":"edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];",
"vertex":"1",
"connectable":"0",
"parent":"pt2kyrPXSm7H56EBWWGj-6"
},
{
"mxGeometry":{
Expand All @@ -115,8 +133,8 @@
"id":"pt2kyrPXSm7H56EBWWGj-7",
"value":"",
"style":"outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;",
"vertex":"1",
"parent":"1"
"parent":"1",
"vertex":"1"
},
{
"mxGeometry":{
Expand All @@ -125,15 +143,15 @@
},
"id":"pt2kyrPXSm7H56EBWWGj-8",
"style":"edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;",
"edge":"1",
"parent":"1",
"source":"pt2kyrPXSm7H56EBWWGj-7",
"target":"pt2kyrPXSm7H56EBWWGj-7"
"target":"pt2kyrPXSm7H56EBWWGj-7",
"edge":"1"
}
]
},
"dx":"1364",
"dy":"771",
"dy":"759",
"grid":"1",
"gridSize":"10",
"guides":"1",
Expand All @@ -152,9 +170,10 @@
"id":"KqMttW68mEOmiwTKMwjx"
},
"host":"app.diagrams.net",
"modified":"2023-10-19T16:09:41.010Z",
"agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36",
"etag":"53oyWIo9RTndIs_Ustab",
"version":"22.0.5"
"modified":"2023-10-25T06:52:34.609Z",
"agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36",
"etag":"gHENJeu3QhVxARD-wiXo",
"version":"22.0.7",
"type":"device"
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" modified="2023-10-19T16:09:41.010Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36" etag="53oyWIo9RTndIs_Ustab" version="22.0.5">
<mxfile host="app.diagrams.net" modified="2023-10-25T06:52:34.609Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36" etag="gHENJeu3QhVxARD-wiXo" version="22.0.7" type="device">
<diagram name="Page-1" id="KqMttW68mEOmiwTKMwjx">
<mxGraphModel dx="1364" dy="771" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<mxGraphModel dx="1364" dy="759" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="pt2kyrPXSm7H56EBWWGj-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="pt2kyrPXSm7H56EBWWGj-1">
<mxCell id="pt2kyrPXSm7H56EBWWGj-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="pt2kyrPXSm7H56EBWWGj-1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="308.25" y="230" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1">
<mxCell id="pt2kyrPXSm7H56EBWWGj-4" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="210" y="240" as="targetPoint" />
<mxPoint x="210" y="340" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-1" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" vertex="1" parent="1">
<mxCell id="pt2kyrPXSm7H56EBWWGj-1" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" parent="1" vertex="1">
<mxGeometry x="270" y="340" width="76.5" height="73" as="geometry" />
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" target="pt2kyrPXSm7H56EBWWGj-1">
<mxCell id="pt2kyrPXSm7H56EBWWGj-5" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" target="pt2kyrPXSm7H56EBWWGj-1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="308" y="490" as="sourcePoint" />
<Array as="points">
Expand All @@ -28,13 +27,18 @@
</Array>
</mxGeometry>
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="pt2kyrPXSm7H56EBWWGj-1" target="pt2kyrPXSm7H56EBWWGj-7">
<mxCell id="pt2kyrPXSm7H56EBWWGj-6" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="pt2kyrPXSm7H56EBWWGj-1" target="pt2kyrPXSm7H56EBWWGj-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-7" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" vertex="1" parent="1">
<mxCell id="m2HWG3bc47D113dpYQm--1" value="Dataflow Info" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="pt2kyrPXSm7H56EBWWGj-6">
<mxGeometry x="-0.0044" y="1" relative="1" as="geometry">
<mxPoint y="1" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-7" value="" style="outlineConnect=0;dashed=0;verticalLabelPosition=bottom;verticalAlign=top;align=center;html=1;shape=mxgraph.aws3.ec2;fillColor=#F58534;gradientColor=none;" parent="1" vertex="1">
<mxGeometry x="460" y="330" width="76.5" height="93" as="geometry" />
</mxCell>
<mxCell id="pt2kyrPXSm7H56EBWWGj-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="pt2kyrPXSm7H56EBWWGj-7" target="pt2kyrPXSm7H56EBWWGj-7">
<mxCell id="pt2kyrPXSm7H56EBWWGj-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="pt2kyrPXSm7H56EBWWGj-7" target="pt2kyrPXSm7H56EBWWGj-7" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
</root>
Expand Down
2 changes: 1 addition & 1 deletion slp_drawio/tests/resources/test_resource_paths.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
aws_minimal_drawio_as_json = f'{drawio}/aws_minimal_source.json'
aws_multiple_pages_drawio = f'{drawio}/aws_multiple_pages.drawio'
aws_multiple_pages_drawio_as_json = f'{drawio}/aws_multiple_pages.json'
aws_two_component_multiple_dataflows = f'{drawio}/aws_two_component_multiple_dataflows.json'
aws_two_component_multiple_dataflows_as_json = f'{drawio}/aws_two_component_multiple_dataflows.json'
wrong_mxcell_drawio = f'{drawio}/wrong_mxcell.drawio'
wrong_mxfile_drawio = f'{drawio}/wrong_mxfile.drawio'
wrong_mxgraphmodel_drawio = f'{drawio}/wrong_mxgraphmodel.drawio'
Expand Down
38 changes: 38 additions & 0 deletions slp_drawio/tests/unit/load/test_diagram_dataflow_loader.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import json
from unittest.mock import patch

from sl_util.sl_util.file_utils import get_byte_data
from slp_drawio.slp_drawio.load.diagram_dataflow_loader import DiagramDataflowLoader
from slp_drawio.slp_drawio.load.drawio_dict_utils import get_dataflow_tags
from slp_drawio.tests.resources import test_resource_paths


class TestDiagramDataflowLoader:

@patch('slp_drawio.slp_drawio.load.diagram_dataflow_loader.get_dataflow_tags', wraps=get_dataflow_tags)
def test_load(self, get_dataflow_tags_wrapper):
# GIVEN a DrawIO
source = json.loads(get_byte_data(test_resource_paths.aws_two_component_multiple_dataflows_as_json))

# WHEN DiagramDataflowLoader::load
diagram_dataflows = DiagramDataflowLoader(source).load()

# THEN diagram dataflows has length of 2
assert len(diagram_dataflows) == 2
# AND elements has the following information
assert diagram_dataflows[0].otm.id == 'pt2kyrPXSm7H56EBWWGj-6'
assert diagram_dataflows[0].otm.name == 'pt2kyrPXSm7H56EBWWGj-6-dataflow'
assert diagram_dataflows[0].otm.source_node == 'pt2kyrPXSm7H56EBWWGj-1'
assert diagram_dataflows[0].otm.destination_node == 'pt2kyrPXSm7H56EBWWGj-7'
assert len(diagram_dataflows[0].otm.tags) == 1
assert diagram_dataflows[0].otm.tags[0] == 'Dataflow Info'

# AND self reference dataflow is also mapped
assert diagram_dataflows[1].otm.id == 'pt2kyrPXSm7H56EBWWGj-8'
assert diagram_dataflows[1].otm.name == 'pt2kyrPXSm7H56EBWWGj-8-dataflow'
assert diagram_dataflows[1].otm.source_node == 'pt2kyrPXSm7H56EBWWGj-7'
assert diagram_dataflows[1].otm.destination_node == 'pt2kyrPXSm7H56EBWWGj-7'
assert len(diagram_dataflows[1].otm.tags) == 0

# AND the method get_dataflow_tags has been called once for each dataflow
assert get_dataflow_tags_wrapper.call_count == len(diagram_dataflows)
28 changes: 25 additions & 3 deletions slp_drawio/tests/unit/load/test_drawio_dict_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

# class TestDrawioDictUtils:
import json
from unittest.mock import patch

import pytest

Expand Down Expand Up @@ -48,7 +49,7 @@ def test_is_multiple_pages(source, expected):

def test_get_mx_cell_components():
# GIVEN a DrawIO with one component and Dataflow with multiple configurations
source = json.loads(get_byte_data(test_resource_paths.aws_two_component_multiple_dataflows))
source = json.loads(get_byte_data(test_resource_paths.aws_two_component_multiple_dataflows_as_json))

# WHEN drawio_dict_utils::get_components_from_source
components = drawio_dict_utils.get_mx_cell_components(source)
Expand All @@ -59,15 +60,36 @@ def test_get_mx_cell_components():

def test_get_mx_cell_dataflows():
# GIVEN a DrawIO with one component and Dataflow with multiple configurations
source = json.loads(get_byte_data(test_resource_paths.aws_two_component_multiple_dataflows))
source = json.loads(get_byte_data(test_resource_paths.aws_two_component_multiple_dataflows_as_json))

# WHEN drawio_dict_utils::get_components_from_source
dataflows = drawio_dict_utils.get_mxcell_dataflows(source)
dataflows = drawio_dict_utils.get_mx_cell_dataflows(source)

# THEN it returns 5 dataflows
assert len(dataflows) == 5


@patch('slp_drawio.slp_drawio.load.drawio_dict_utils.__get_mx_cells')
@pytest.mark.parametrize('dataflow_id, source, expected', [
pytest.param('1', [], [], id="tags are empty"),
pytest.param('1', [{'parent': '2'}, {'parent': '1', 'value': 'tag'}], ['tag'], id="tags has one value"),
pytest.param('1', [{'parent': '1', 'value': 'tag'}, {'parent': '1', 'value': 'tag2'}], ['tag', 'tag2'],
id="tags has two values"),
pytest.param('1', [{'parent': '2', 'value': 'tag'}], [], id="tags is empty as not child exists"),
pytest.param('1', [{'parent': '1'}], [], id="tags is empty as not value exists"),
])
def test_get_dataflow_tags(__get_mx_cells_mock, dataflow_id: str, source, expected):
# GIVEN the dataflow_id
# AND the get_mx_cells returning the given source
__get_mx_cells_mock.return_value = source

# WHEN drawio_dict_utils::get_dataflow_tags
tags = drawio_dict_utils.get_dataflow_tags(dataflow_id, {})

# THEN the tags are as expected
assert tags == expected


@pytest.mark.parametrize('mx_geometry, expected', [
pytest.param({}, {'x': 0, 'y': 0}, id="without position"),
pytest.param({'x': '10'}, {'x': 10, 'y': 0}, id="only with x value"),
Expand Down