Skip to content

Commit 680474c

Browse files
committed
test: add comprehensive tests and improve CI badges - Add tests for CLI, pipeline, observe, and schema modules - Fix CI workflow badges to show real status - Update README with accurate test badge - Remove coverage reporting from CI - Fix CONTRIBUTING.md links
1 parent d77c1c6 commit 680474c

8 files changed

Lines changed: 1519 additions & 549 deletions

File tree

.github/workflows/ci.yml

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: CI
22

33
on:
44
push:
5-
![1761039569900](image/ci/1761039569900.png)![1761039571157](image/ci/1761039571157.png) branches: [ main, gh ]
5+
branches: [ main, gh ]
66
pull_request:
77
branches: [ main ]
88

@@ -29,18 +29,9 @@ jobs:
2929
python -m pip install --upgrade pip
3030
pip install -e ".[dev]"
3131
32-
- name: 🧪 Run tests with coverage
32+
- name: 🧪 Run tests
3333
run: |
34-
pytest tests/ -v --tb=short --cov=pydhis2 --cov-report=xml --cov-report=term-missing || true
35-
36-
- name: 📊 Upload coverage to Codecov
37-
uses: codecov/codecov-action@v3
38-
if: matrix.os == 'ubuntu-latest' && matrix.python-version == '3.11'
39-
with:
40-
file: ./coverage.xml
41-
flags: unittests
42-
name: codecov-umbrella
43-
fail_ci_if_error: false
34+
pytest tests/unit/ tests/integration/ -v --tb=short -x
4435
4536
- name: ✅ Summary
4637
run: |
@@ -64,5 +55,5 @@ jobs:
6455
6556
- name: 🔍 Run ruff
6657
run: |
67-
ruff check pydhis2/ || true
58+
ruff check pydhis2/
6859
echo "✅ Linting completed"

CONTRIBUTING.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ This project and everyone participating in it is governed by the [Code of Conduc
1212

1313
### Reporting Bugs
1414

15-
This is one of the simplest ways to contribute. If you find a bug, please ensure the bug was not already reported by searching on GitHub under [Issues](https://github.com/pydhis2/pydhis2/issues).
15+
This is one of the simplest ways to contribute. If you find a bug, please ensure the bug was not already reported by searching on GitHub under [Issues](https://github.com/HzaCode/pyDHIS2/issues).
1616

1717
If you're unable to find an open issue addressing the problem, open a new one. Be sure to include a title and clear description, as much relevant information as possible, and a code sample or an executable test case demonstrating the expected behavior that is not occurring.
1818

@@ -24,8 +24,8 @@ If you have an idea for an enhancement, please open an issue to discuss it. This
2424

2525
Unsure where to begin contributing to `pydhis2`? You can start by looking through these `good-first-issue` and `help-wanted` issues:
2626

27-
- [Good first issues](https://github.com/pydhis2/pydhis2/labels/good%20first%20issue) - issues which should only require a few lines of code, and a test or two.
28-
- [Help wanted issues](https://github.com/pydhis2/pydhis2/labels/help%20wanted) - issues which should be a bit more involved than `good-first-issue` issues.
27+
- [Good first issues](https://github.com/HzaCode/pyDHIS2/labels/good%20first%20issue) - issues which should only require a few lines of code, and a test or two.
28+
- [Help wanted issues](https://github.com/HzaCode/pyDHIS2/labels/help%20wanted) - issues which should be a bit more involved than `good-first-issue` issues.
2929

3030
### Pull Requests
3131

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222
<a href="https://pepy.tech/project/pydhis2">
2323
<img src="https://img.shields.io/pepy/dt/pydhis2?style=flat&color=blue" alt="Downloads">
2424
</a>
25-
<!-- Test Passing -->
25+
<!-- Test Status -->
2626
<a href="https://github.com/HzaCode/pyDHIS2/actions/workflows/ci.yml">
27-
<img src="https://img.shields.io/badge/tests-passing-brightgreen?style=flat" alt="Tests">
27+
<img src="https://img.shields.io/github/actions/workflow/status/HzaCode/pyDHIS2/ci.yml?branch=main&label=test&style=flat" alt="Tests">
2828
</a>
29-
<!-- Docs Passing -->
29+
<!-- Documentation -->
3030
<a href="https://hzacode.github.io/pyDHIS2">
3131
<img src="https://img.shields.io/badge/docs-passing-brightgreen?style=flat" alt="Docs">
3232
</a>
@@ -36,7 +36,7 @@
3636
</a>
3737
<!-- Ruff -->
3838
<a href="https://github.com/astral-sh/ruff">
39-
<img src="https://img.shields.io/badge/code%20style-ruff-black?style=flat" alt="Ruff">
39+
<img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff">
4040
</a>
4141
</p>
4242
</div>

tests/unit/test_cli.py

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
"""Tests for CLI module"""
2+
3+
import pytest
4+
from typer.testing import CliRunner
5+
from pydhis2.cli.main import app
6+
from unittest.mock import patch, MagicMock
7+
8+
runner = CliRunner()
9+
10+
11+
class TestVersionCommand:
12+
"""Test version command"""
13+
14+
def test_version_command(self):
15+
"""Test version command output"""
16+
result = runner.invoke(app, ["version"])
17+
assert result.exit_code == 0
18+
assert "pydhis2 version" in result.stdout
19+
20+
21+
class TestConfigCommand:
22+
"""Test config command"""
23+
24+
def test_config_with_all_params(self):
25+
"""Test config command with all parameters"""
26+
result = runner.invoke(
27+
app,
28+
["config", "--url", "https://test.dhis2.org", "--username", "admin", "--password", "district"],
29+
)
30+
assert result.exit_code == 0
31+
assert "Configured connection" in result.stdout
32+
33+
def test_config_with_env_vars(self):
34+
"""Test config command using environment variables"""
35+
with patch.dict('os.environ', {
36+
'DHIS2_USERNAME': 'test_user',
37+
'DHIS2_PASSWORD': 'test_pass'
38+
}):
39+
result = runner.invoke(
40+
app,
41+
["config", "--url", "https://test.dhis2.org"],
42+
)
43+
assert result.exit_code == 0
44+
45+
46+
class TestAnalyticsCommands:
47+
"""Test analytics commands"""
48+
49+
def test_analytics_pull_command(self):
50+
"""Test analytics pull command"""
51+
result = runner.invoke(
52+
app,
53+
[
54+
"analytics", "pull",
55+
"--url", "https://test.dhis2.org",
56+
"--dx", "test_dx",
57+
"--ou", "test_ou",
58+
"--pe", "2023",
59+
"--out", "test.parquet"
60+
],
61+
)
62+
assert result.exit_code == 0
63+
assert "Would pull data" in result.stdout
64+
assert "test_dx" in result.stdout
65+
66+
def test_analytics_pull_with_format(self):
67+
"""Test analytics pull with custom format"""
68+
result = runner.invoke(
69+
app,
70+
[
71+
"analytics", "pull",
72+
"--url", "https://test.dhis2.org",
73+
"--dx", "dx1",
74+
"--ou", "ou1",
75+
"--pe", "2023",
76+
"--format", "csv"
77+
],
78+
)
79+
assert result.exit_code == 0
80+
81+
82+
class TestDataValueSetsCommands:
83+
"""Test datavaluesets commands"""
84+
85+
def test_datavaluesets_pull_command(self):
86+
"""Test datavaluesets pull command"""
87+
result = runner.invoke(
88+
app,
89+
[
90+
"datavaluesets", "pull",
91+
"--url", "https://test.dhis2.org",
92+
"--data-set", "ds1",
93+
"--org-unit", "ou1",
94+
"--period", "202301"
95+
],
96+
)
97+
assert result.exit_code == 0
98+
assert "Would pull data" in result.stdout
99+
100+
def test_datavaluesets_push_command(self):
101+
"""Test datavaluesets push command"""
102+
result = runner.invoke(
103+
app,
104+
[
105+
"datavaluesets", "push",
106+
"--url", "https://test.dhis2.org",
107+
"--input", "test.parquet"
108+
],
109+
)
110+
assert result.exit_code == 0
111+
assert "Implementation in progress" in result.stdout
112+
113+
114+
class TestTrackerCommands:
115+
"""Test tracker commands"""
116+
117+
def test_tracker_events_command(self):
118+
"""Test tracker events command"""
119+
result = runner.invoke(
120+
app,
121+
[
122+
"tracker", "events",
123+
"--url", "https://test.dhis2.org",
124+
"--program", "prog1",
125+
"--out", "events.parquet"
126+
],
127+
)
128+
assert result.exit_code == 0
129+
130+
131+
class TestDQRCommands:
132+
"""Test DQR commands"""
133+
134+
def test_dqr_analyze_command(self):
135+
"""Test DQR analyze command"""
136+
result = runner.invoke(
137+
app,
138+
[
139+
"dqr", "analyze",
140+
"--input", "test.parquet",
141+
"--html", "report.html"
142+
],
143+
)
144+
assert result.exit_code == 0
145+
assert "Implementation in progress" in result.stdout
146+
147+
148+
class TestDemoCommand:
149+
"""Test demo command"""
150+
151+
@patch('pydhis2.cli.main.asyncio.run')
152+
def test_demo_quick_command(self, mock_run):
153+
"""Test demo quick command"""
154+
mock_run.return_value = None
155+
result = runner.invoke(app, ["demo", "quick"])
156+
# Command should execute without error
157+
assert result.exit_code == 0 or "demo" in result.stdout.lower()
158+
159+
160+
class TestPipelineCommands:
161+
"""Test pipeline commands"""
162+
163+
def test_pipeline_run_command(self):
164+
"""Test pipeline run command"""
165+
result = runner.invoke(
166+
app,
167+
[
168+
"pipeline", "run",
169+
"--config", "test.yml"
170+
],
171+
)
172+
# Should show implementation message or execute
173+
assert result.exit_code == 0 or "pipeline" in result.stdout.lower()
174+
175+
176+
class TestMetadataCommands:
177+
"""Test metadata commands"""
178+
179+
def test_metadata_export_command(self):
180+
"""Test metadata export command"""
181+
result = runner.invoke(
182+
app,
183+
[
184+
"metadata", "export",
185+
"--url", "https://test.dhis2.org",
186+
"--type", "dataElements",
187+
"--out", "metadata.json"
188+
],
189+
)
190+
assert result.exit_code == 0
191+
192+
def test_metadata_import_command(self):
193+
"""Test metadata import command"""
194+
result = runner.invoke(
195+
app,
196+
[
197+
"metadata", "import",
198+
"--url", "https://test.dhis2.org",
199+
"--input", "metadata.json"
200+
],
201+
)
202+
assert result.exit_code == 0
203+

0 commit comments

Comments
 (0)