diff --git a/features/backup_plan_model_update.feature b/features/backup_plan_model_update.feature new file mode 100644 index 0000000..7b5896e --- /dev/null +++ b/features/backup_plan_model_update.feature @@ -0,0 +1,30 @@ +Feature: Update a backup plan + + @fixture.injector + @fixture.in_memory_database + @fixture.seeds + Scenario Outline: Update a backup plan's fields + Given I have a backup plan with id="" + When I update the backup plan with id="" and data="" + Then the result should be "" + + Examples: + | backup_plan_id | existing_backup_plan_id | updated_data | result | description | + | 8aa59e7e-dc75-459b-beb5-b710b39be583 | 8aa59e7e-dc75-459b-beb5-b710b39be583 | {"label": "new_label"} | success | update an existing plan | + | 8aa59e7e-dc75-459b-aeb5-b710b39be583 | 8aa59e7e-dc75-459b-beb5-b710b39be512 | {"label": "new_label"} | error | update a non-existing plan | + + @fixture.injector + @fixture.in_memory_database + @fixture.seeds + Scenario Outline: Updated backup plan's fields must be updated + Given I have a backup plan with id="" + When I update the backup plan with id="" and data="" + And I read the backup plan with id="" + Then the result should be "" + And the backup_plan must have same field: "" + + Examples: + | backup_plan_id | existing_backup_plan_id | updated_data | result | description | + | 8aa59e7e-dc75-459b-beb5-b710b39be583 | 8aa59e7e-dc75-459b-beb5-b710b39be583 | {"label": "new_label"} | success | update the label | + | 8aa59e7e-dc75-459b-beb5-b710b39be583 | 8aa59e7e-dc75-459b-beb5-b710b39be583 | {"source": "/new/mnt"} | success | update the source | + | 8aa59e7e-dc75-459b-beb5-b710b39be583 | 8aa59e7e-dc75-459b-beb5-b710b39be583 | {"destinations": ["/mnt2", "/mnt3"]} | success | update the destinations | diff --git a/features/steps/backup_plan_model_steps.py b/features/steps/backup_plan_model_steps.py index 01dba6d..a32f6ec 100644 --- a/features/steps/backup_plan_model_steps.py +++ b/features/steps/backup_plan_model_steps.py @@ -1,6 +1,8 @@ from behave import given, when, then import json +from features.support.backup_plan_helpers import compare_destinations, update_backup_plan, compare_backup_plan_fields +from features.support.helpers import json_to_dict from tui_rsync.core.components.backup_plan.application.services import RemoveAllBackupPlansService from tui_rsync.core.components.backup_plan.application.services.backup_plan_service import BackupPlanService from tui_rsync.core.components.backup_plan.domain import BackupPlan, Source, Destination @@ -42,6 +44,21 @@ def add_backup_plan(context): context.exception_raised = False +@when('I update the backup plan with id="{backup_plan_id}" and data="{updated_data_json}"') +def when_update_backup_plan_with_id(context, backup_plan_id, updated_data_json): + try: + context.backup_plan_service = context.injector.get(BackupPlanService) + context.backup_plan = context.backup_plan_service.get_by_id(UUID(backup_plan_id)) + + update_backup_plan(context.backup_plan, json_to_dict(updated_data_json)) + + context.backup_plan_service.update(context.backup_plan) + except QueryException as e: + context.exception_raised = True + else: + context.exception_raised = False + + @when('I remove the backup plan with id="{backup_plan_id}"') def when_remove_backup_plan_with_id(context, backup_plan_id): try: @@ -68,18 +85,13 @@ def when_remove_all_backup_plans(context): def when_read_backup_plan_with_id(context, backup_plan_id): try: context.backup_plan_service = context.injector.get(BackupPlanService) - context.backup_plan_service.get_by_id(UUID(backup_plan_id)) + context.backup_plan = context.backup_plan_service.get_by_id(UUID(backup_plan_id)) except QueryException as e: context.exception_raised = True else: context.exception_raised = False -def compare_destinations(actual: list[Destination], expected: list[str]) -> bool: - actual_path_set = {destionation.path for destionation in actual} - return actual_path_set == set(expected) - - @then('it should be created successfully') def backup_plan_has_added(context): assert context.exception_raised == False @@ -108,3 +120,7 @@ def then_cli_executed_successfully(context, result): assert result == str(context.result_value) +@then('the backup_plan must have same field: "{fields_json}"') +def backup_plan_has_added(context, fields_json): + assert compare_backup_plan_fields(context.backup_plan, json_to_dict(fields_json)) + diff --git a/features/support/backup_plan_helpers.py b/features/support/backup_plan_helpers.py new file mode 100644 index 0000000..f63f540 --- /dev/null +++ b/features/support/backup_plan_helpers.py @@ -0,0 +1,57 @@ +from features.support.helpers import json_to_dict +from tui_rsync.core.components.backup_plan.domain import Destination, BackupPlan, Source + + +def json_to_backup_plan(backup_plan_json): + fields = json_to_dict(backup_plan_json) + + backup_plan = BackupPlan( + label=fields['label'], + source=Source(fields['source']), + destinations=list(map(lambda path: Destination(path), fields['destinations'])), + ) + + return backup_plan + + +def update_backup_plan(backup_plan, fields: dict): + for field, value in fields.items(): + match field: + case 'label': + backup_plan.label = value + case 'source': + backup_plan.source = Source(value) + case 'destinations': + backup_plan.destinations = list(map(lambda path: Destination(path), value)) + + return backup_plan + + +def compare_backup_plan_fields(backup_plan, fields: dict): + for field, value in fields.items(): + match field: + case 'label': + if backup_plan.label != value: + return False + case 'source': + if backup_plan.source.path != value: + return False + case 'destinations': + if not compare_destinations(backup_plan.destinations, value): + return False + + return True + + +def compare_destinations(actual: list[Destination], expected: list[str]) -> bool: + actual_path_set = {destionation.path for destionation in actual} + return actual_path_set == set(expected) + + +def compare_backup_plans(backup_plan, expected): + return backup_plan.label == expected.label \ + and backup_plan.source == expected.source_path \ + and compare_destinations( + backup_plan.destinations, + expected.destinations + ) diff --git a/features/support/helpers.py b/features/support/helpers.py new file mode 100644 index 0000000..8f7f291 --- /dev/null +++ b/features/support/helpers.py @@ -0,0 +1,5 @@ +import json + + +def json_to_dict(json_data): + return json.loads(json_data)