Skip to content

Commit 4df9cdd

Browse files
bosdbosd
authored andcommitted
[IMP] coverage of main.py
1 parent 07d2045 commit 4df9cdd

File tree

2 files changed

+184
-12
lines changed

2 files changed

+184
-12
lines changed

src/odoo_data_flow/__main__.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,8 +285,11 @@ def migrate_cmd(**kwargs: Any) -> None:
285285
"""Performs a direct server-to-server data migration."""
286286
if kwargs.get("mapping"):
287287
try:
288-
kwargs["mapping"] = ast.literal_eval(kwargs["mapping"])
289-
except Exception as e:
288+
parsed_mapping = ast.literal_eval(kwargs["mapping"])
289+
if not isinstance(parsed_mapping, dict):
290+
raise TypeError("Mapping must be a dictionary.")
291+
kwargs["mapping"] = parsed_mapping
292+
except (ValueError, TypeError, SyntaxError) as e:
290293
print(
291294
"Error: Invalid mapping provided. "
292295
f"Must be a valid Python dictionary string. Error: {e}"

tests/test_main.py

Lines changed: 179 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
"""Test cases for the __main__ module."""
22

3+
from unittest.mock import MagicMock, patch
4+
35
import pytest
46
from click.testing import CliRunner
57

6-
# CORRECTED: Use an underscore for the package name in the import.
78
from odoo_data_flow import __main__
89

910

@@ -19,10 +20,8 @@ def test_main_succeeds_without_command(runner: CliRunner) -> None:
1920
It exits with a status code of 0 when no command is provided
2021
and should show the main help message.
2122
"""
22-
# CORRECTED: The entry point function from our __main__.py is now 'cli'.
2323
result = runner.invoke(__main__.cli)
2424
assert result.exit_code == 0
25-
# A good basic test is to ensure the main commands are listed in the help output.
2625
assert "import" in result.output
2726
assert "export" in result.output
2827
assert "path-to-image" in result.output
@@ -33,19 +32,189 @@ def test_main_shows_version(runner: CliRunner) -> None:
3332
"""It shows the version of the package when --version is used."""
3433
result = runner.invoke(__main__.cli, ["--version"])
3534
assert result.exit_code == 0
36-
# This checks that the command runs and that the word 'version'
37-
# appears in the output, which is a robust check for the --version flag.
3835
assert "version" in result.output
3936

4037

41-
# You can also add more specific tests for each command.
42-
# For example, testing that the 'import' command fails without required options:
4338
def test_import_fails_without_options(runner: CliRunner) -> None:
4439
"""The import command should fail if required options are missing."""
45-
# We invoke the 'import' sub-command directly.
4640
result = runner.invoke(__main__.cli, ["import"])
47-
# It should exit with a non-zero status code because options are missing.
4841
assert result.exit_code != 0
49-
# Click's error message should mention the missing options.
5042
assert "Missing option" in result.output
5143
assert "--file" in result.output
44+
45+
46+
@patch("odoo_data_flow.__main__.run_import")
47+
def test_import_command_calls_runner(
48+
mock_run_import: MagicMock, runner: CliRunner
49+
) -> None:
50+
"""Tests that the import command calls the correct runner function."""
51+
result = runner.invoke(
52+
__main__.cli,
53+
[
54+
"import",
55+
"--config",
56+
"my.conf",
57+
"--file",
58+
"my.csv",
59+
"--model",
60+
"res.partner",
61+
],
62+
)
63+
assert result.exit_code == 0
64+
mock_run_import.assert_called_once()
65+
call_kwargs = mock_run_import.call_args.kwargs
66+
assert call_kwargs["config"] == "my.conf"
67+
assert call_kwargs["filename"] == "my.csv"
68+
assert call_kwargs["model"] == "res.partner"
69+
70+
71+
@patch("odoo_data_flow.__main__.run_export")
72+
def test_export_command_calls_runner(
73+
mock_run_export: MagicMock, runner: CliRunner
74+
) -> None:
75+
"""Tests that the export command calls the correct runner function."""
76+
result = runner.invoke(
77+
__main__.cli,
78+
[
79+
"export",
80+
"--config",
81+
"my.conf",
82+
"--file",
83+
"my.csv",
84+
"--model",
85+
"res.partner",
86+
"--fields",
87+
"id,name",
88+
],
89+
)
90+
assert result.exit_code == 0
91+
mock_run_export.assert_called_once()
92+
93+
94+
@patch("odoo_data_flow.__main__.run_path_to_image")
95+
def test_path_to_image_command_calls_runner(
96+
mock_run_path_to_image: MagicMock, runner: CliRunner
97+
) -> None:
98+
"""Tests that the path-to-image command calls the correct runner function."""
99+
result = runner.invoke(
100+
__main__.cli, ["path-to-image", "my.csv", "--fields", "image"]
101+
)
102+
assert result.exit_code == 0
103+
mock_run_path_to_image.assert_called_once()
104+
105+
106+
@patch("odoo_data_flow.__main__.run_url_to_image")
107+
def test_url_to_image_command_calls_runner(
108+
mock_run_url_to_image: MagicMock, runner: CliRunner
109+
) -> None:
110+
"""Tests that the url-to-image command calls the correct runner function."""
111+
result = runner.invoke(
112+
__main__.cli, ["url-to-image", "my.csv", "--fields", "image_url"]
113+
)
114+
assert result.exit_code == 0
115+
mock_run_url_to_image.assert_called_once()
116+
117+
118+
@patch("odoo_data_flow.__main__.run_migration")
119+
def test_migrate_command_calls_runner(
120+
mock_run_migration: MagicMock, runner: CliRunner
121+
) -> None:
122+
"""Tests that the migrate command calls the correct runner function."""
123+
result = runner.invoke(
124+
__main__.cli,
125+
[
126+
"migrate",
127+
"--config-export",
128+
"src.conf",
129+
"--config-import",
130+
"dest.conf",
131+
"--model",
132+
"res.partner",
133+
"--fields",
134+
"id,name",
135+
"--mapping",
136+
"{'name': ('val', 'name')}",
137+
],
138+
)
139+
assert result.exit_code == 0
140+
mock_run_migration.assert_called_once()
141+
call_kwargs = mock_run_migration.call_args.kwargs
142+
assert isinstance(call_kwargs["mapping"], dict)
143+
144+
145+
@patch("odoo_data_flow.__main__.run_migration")
146+
def test_migrate_command_bad_mapping_syntax(
147+
mock_run_migration: MagicMock, runner: CliRunner
148+
) -> None:
149+
"""Tests that the migrate command handles a bad mapping string."""
150+
result = runner.invoke(
151+
__main__.cli,
152+
[
153+
"migrate",
154+
"--config-export",
155+
"src.conf",
156+
"--config-import",
157+
"dest.conf",
158+
"--model",
159+
"res.partner",
160+
"--fields",
161+
"id,name",
162+
"--mapping",
163+
"this-is-not-a-dict",
164+
],
165+
)
166+
assert result.exit_code == 0
167+
assert "Invalid mapping provided" in result.output
168+
mock_run_migration.assert_not_called()
169+
170+
171+
@patch("odoo_data_flow.__main__.run_migration")
172+
def test_migrate_command_mapping_not_a_dict(
173+
mock_run_migration: MagicMock, runner: CliRunner
174+
) -> None:
175+
"""Tests that migrate command handles a valid literal that is not a dict."""
176+
result = runner.invoke(
177+
__main__.cli,
178+
[
179+
"migrate",
180+
"--config-export",
181+
"src.conf",
182+
"--config-import",
183+
"dest.conf",
184+
"--model",
185+
"res.partner",
186+
"--fields",
187+
"id,name",
188+
"--mapping",
189+
"['this', 'is', 'a', 'list']", # Valid literal, but not a dict
190+
],
191+
)
192+
assert result.exit_code == 0
193+
assert "Mapping must be a dictionary" in result.output
194+
mock_run_migration.assert_not_called()
195+
196+
197+
@patch("odoo_data_flow.__main__.run_invoice_v9_workflow")
198+
def test_workflow_command_calls_runner(
199+
mock_run_workflow: MagicMock, runner: CliRunner
200+
) -> None:
201+
"""Tests that the workflow command calls the correct runner function."""
202+
result = runner.invoke(
203+
__main__.cli,
204+
[
205+
"workflow",
206+
"invoice-v9",
207+
"--config",
208+
"my.conf",
209+
"--field",
210+
"x_status",
211+
"--status-map",
212+
"{}",
213+
"--paid-date-field",
214+
"x_date",
215+
"--payment-journal",
216+
"1",
217+
],
218+
)
219+
assert result.exit_code == 0
220+
mock_run_workflow.assert_called_once()

0 commit comments

Comments
 (0)