def test_preview_already_up_to_date(self):
        self.os_mock.path.isdir.side_effect = lambda path: {
            "/tmp/target-repo/my-app-685912d3-preview":
            True,  # already exists -> expect update
        }[path]

        self.update_yaml_file_mock.return_value = False  # nothing updated -> expect already up to date

        deployment_already_up_to_date_callback = Mock(return_value=None)

        command = CreatePreviewCommand(ARGS)
        command.register_callbacks(
            deployment_already_up_to_date_callback=
            deployment_already_up_to_date_callback,
            deployment_updated_callback=lambda route_host: self.fail(
                "should not be called"),
            deployment_created_callback=lambda route_host: self.fail(
                "should not be called"),
        )
        command.execute()

        deployment_already_up_to_date_callback.assert_called_once_with(
            "app.xy-685912d3.example.tld")

        assert self.mock_manager.method_calls == [
            call.load_gitops_config(
                ARGS,
                "ORGA",
                "REPO",
            ),
            call.yaml_file_dump(
                INFO_YAML,
                "/tmp/gitopscli-preview-info.yaml",
            ),
            call.GitRepoApiFactory.create(
                ARGS,
                "PREVIEW_TARGET_ORG",
                "PREVIEW_TARGET_REPO",
            ),
            call.GitRepo(self.target_git_repo_api_mock),
            call.GitRepo.clone(None),
            call.GitRepoApiFactory.create(
                ARGS,
                "PREVIEW_TEMPLATE_ORG",
                "PREVIEW_TEMPLATE_REPO",
            ),
            call.GitRepo(self.template_git_repo_api_mock),
            call.GitRepo.clone("template-branch"),
            call.GitRepo.get_full_file_path("my-app-685912d3-preview"),
            call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"),
            call.logging.info("Use existing folder for preview: %s",
                              "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/Chart.yaml"),
            call.update_yaml_file(
                "/tmp/target-repo/my-app-685912d3-preview/Chart.yaml", "name",
                "my-app-685912d3-preview"),
            call.logging.info("Keep property '%s' in '%s' value: %s", "name",
                              "Chart.yaml", "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/target-repo/my-app-685912d3-preview/values.yaml",
                "image.tag",
                "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9",
            ),
            call.logging.info(
                "Keep property '%s' in '%s' value: %s",
                "image.tag",
                "values.yaml",
                "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9",
            ),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/target-repo/my-app-685912d3-preview/values.yaml",
                "route.host", "app.xy-685912d3.example.tld"),
            call.logging.info("Keep property '%s' in '%s' value: %s",
                              "route.host", "values.yaml",
                              "app.xy-685912d3.example.tld"),
            call.logging.info(
                "The preview is already up-to-date. I'm done here."),
        ]
    def test_create_new_preview(self):
        self.os_mock.path.isdir.side_effect = lambda path: {
            "/tmp/created-tmp-dir/my-app-685912d3-preview":
            False,  # doesn't exist yet -> expect create
            "/tmp/created-tmp-dir/.preview-templates/my-app": True,
        }[path]

        deployment_created_callback = Mock(return_value=None)

        command = CreatePreviewCommand(ARGS)
        command.register_callbacks(
            deployment_already_up_to_date_callback=lambda route_host: self.
            fail("should not be called"),
            deployment_updated_callback=lambda route_host: self.fail(
                "should not be called"),
            deployment_created_callback=deployment_created_callback,
        )
        command.execute()

        deployment_created_callback.assert_called_once_with(
            "app.xy-685912d3.example.tld")

        assert self.mock_manager.method_calls == [
            call.load_gitops_config(
                ARGS,
                "ORGA",
                "REPO",
            ),
            call.yaml_file_dump(
                {
                    "previewId": "PREVIEW_ID",
                    "previewIdHash": "685912d3",
                    "routeHost": "app.xy-685912d3.example.tld",
                    "namespace": "my-app-685912d3-preview",
                },
                "/tmp/gitopscli-preview-info.yaml",
            ),
            call.GitRepoApiFactory.create(
                ARGS,
                "TEAM_CONFIG_ORG",
                "TEAM_CONFIG_REPO",
            ),
            call.GitRepo(self.git_repo_api_mock),
            call.GitRepo.clone(),
            call.GitRepo.get_full_file_path("my-app-685912d3-preview"),
            call.os.path.isdir("/tmp/created-tmp-dir/my-app-685912d3-preview"),
            call.logging.info("Create new folder for preview: %s",
                              "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(".preview-templates/my-app"),
            call.os.path.isdir(
                "/tmp/created-tmp-dir/.preview-templates/my-app"),
            call.logging.info("Using the preview template folder: %s",
                              ".preview-templates/my-app"),
            call.shutil.copytree(
                "/tmp/created-tmp-dir/.preview-templates/my-app",
                "/tmp/created-tmp-dir/my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/Chart.yaml"),
            call.update_yaml_file(
                "/tmp/created-tmp-dir/my-app-685912d3-preview/Chart.yaml",
                "name", "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml",
                "image.tag",
                "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9",
            ),
            call.logging.info("Replaced property '%s' with value: %s",
                              "image.tag",
                              "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml",
                "route.host", "app.xy-685912d3.example.tld"),
            call.logging.info("Replaced property '%s' with value: %s",
                              "route.host", "app.xy-685912d3.example.tld"),
            call.GitRepo.commit(
                "GIT_USER",
                "GIT_EMAIL",
                "Create new preview environment for 'my-app' and git hash '3361723dbd91fcfae7b5b8b8b7d462fbc14187a9'.",
            ),
            call.GitRepo.push(),
        ]
    def test_create_new_preview_from_same_template_target_repo(self):
        gitops_config: GitOpsConfig = self.load_gitops_config_mock.return_value
        self.load_gitops_config_mock.return_value = GitOpsConfig(
            api_version=gitops_config.api_version,
            application_name=gitops_config.application_name,
            preview_host_template=gitops_config.preview_host_template,
            preview_template_organisation=gitops_config.
            preview_target_organisation,  # template = target
            preview_template_repository=gitops_config.
            preview_target_repository,  # template = target
            preview_template_path_template=gitops_config.
            preview_template_path_template,
            preview_template_branch=gitops_config.
            preview_target_branch,  # template = target
            preview_target_organisation=gitops_config.
            preview_target_organisation,
            preview_target_repository=gitops_config.preview_target_repository,
            preview_target_branch=gitops_config.preview_target_branch,
            preview_target_namespace_template=gitops_config.
            preview_target_namespace_template,
            preview_target_max_namespace_length=gitops_config.
            preview_target_max_namespace_length,
            replacements=gitops_config.replacements,
        )

        self.os_mock.path.isdir.side_effect = lambda path: {
            "/tmp/target-repo/my-app-685912d3-preview":
            False,  # doesn't exist yet -> expect create
            "/tmp/target-repo/.preview-templates/my-app": True,
        }[path]

        deployment_created_callback = Mock(return_value=None)

        command = CreatePreviewCommand(ARGS)
        command.register_callbacks(
            deployment_already_up_to_date_callback=lambda route_host: self.
            fail("should not be called"),
            deployment_updated_callback=lambda route_host: self.fail(
                "should not be called"),
            deployment_created_callback=deployment_created_callback,
        )
        command.execute()

        deployment_created_callback.assert_called_once_with(
            "app.xy-685912d3.example.tld")

        assert self.mock_manager.method_calls == [
            call.load_gitops_config(
                ARGS,
                "ORGA",
                "REPO",
            ),
            call.yaml_file_dump(
                {
                    "previewId": "PREVIEW_ID",
                    "previewIdHash": "685912d3",
                    "routeHost": "app.xy-685912d3.example.tld",
                    "namespace": "my-app-685912d3-preview",
                },
                "/tmp/gitopscli-preview-info.yaml",
            ),
            call.GitRepoApiFactory.create(
                ARGS,
                "PREVIEW_TARGET_ORG",
                "PREVIEW_TARGET_REPO",
            ),  # only clone once for template and target
            call.GitRepo(self.target_git_repo_api_mock),
            call.GitRepo.clone(None),
            call.GitRepo.get_full_file_path("my-app-685912d3-preview"),
            call.os.path.isdir("/tmp/target-repo/my-app-685912d3-preview"),
            call.logging.info("Create new folder for preview: %s",
                              "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(".preview-templates/my-app"),
            call.os.path.isdir("/tmp/target-repo/.preview-templates/my-app"),
            call.logging.info("Using the preview template folder: %s",
                              ".preview-templates/my-app"),
            call.shutil.copytree("/tmp/target-repo/.preview-templates/my-app",
                                 "/tmp/target-repo/my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/Chart.yaml"),
            call.update_yaml_file(
                "/tmp/target-repo/my-app-685912d3-preview/Chart.yaml", "name",
                "my-app-685912d3-preview"),
            call.logging.info("Replaced property '%s' in '%s' with value: %s",
                              "name", "Chart.yaml", "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/target-repo/my-app-685912d3-preview/values.yaml",
                "image.tag",
                "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9",
            ),
            call.logging.info(
                "Replaced property '%s' in '%s' with value: %s",
                "image.tag",
                "values.yaml",
                "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9",
            ),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/target-repo/my-app-685912d3-preview/values.yaml",
                "route.host", "app.xy-685912d3.example.tld"),
            call.logging.info(
                "Replaced property '%s' in '%s' with value: %s",
                "route.host",
                "values.yaml",
                "app.xy-685912d3.example.tld",
            ),
            call.GitRepo.commit(
                "GIT_USER",
                "GIT_EMAIL",
                "Create new preview environment for 'my-app' and git hash '3361723dbd91fcfae7b5b8b8b7d462fbc14187a9'.",
            ),
            call.GitRepo.push(),
        ]
    def test_update_existing_preview(self):
        self.os_mock.path.isdir.side_effect = lambda path: {
            "/tmp/created-tmp-dir/my-app-685912d3-preview":
            True,  # already exists -> expect update
        }[path]

        deployment_updated_callback = Mock(return_value=None)

        command = CreatePreviewCommand(ARGS)
        command.register_callbacks(
            deployment_already_up_to_date_callback=lambda route_host: self.
            fail("should not be called"),
            deployment_updated_callback=deployment_updated_callback,
            deployment_created_callback=lambda route_host: self.fail(
                "should not be called"),
        )
        command.execute()

        deployment_updated_callback.assert_called_once_with(
            "app.xy-685912d3.example.tld")

        assert self.mock_manager.method_calls == [
            call.load_gitops_config(
                ARGS,
                "ORGA",
                "REPO",
            ),
            call.yaml_file_dump(
                INFO_YAML,
                "/tmp/gitopscli-preview-info.yaml",
            ),
            call.GitRepoApiFactory.create(
                ARGS,
                "TEAM_CONFIG_ORG",
                "TEAM_CONFIG_REPO",
            ),
            call.GitRepo(self.git_repo_api_mock),
            call.GitRepo.clone(),
            call.GitRepo.get_full_file_path("my-app-685912d3-preview"),
            call.os.path.isdir("/tmp/created-tmp-dir/my-app-685912d3-preview"),
            call.logging.info("Use existing folder for preview: %s",
                              "my-app-685912d3-preview"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml",
                "image.tag",
                "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9",
            ),
            call.logging.info("Replaced property '%s' with value: %s",
                              "image.tag",
                              "3361723dbd91fcfae7b5b8b8b7d462fbc14187a9"),
            call.GitRepo.get_full_file_path(
                "my-app-685912d3-preview/values.yaml"),
            call.update_yaml_file(
                "/tmp/created-tmp-dir/my-app-685912d3-preview/values.yaml",
                "route.host", "app.xy-685912d3.example.tld"),
            call.logging.info("Replaced property '%s' with value: %s",
                              "route.host", "app.xy-685912d3.example.tld"),
            call.GitRepo.commit(
                "GIT_USER",
                "GIT_EMAIL",
                "Update preview environment for 'my-app' and git hash '3361723dbd91fcfae7b5b8b8b7d462fbc14187a9'.",
            ),
            call.GitRepo.push(),
        ]