Exemple #1
0
def test_pre_commit_autoinstall(tmp_path: Path, supported_odoo_version: float):
    """Testea que pre-commit se (des)instala automaticamente en repos alien.

    Esta prueba es más lenta porque tiene que descargar y construir imágenes
    OCI y descargar código git, por lo que solo se ejecuta en estas versiones
    de Odoo:

    - 10.0 porque es Python 2 y no tiene configuraciones de confirmación previa en OCA.
    - 13.0 porque es Python 3 y tiene configuraciones de confirmación previa en OCA..
    """
    if supported_odoo_version not in {10.0, 13.0}:
        pytest.skip("esta prueba solo se testea con otras versiones de odoo")
    copy(
        ".",
        str(tmp_path),
        vcs_ref="HEAD",
        force=True,
        data={"odoo_version": supported_odoo_version},
    )
    with local.cwd(tmp_path):
        with (tmp_path / "odoo" / "custom" / "src" /
              "addons.yaml").open("w") as fd:
            yaml.dump({"server-tools": "*"}, fd)
        # El usuario puede descargar el código git desde cualquier carpeta
        with local.cwd(tmp_path / "odoo" / "custom" / "src" / "private"):
            invoke("git-aggregate")
        # Check pre-commit está correctamente (des)instalado
        pre_commit_present = supported_odoo_version >= 13.0
        server_tools_git = (tmp_path / "odoo" / "custom" / "src" /
                            "server-tools" / ".git")
        assert server_tools_git.is_dir()
        assert (server_tools_git / "hooks" /
                "pre-commit").is_file() == pre_commit_present
    # Elimine el código fuente, puede usar mucho espacio en disco
    rmtree(tmp_path)
Exemple #2
0
def test_v1_5_2_migration(tmp_path: Path, cloned_template: Path,
                          supported_odoo_version: float):
    """Test migration to v1.5.2."""
    auto = tmp_path / "odoo" / "auto"
    empty = auto / ".empty"  # This file existed in doodba-scaffolding
    with local.cwd(tmp_path):
        # Copy v1.5.1
        copy(
            src_path=str(cloned_template),
            vcs_ref="v1.5.1",
            force=True,
            data={"odoo_version": supported_odoo_version},
        )
        auto.mkdir()
        empty.touch()
        assert empty.exists()
        git("add", ".")
        git("add", "-f", empty)
        git("commit", "-am", "reformat", retcode=1)
        git("commit", "-am", "copied from template in v1.5.1")
        # Update to v1.5.2
        copy(vcs_ref="v1.5.2", force=True)
        assert not empty.exists()
        assert not auto.exists()
        invoke("develop")
        assert auto.exists()
        assert not empty.exists()
Exemple #3
0
def test_code_workspace_file(tmp_path: Path, cloned_template: Path):
    """The file is generated as expected."""
    copy(
        str(cloned_template), str(tmp_path), vcs_ref="HEAD", force=True,
    )
    assert (tmp_path / f"doodba.{tmp_path.name}.code-workspace").is_file()
    (tmp_path / f"doodba.{tmp_path.name}.code-workspace").rename(
        tmp_path / "doodba.other1.code-workspace"
    )
    with local.cwd(tmp_path):
        invoke("write-code-workspace-file")
        assert (tmp_path / "doodba.other1.code-workspace").is_file()
        assert not (tmp_path / f"doodba.{tmp_path.name}.code-workspace").is_file()
        # Do a stupid and dirty git clone to check it's sorted fine
        git("clone", cloned_template, Path("odoo", "custom", "src", "zzz"))
        invoke("write-code-workspace-file", "-c", "doodba.other2.code-workspace")
        assert not (tmp_path / f"doodba.{tmp_path.name}.code-workspace").is_file()
        assert (tmp_path / "doodba.other1.code-workspace").is_file()
        assert (tmp_path / "doodba.other2.code-workspace").is_file()
        with (tmp_path / "doodba.other2.code-workspace").open() as fp:
            workspace_definition = json.load(fp)
        assert workspace_definition == {
            "folders": [
                {"path": "odoo/custom/src/zzz"},
                {"path": "odoo/custom/src/private"},
                {"path": "."},
            ]
        }
Exemple #4
0
def test_pre_commit_autoinstall(tmp_path: Path, supported_odoo_version: float):
    """Test that pre-commit is automatically (un)installed in alien repos.

    This test is slower because it has to download and build OCI images and
    download git code, so it's only executed against these Odoo versions:

    - 10.0 because it's Python 2 and has no pre-commit configurations in OCA.
    - 13.0 because it's Python 3 and has pre-commit configurations in OCA.
    """
    if supported_odoo_version not in {10.0, 13.0}:
        pytest.skip("this test is only tested with other odoo versions")
    copy(
        ".",
        str(tmp_path),
        vcs_ref="HEAD",
        force=True,
        data={"odoo_version": supported_odoo_version},
    )
    with local.cwd(tmp_path):
        with (tmp_path / "odoo" / "custom" / "src" / "addons.yaml").open("w") as fd:
            yaml.dump({"server-tools": "*"}, fd)
        # User can download git code from any folder
        with local.cwd(tmp_path / "odoo" / "custom" / "src" / "private"):
            invoke("git-aggregate")
        # Check pre-commit is properly (un)installed
        pre_commit_present = supported_odoo_version >= 13.0
        server_tools_git = (
            tmp_path / "odoo" / "custom" / "src" / "server-tools" / ".git"
        )
        assert server_tools_git.is_dir()
        assert (
            server_tools_git / "hooks" / "pre-commit"
        ).is_file() == pre_commit_present
    # Remove source code, it can use a lot of disk space
    rmtree(tmp_path)
def test_start(
    cloned_template: Path,
    docker: LocalCommand,
    supported_odoo_version: float,
    tmp_path: Path,
):
    """Test the start task.

    On this test flow, other downsream tasks are also tested:

    - img-build
    - git-aggregate
    - stop --purge
    """
    try:
        with local.cwd(tmp_path):
            copy(
                src_path=str(cloned_template),
                vcs_ref="HEAD",
                force=True,
                data={"odoo_version": supported_odoo_version},
            )
            # Imagine the user is in the src subfolder for these tasks
            with local.cwd(tmp_path / "odoo" / "custom" / "src"):
                invoke("img-build")
                invoke("git-aggregate")
            # Test normal call
            stdout = invoke("start")
            print(stdout)
            assert "Reinitialized existing Git repository" in stdout
            assert "pre-commit installed" in stdout
            # Test "--debugpy and wait time call
            invoke("stop")
            stdout = invoke("start", "--debugpy")
            assert socket_is_open("127.0.0.1",
                                  int(supported_odoo_version) * 1000 + 899)
            # Check if auto-reload is disabled
            container_logs = docker_compose("logs", "odoo")
            assert "dev=reload" not in container_logs
    finally:
        # Imagine the user is in the odoo subrepo for this command
        with local.cwd(tmp_path / "odoo" / "custom" / "src" / "odoo"):
            invoke("stop", "--purge")
Exemple #6
0
def test_code_workspace_file(tmp_path: Path, cloned_template: Path):
    """The file is generated as expected."""
    copy(
        str(cloned_template),
        str(tmp_path),
        vcs_ref="HEAD",
        force=True,
    )
    assert (tmp_path / f"doodba.{tmp_path.name}.code-workspace").is_file()
    (tmp_path / f"doodba.{tmp_path.name}.code-workspace").rename(
        tmp_path / "doodba.other1.code-workspace")
    with local.cwd(tmp_path):
        invoke("write-code-workspace-file")
        assert (tmp_path / "doodba.other1.code-workspace").is_file()
        assert not (tmp_path /
                    f"doodba.{tmp_path.name}.code-workspace").is_file()
        invoke("write-code-workspace-file", "-c",
               "doodba.other2.code-workspace")
        assert not (tmp_path /
                    f"doodba.{tmp_path.name}.code-workspace").is_file()
        assert (tmp_path / "doodba.other1.code-workspace").is_file()
        assert (tmp_path / "doodba.other2.code-workspace").is_file()
Exemple #7
0
def test_v1_5_3_migration(tmp_path: Path, cloned_template: Path,
                          supported_odoo_version: float):
    """Test migration to v1.5.3."""
    auto_addons = tmp_path / "odoo" / "auto" / "addons"
    # This part makes sense only when v1.5.3 is not yet released
    with local.cwd(cloned_template):
        if "v1.5.3" not in git("tag").split():
            git("tag", "-d", "test")
            git("tag", "v1.5.3")
    with local.cwd(tmp_path):
        # Copy v1.5.2
        copy(src_path=str(cloned_template), vcs_ref="v1.5.2", force=True)
        assert not auto_addons.exists()
        git("add", ".")
        git("commit", "-am", "reformat", retcode=1)
        git("commit", "-am", "copied from template in v1.5.2")
        # Update to v1.5.3
        copy(vcs_ref="v1.5.3", force=True)
        assert not auto_addons.exists()
        invoke("develop")
        assert auto_addons.is_dir()
        # odoo/auto/addons dir must be writable
        (auto_addons / "sample").touch()
Exemple #8
0
def test_resetdb(
    cloned_template: Path,
    docker: LocalCommand,
    supported_odoo_version: float,
    tmp_path: Path,
):
    """Test the dropdb task.

    On this test flow, other downsream tasks are also tested:

    - img-build
    - git-aggregate
    - stop --purge
    """
    try:
        with local.cwd(tmp_path):
            copy(
                src_path=str(cloned_template),
                vcs_ref="HEAD",
                force=True,
                data={"odoo_version": supported_odoo_version},
            )
            # Imagine the user is in the src subfolder for these tasks
            with local.cwd(tmp_path / "odoo" / "custom" / "src"):
                invoke("img-build")
                invoke("git-aggregate")
            # No ir_module_module table exists yet
            with pytest.raises(ProcessExecutionError):
                _install_status("base")
            # Imagine the user is in the odoo subrepo for these tasks
            with local.cwd(tmp_path / "odoo" / "custom" / "src" / "odoo"):
                # This should install just "base"
                stdout = invoke("resetdb")
            assert "Creating database cache" in stdout
            assert "from template devel" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "uninstalled"
            assert _install_status("sale") == "uninstalled"
            # Install "purchase"
            stdout = invoke("resetdb", "-m", "purchase")
            assert "Creating database cache" in stdout
            assert "from template devel" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "installed"
            assert _install_status("sale") == "uninstalled"
            # Install "sale" in a separate database
            stdout = invoke("resetdb", "-m", "sale", "-d", "sale_only")
            assert "Creating database cache" in stdout
            assert "from template sale_only" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "installed"
            assert _install_status("sale") == "uninstalled"
            assert _install_status("base", "sale_only") == "installed"
            assert _install_status("purchase", "sale_only") == "uninstalled"
            assert _install_status("sale", "sale_only") == "installed"
            # Install "sale" in main database
            stdout = invoke("resetdb", "-m", "sale")
            assert "Creating database devel from template cache" in stdout
            assert "Found matching database template" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "uninstalled"
            assert _install_status("sale") == "installed"
    finally:
        # Imagine the user is in the odoo subrepo for this command
        with local.cwd(tmp_path / "odoo" / "custom" / "src" / "odoo"):
            invoke("stop", "--purge")
def test_resetdb(
    cloned_template: Path,
    docker: LocalCommand,
    supported_odoo_version: float,
    tmp_path: Path,
):
    """Test the dropdb task.

    On this test flow, other downsream tasks are also tested:

    - img-build
    - git-aggregate
    - stop --purge
    - snapshot
    - restore-snapshot
    """
    try:
        with local.cwd(tmp_path):
            copy(
                src_path=str(cloned_template),
                vcs_ref="HEAD",
                force=True,
                data={"odoo_version": supported_odoo_version},
            )
            # Imagine the user is in the src subfolder for these tasks
            with local.cwd(tmp_path / "odoo" / "custom" / "src"):
                invoke("img-build")
                invoke("git-aggregate")
            # No ir_module_module table exists yet
            with pytest.raises(ProcessExecutionError):
                _install_status("base")
            # Imagine the user is in the odoo subrepo for these tasks
            with local.cwd(tmp_path / "odoo" / "custom" / "src" / "odoo"):
                # This should install just "base"
                stdout = invoke("resetdb", "--no-populate")
            assert "Creating database cache" in stdout
            assert "from template devel" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "uninstalled"
            assert _install_status("sale") == "uninstalled"
            assert not _get_config_param("report.url")
            # Install "purchase"
            stdout = invoke("resetdb", "-m", "purchase")
            assert "Creating database cache" in stdout
            assert "from template devel" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "installed"
            assert _install_status("sale") == "uninstalled"
            # Install "sale" in a separate database
            stdout = invoke("resetdb", "-m", "sale", "-d", "sale_only")
            assert "Creating database cache" in stdout
            assert "from template sale_only" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "installed"
            assert _install_status("sale") == "uninstalled"
            assert _install_status("base", "sale_only") == "installed"
            assert _install_status("purchase", "sale_only") == "uninstalled"
            assert _install_status("sale", "sale_only") == "installed"
            # Install "sale" in main database
            stdout = invoke("resetdb", "-m", "sale")
            assert "Creating database devel from template cache" in stdout
            assert "Found matching database template" in stdout
            assert _install_status("base") == "installed"
            assert _install_status("purchase") == "uninstalled"
            assert _install_status("sale") == "installed"
            # Snapshot current DB
            invoke("snapshot", "--destination-db", "db_with_sale")
            if supported_odoo_version >= 11:
                invoke("preparedb")
                assert _get_config_param(
                    "report.url") == "http://localhost:8069"
                stdout = invoke("resetdb")  # --populate default
                # report.url should be set in the DB
                assert _get_config_param(
                    "report.url") == "http://localhost:8069"
            else:
                invoke(
                    "resetdb"
                )  # Despite new default --populate, shouldn't introduce error
                with pytest.raises(ProcessExecutionError):
                    invoke("preparedb")
            # DB should now be reset
            assert _install_status("sale") == "uninstalled"
            # Restore snapshot
            invoke("restore-snapshot", "--snapshot-name", "db_with_sale")
            assert _install_status("sale") == "installed"
    finally:
        safe_stop_env(tmp_path / "odoo" / "custom" / "src" / "odoo", )
def test_test_tasks(
    cloned_template: Path,
    docker: LocalCommand,
    supported_odoo_version: float,
    tmp_path: Path,
):
    """Test the tasks associated with the Odoo test flow.

    On this test flow, the following tasks are tested:

    - img-build
    - git-aggregate
    - stop --purge
    - resetdb --dependencies
    - test [options]

    This test will be skipped for prereleased versions of Doodba
    """
    try:
        with local.cwd(tmp_path):
            copy(
                src_path=str(cloned_template),
                vcs_ref="HEAD",
                force=True,
                data={"odoo_version": supported_odoo_version},
            )
            # Imagine the user is in the src subfolder for these tasks
            # and the DB is clean
            with local.cwd(tmp_path / "odoo" / "custom" / "src"):
                invoke("img-build")
                invoke("git-aggregate")
            # Prepare environment with "note" dependencies
            invoke("resetdb", "-m", "note", "--dependencies")
            assert _install_status("mail") == "installed"
            # Test "note" simple call in init mode (default)
            assert _install_status("note") == "uninstalled"
            stdout = invoke("test", "-m", "note", retcode=None)
            # Ensure "note" was installed and tests ran
            assert _install_status("note") == "installed"
            _tests_ran(stdout, supported_odoo_version, "note")
            if supported_odoo_version >= 11:
                # Prepare environment for all private addons and "test" them
                with local.cwd(tmp_path / "odoo" / "custom" / "src" /
                               "private"):
                    generate_test_addon("test_module",
                                        supported_odoo_version,
                                        dependencies='["mail"]')
                    invoke("resetdb", "--private", "--dependencies")
                    assert _install_status("mail") == "installed"
                    # Test "test_module" simple call in init mode (default)
                    assert _install_status("test_module") == "uninstalled"
                    stdout = invoke("test", "--private", retcode=None)
                    # Ensure "test_module" was installed and tests ran
                    assert _install_status("test_module") == "installed"
                # Prepare environment for OCA addons and test them
                with local.cwd(tmp_path / "odoo" / "custom" / "src"):
                    build_file_tree({
                        "addons.yaml":
                        """\
                            account-invoicing:
                                - account_invoice_refund_link
                        """,
                    })
                    invoke("git-aggregate")
                    invoke("resetdb", "--extra", "--private", "--dependencies")
                    assert (_install_status("mail") == "installed"
                            )  # dependency of test_module
                    assert (_install_status("account") == "installed"
                            )  # dependency of account_invoice_refund_link
                    # Test "account_invoice_refund_link"
                    assert _install_status("test_module") == "uninstalled"
                    assert (_install_status("account_invoice_refund_link") ==
                            "uninstalled")
                    stdout = invoke("test",
                                    "--private",
                                    "--extra",
                                    retcode=None)
                    # Ensure "test_module" and "account_invoice_refund_link" were installed
                    assert _install_status("test_module") == "installed"
                    assert _install_status(
                        "account_invoice_refund_link") == "installed"
                    _tests_ran(stdout, supported_odoo_version,
                               "account_invoice_refund_link")
            # Test --test-tags
            if supported_odoo_version >= 12:
                with local.cwd(tmp_path / "odoo" / "custom" / "src" /
                               "private"):
                    generate_test_addon(
                        "test_module",
                        supported_odoo_version,
                        dependencies='["account_invoice_refund_link"]',
                    )
                    # Run again but skip tests
                    invoke("resetdb", "--extra", "--private", "--dependencies")
                    stdout = invoke(
                        "test",
                        "--private",
                        "--extra",
                        "--skip",
                        "account_invoice_refund_link",
                        retcode=None,
                    )
                    assert _install_status("test_module") == "installed"
                    assert _install_status(
                        "account_invoice_refund_link") == "installed"
                    # Tests for account_invoice_refund_link should not run
                    with pytest.raises(AssertionError):
                        _tests_ran(
                            stdout,
                            supported_odoo_version,
                            "account_invoice_refund_link",
                        )
    finally:
        safe_stop_env(tmp_path, )
def test_install_test(
    cloned_template: Path,
    docker: LocalCommand,
    supported_odoo_version: float,
    tmp_path: Path,
):
    """Test the install and test tasks.

    On this test flow, other downsream tasks are also tested:

    - img-build
    - git-aggregate
    - stop --purge
    """
    try:
        with local.cwd(tmp_path):
            copy(
                src_path=str(cloned_template),
                vcs_ref="HEAD",
                force=True,
                data={"odoo_version": supported_odoo_version},
            )
            # Imagine the user is in the src subfolder for these tasks
            # and the DB is clean
            with local.cwd(tmp_path / "odoo" / "custom" / "src"):
                invoke("img-build")
                invoke("git-aggregate")
                invoke("resetdb")
            # Install "mail"
            assert _install_status("mail") == "uninstalled"
            stdout = invoke("install", "-m", "mail")
            assert _install_status("mail") == "installed"
            if supported_odoo_version > 8:
                assert _install_status("utm") == "uninstalled"
                # Change to "utm" subfolder and install
                with local.cwd(tmp_path / "odoo" / "custom" / "src" / "odoo" /
                               "addons" / "utm"):
                    # Install "utm" based on current folder
                    stdout = invoke("install")
                assert _install_status("mail") == "installed"
                assert _install_status("utm") == "installed"
            # Test "note" simple call in init mode (default)
            assert _install_status("note") == "uninstalled"
            stdout = invoke("test",
                            "-m",
                            "note",
                            "--mode",
                            "init",
                            retcode=None)
            # Ensure "note" was installed and tests ran
            assert _install_status("note") == "installed"
            _tests_ran(stdout, supported_odoo_version, "note")
            # Test "note" simple call in update mode
            stdout = invoke("test",
                            "-m",
                            "note",
                            "--mode",
                            "update",
                            retcode=None)
            _tests_ran(stdout, supported_odoo_version, "note")
            # Change to "note" subfolder and test
            with local.cwd(tmp_path / "odoo" / "custom" / "src" / "odoo" /
                           "addons" / "note"):
                # Test "note" based on current folder
                stdout = invoke("test", retcode=None)
                _tests_ran(stdout, supported_odoo_version, "note")
            # Test --debugpy and wait time call with
            safe_stop_env(tmp_path, purge=False)
            invoke("test", "-m", "note", "--debugpy", retcode=None)
            assert socket_is_open("127.0.0.1",
                                  int(supported_odoo_version) * 1000 + 899)
            stdout = _wait_for_test_to_start()
            assert "python -m debugpy" in stdout
    finally:
        safe_stop_env(tmp_path, )
Exemple #12
0
def test_transtion_to_copier(tmp_path: Path, cloned_template: Path,
                             any_odoo_version: float):
    """Test transition from old git-clone-based workflow to new copier-based."""
    tag = "v999999.99.99"
    with local.cwd(cloned_template):
        git("tag", "--delete", "test")
        git("tag", "--force", tag)
    # Emulate user cloning scaffolding using the old workflow
    git("clone", "https://github.com/Tecnativa/doodba-scaffolding", tmp_path)
    with local.cwd(tmp_path):
        # Emulate user modifying some basic variables and committing
        env_file = tmp_path / ".env"
        env_contents = env_file.read_text()
        env_contents = env_contents.replace(
            "ODOO_MAJOR=11", f"ODOO_MAJOR={int(any_odoo_version)}")
        env_contents = env_contents.replace(
            "ODOO_MINOR=11.0", f"ODOO_MINOR={any_odoo_version:.1f}")
        env_contents = env_contents.replace(
            "ODOO_IMAGE=docker.io/myuser/myproject-odoo",
            "ODOO_IMAGE=registry.example.com/custom-team/custom-project-odoo",
        )
        env_file.write_text(env_contents)
        addons_file = tmp_path / "odoo" / "custom" / "src" / "addons.yaml"
        addons_file.write_text('server-tools: ["*"]')
        assert 'server-tools: ["*"]' in addons_file.read_text()
        answers_file = tmp_path / ".copier-answers.yml"
        answers_file_contents = answers_file.read_text()
        answers_file_contents = answers_file_contents.replace(
            "_src_path: https://github.com/Tecnativa/doodba-copier-template.git",
            f"_src_path: {cloned_template}",
        )
        answers_file.write_text(answers_file_contents)
        assert f"_src_path: {cloned_template}" in answers_file.read_text()
        dep_files = glob(
            str(tmp_path / "odoo" / "custom" / "dependencies" / "*.txt"))
        assert len(dep_files) == 5
        for dep_file in map(Path, dep_files):
            with dep_file.open("a") as dep_fd:
                dep_fd.write("\n# a comment")
        git("add", ".")
        git("commit", "-m", "update")
        # Emulate user upgrading to copier, passing the right variables
        copy(
            dst_path=str(tmp_path),
            force=True,
            data={
                "odoo_version":
                any_odoo_version,
                "odoo_oci_image":
                "registry.example.com/custom-team/custom-project-odoo",
            },
            vcs_ref=tag,
        )
        env_contents = env_file.read_text()
        assert f"ODOO_MAJOR={int(any_odoo_version)}" in env_contents
        assert f"ODOO_MINOR={any_odoo_version:.1f}" in env_contents
        assert (tmp_path / ".copier-answers.yml").is_file()
        assert 'server-tools: ["*"]' in addons_file.read_text()
        for dep_file in map(Path, dep_files):
            assert dep_file.read_text().endswith("\n# a comment")
        # Check migrations ran fine
        assert not (tmp_path / ".travis.yml").exists()
        assert not (tmp_path / ".vscode" / "doodba").exists()
        assert not (tmp_path / ".vscode" / "doodbasetup.py").exists()
        assert not (tmp_path / "odoo" / "custom" / "src" / "private" /
                    ".empty").exists()
        # Ensure migrations are resilient to subproject changes
        invoke(
            "--search-root",
            cloned_template,
            "--collection",
            "migrations",
            "from-doodba-scaffolding-to-copier",
        )
def test_code_workspace_file(tmp_path: Path, cloned_template: Path,
                             supported_odoo_version: float):
    """The file is generated as expected."""
    copy(
        str(cloned_template),
        str(tmp_path),
        vcs_ref="HEAD",
        force=True,
        data={"odoo_version": supported_odoo_version},
    )
    assert (tmp_path / f"doodba.{tmp_path.name}.code-workspace").is_file()
    (tmp_path / f"doodba.{tmp_path.name}.code-workspace").rename(
        tmp_path / "doodba.other1.code-workspace")
    with local.cwd(tmp_path / "odoo" / "custom" / "src" / "private"):
        # Generate generic addon path
        is_py3 = supported_odoo_version >= 11
        manifest = "__manifest__" if is_py3 else "__openerp__"
        build_file_tree({
            f"test_module_static/{manifest}.py":
            f"""\
                    {"{"}
                    'name':'test module','license':'AGPL-3',
                    'version':'{supported_odoo_version}.1.0.0',
                    'installable': True,
                    'auto_install': False
                    {"}"}
                """,
            "test_module_static/static/index.html":
            """\
                    <html>
                    </html>
                """,
        })
    with local.cwd(tmp_path):
        invoke("write-code-workspace-file")
        assert (tmp_path / "doodba.other1.code-workspace").is_file()
        assert not (tmp_path /
                    f"doodba.{tmp_path.name}.code-workspace").is_file()
        # Do a stupid and dirty git clone to check it's sorted fine
        git("clone", cloned_template, Path("odoo", "custom", "src", "zzz"))
        # "Clone" a couple more repos, including odoo to check order
        git("clone", cloned_template, Path("odoo", "custom", "src", "aaa"))
        git("clone", cloned_template, Path("odoo", "custom", "src", "bbb"))
        git("clone", cloned_template, Path("odoo", "custom", "src", "odoo"))
        invoke("write-code-workspace-file", "-c",
               "doodba.other2.code-workspace")
        assert not (tmp_path /
                    f"doodba.{tmp_path.name}.code-workspace").is_file()
        assert (tmp_path / "doodba.other1.code-workspace").is_file()
        assert (tmp_path / "doodba.other2.code-workspace").is_file()
        with (tmp_path / "doodba.other2.code-workspace").open() as fp:
            workspace_definition = json.load(fp)
        # Check workspace folder definition and order
        assert workspace_definition["folders"] == [
            {
                "path": "odoo/custom/src/aaa"
            },
            {
                "path": "odoo/custom/src/bbb"
            },
            {
                "path": "odoo/custom/src/zzz"
            },
            {
                "path": "odoo/custom/src/odoo"
            },
            {
                "path": "odoo/custom/src/private"
            },
            {
                "name": f"doodba.{tmp_path.name}",
                "path": "."
            },
        ]
        # Firefox debugger configuration
        url = f"http://localhost:{supported_odoo_version:.0f}069/test_module_static/static/"
        path = "${workspaceRoot:private}/test_module_static/static/"
        firefox_configuration = next(
            conf for conf in workspace_definition["launch"]["configurations"]
            if conf["type"] == "firefox")
        assert {
            "url": url,
            "path": path
        } in firefox_configuration["pathMappings"]
        # Chrome debugger configuration
        chrome_configuration = next(
            conf for conf in workspace_definition["launch"]["configurations"]
            if conf["type"] == "chrome")
        assert chrome_configuration["pathMapping"][url] == path
def test_pre_commit_in_template():
    """Make sure linters are happy."""
    with local.cwd(Path(__file__).parent.parent):
        invoke("lint")