Skip to content

Commit

Permalink
extend tests
Browse files Browse the repository at this point in the history
  • Loading branch information
seebi committed Nov 14, 2023
1 parent eec62ee commit c26f67f
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 19 deletions.
16 changes: 8 additions & 8 deletions cmem_plugin_yaml/parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
TARGET_OPTIONS = OrderedDict(
{
TARGET_JSON_ENTITIES: f"{TARGET_JSON_ENTITIES}: "
"Parsed structure will be send as JSON to the output port (current default).",
"Parsed structure will be send as JSON entities to the output port (current default).",
TARGET_JSON_DATASET: f"{TARGET_JSON_DATASET}: "
"Parsed structure will be is saved in a JSON dataset (advanced option).",
TARGET_ENTITIES: f"{TARGET_ENTITIES}: "
Expand Down Expand Up @@ -141,7 +141,7 @@ def __init__( # noqa: PLR0913

def _raise_error(self, message: str) -> None:
"""Send a report and raise an error"""
if self.execution_context:
if hasattr(self, "execution_context"):
self.execution_context.report.update(
ExecutionReport(
entity_count=0, operation_desc="YAML document parsed", error=message
Expand Down Expand Up @@ -172,10 +172,10 @@ def _validate_config(self) -> None:
f"When using the source mode '{SOURCE_FILE}', "
"you need to select a YAML file."
)
if self.execution_context and not resource_exist(self.project, self.source_file):
self._raise_error(
f"The file '{self.source_file}' does not exist " "in the project."
)
if hasattr(self, "execution_context") and not resource_exist(
self.project, self.source_file
):
self._raise_error(f"The file '{self.source_file}' does not exist in the project.")
if self.target_mode == TARGET_JSON_DATASET and self.target_dataset == "":
self._raise_error(
f"When using the target mode '{TARGET_JSON_DATASET}', "
Expand Down Expand Up @@ -206,7 +206,7 @@ def _get_input(self) -> Path:
# Select a _get_input_* function based on source_mode
get_input = getattr(self, f"_get_input_{self.source_mode}")
except AttributeError as error:
raise ValueError(f"Source mode '{self.source_mode}' not implemented yet.") from error
raise ValueError(f"Source mode not implemented yet: '{self.source_mode}'") from error
with Path.open(file_yaml, "wb") as writer:
get_input(writer)
return file_yaml
Expand Down Expand Up @@ -248,7 +248,7 @@ def _provide_output(self, file_json: Path) -> Entities | None:
# Select a _provide_output_* function based on target_mode
provide_output = getattr(self, f"_provide_output_{self.target_mode}")
except AttributeError as error:
raise ValueError(f"Target mode '{self.target_mode}' not implemented yet.") from error
raise ValueError(f"Target mode not implemented yet: '{self.target_mode}'") from error
return provide_output(file_json)

def execute(self, inputs: Sequence[Entities], context: ExecutionContext) -> Entities | None:
Expand Down
139 changes: 131 additions & 8 deletions tests/test_workflow.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,145 @@
"""Test different source and target modes"""
import io
import json
from pathlib import Path

from cmem_plugin_base.dataintegration.entity import Entities
import pytest
import yaml
from cmem.cmempy.workspace.projects.datasets.dataset import make_new_dataset
from cmem.cmempy.workspace.projects.project import delete_project, make_new_project
from cmem.cmempy.workspace.projects.resources.resource import (
create_resource,
get_resource_response,
)
from cmem_plugin_base.dataintegration.entity import Entities, Entity, EntityPath, EntitySchema
from cmem_plugin_base.dataintegration.parameter.code import YamlCode

from cmem_plugin_yaml.parse import ParseYaml, SOURCE_CODE, TARGET_JSON_ENTITIES
from tests.utils import TestExecutionContext
from cmem_plugin_yaml.parse import (
SOURCE_CODE,
SOURCE_FILE,
TARGET_ENTITIES,
TARGET_JSON_DATASET,
TARGET_JSON_ENTITIES,
ParseYaml,
)
from tests import PROJECT_ROOT
from tests.utils import PROJECT_NAME, TestExecutionContext, needs_cmem

YAML_SOURCE = YamlCode("""---
ttt: 123
""")
DATASET_NAME = "json_dataset"
RESOURCE_NAME = "output_json"
DATASET_TYPE = "json"


@pytest.fixture()
def di_environment() -> object:
"""Provide the DI build project incl. assets."""
make_new_project(PROJECT_NAME)
make_new_dataset(
project_name=PROJECT_NAME,
dataset_name=DATASET_NAME,
dataset_type=DATASET_TYPE,
parameters={"file": RESOURCE_NAME},
autoconfigure=False,
)
with io.StringIO('{"key": "value"}') as response_file:
create_resource(
project_name=PROJECT_NAME,
resource_name=RESOURCE_NAME,
file_resource=response_file,
replace=True,
)
yield {"project": PROJECT_NAME, "dataset": DATASET_NAME, "resource": RESOURCE_NAME}
delete_project(PROJECT_NAME)


def test_bad_configurations() -> None:
"""Test some bad configuration"""
# source mode 'code' without configured YAML code
with pytest.raises(
ValueError, match="you need to enter or paste YAML Source Code in the code field"
):
ParseYaml(
source_mode=SOURCE_CODE,
target_mode=TARGET_JSON_ENTITIES,
source_code=YamlCode(""),
)

# source mode 'file' without configured file
with pytest.raises(ValueError, match="you need to select a YAML file"):
ParseYaml(
source_mode=SOURCE_FILE,
target_mode=TARGET_JSON_ENTITIES,
)

# target mode 'dataset' without configured JSON dataset
with pytest.raises(ValueError, match="you need to select a JSON dataset"):
ParseYaml(
source_mode=SOURCE_CODE,
target_mode=TARGET_JSON_DATASET,
source_code=YamlCode("---"),
)

# yaml not complete
with pytest.raises(TypeError, match="YAML content could not be parsed to a dict or list"):
ParseYaml(
source_mode=SOURCE_CODE,
target_mode=TARGET_JSON_ENTITIES,
source_code=YamlCode("---"),
).execute([], TestExecutionContext())

# unknown source mode
with pytest.raises(ValueError, match="Source mode not implemented yet"):
ParseYaml(
source_mode="not-there",
target_mode=TARGET_JSON_ENTITIES,
source_code=YamlCode(""),
).execute([], TestExecutionContext())

# unknown target mode
with pytest.raises(ValueError, match="Target mode not implemented yet"):
ParseYaml(
source_mode=SOURCE_CODE,
target_mode="not-there",
source_code=YamlCode("ttt: 123"),
).execute([], TestExecutionContext())


def test_code_to_json_entities() -> None:
"""Test source to json entities"""
with Path.open(Path(PROJECT_ROOT) / "Taskfile.yaml") as reader:
yaml_code = reader.read()
yaml_as_dict: dict = yaml.safe_load(yaml_code)
yaml_as_json = json.dumps(yaml_as_dict)

plugin = ParseYaml(
source_mode=SOURCE_CODE,
target_mode=TARGET_JSON_ENTITIES,
source_code=YAML_SOURCE,
source_code=YamlCode(yaml_code),
)
entities: Entities = plugin.execute([], TestExecutionContext())
assert next(entities.entities).values[0]
json_result: str = next(entities.entities).values[0][0]
assert json_result == yaml_as_json


@needs_cmem
def test_entities_to_json_dataset(di_environment: dict) -> None:
"""Test entities to JSON dataset"""
with Path.open(Path(PROJECT_ROOT) / "Taskfile.yaml") as reader:
yaml_code = reader.read()
yaml_as_dict: dict = yaml.safe_load(yaml_code)
yaml_as_json = json.dumps(yaml_as_dict)

schema = EntitySchema(type_uri="urn:x-yaml:document", paths=[EntityPath(path="yaml-src")])
entities = Entities(
iter([Entity(uri="urn:x-yaml:source", values=[[yaml_code]])]), schema=schema
)

plugin = ParseYaml(
source_mode=TARGET_ENTITIES,
target_mode=TARGET_JSON_DATASET,
target_dataset=di_environment["dataset"],
)
plugin.execute(inputs=[entities], context=TestExecutionContext())

with get_resource_response(di_environment["project"], di_environment["resource"]) as response:
assert response.text == yaml_as_json
9 changes: 6 additions & 3 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
UserContext,
)

PROJECT_NAME = "yaml_test_project"


needs_cmem = pytest.mark.skipif(
os.environ.get("CMEM_BASE_URI", "") == "", reason="Needs CMEM configuration"
)
Expand Down Expand Up @@ -43,7 +46,7 @@ class TestPluginContext(PluginContext):

def __init__(
self,
project_id: str = "dummyProject",
project_id: str = PROJECT_NAME,
):
self.project_id = project_id
self.user = TestUserContext()
Expand All @@ -54,7 +57,7 @@ class TestTaskContext(TaskContext):

__test__ = False

def __init__(self, project_id: str = "dummyProject", task_id: str = "dummyTask"):
def __init__(self, project_id: str = PROJECT_NAME, task_id: str = "dummyTask"):
self.project_id = lambda: project_id
self.task_id = lambda: task_id

Expand All @@ -64,7 +67,7 @@ class TestExecutionContext(ExecutionContext):

__test__ = False

def __init__(self, project_id: str = "dummyProject", task_id: str = "dummyTask"):
def __init__(self, project_id: str = PROJECT_NAME, task_id: str = "dummyTask"):
self.report = ReportContext()
self.task = TestTaskContext(project_id=project_id, task_id=task_id)
self.user = TestUserContext()

0 comments on commit c26f67f

Please sign in to comment.