diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 0000000..30e841d --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,40 @@ +name: Run Tests + +on: + pull_request: + branches: + - main + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements*.txt') }} + restore-keys: | + ${{ runner.os }}-pip- + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.12' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + pip install -r requirements-dev.txt || true + + - name: Set PYTHONPATH + run: echo "PYTHONPATH=$(pwd)" >> $GITHUB_ENV + + - name: Run tests + run: | + pytest diff --git a/requirements-dev.txt b/requirements-dev.txt new file mode 100644 index 0000000..ee56dc2 --- /dev/null +++ b/requirements-dev.txt @@ -0,0 +1,11 @@ +# Testing dependencies +pytest +pytest-cov + +# Linting dependencies +flake8 +black +isort + +# Optional: Type checking +mypy diff --git a/requirements.txt b/requirements.txt index 279c014..b317ec1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,7 @@ -homeassistant==2024.9.3 +homeassistant==2024.12.5 aiodiscover==2.1.0 -pyspeex-noise==1.0.2 \ No newline at end of file +pyspeex-noise==1.0.2 +opentelemetry-sdk +grpcio +opentelemetry-exporter-otlp-proto-http +opentelemetry-exporter-otlp-proto-grpc \ No newline at end of file diff --git a/tests/test_oig_cloud_api.py b/tests/test_oig_cloud_api.py new file mode 100644 index 0000000..1ea0f53 --- /dev/null +++ b/tests/test_oig_cloud_api.py @@ -0,0 +1,36 @@ +import unittest +from unittest.mock import patch, AsyncMock +from custom_components.oig_cloud.api.oig_cloud_api import OigCloudApi + +class TestOigCloudApi(unittest.TestCase): + def setUp(self): + self.api = OigCloudApi("username", "password", False, None) + + @patch("custom_components.oig_cloud.api.oig_cloud_api.aiohttp.ClientSession") + @patch("custom_components.oig_cloud.api.oig_cloud_api.datetime") + @patch("custom_components.oig_cloud.api.oig_cloud_api.tracer") + async def test_get_stats(self, mock_tracer, mock_datetime, mock_session): + mock_datetime.datetime.now.return_value = mock_datetime.datetime(2025, 1, 27, 8, 34, 57) + mock_response = AsyncMock() + mock_response.status = 200 + mock_response.json.return_value = {"key": "value"} + mock_session.return_value.__aenter__.return_value.get.return_value = mock_response + + result = await self.api.get_stats() + self.assertEqual(result, {"key": "value"}) + self.assertEqual(self.api.last_state, {"key": "value"}) + self.assertEqual(self.api.box_id, "key") + + @patch("custom_components.oig_cloud.api.oig_cloud_api.aiohttp.ClientSession") + @patch("custom_components.oig_cloud.api.oig_cloud_api.datetime") + @patch("custom_components.oig_cloud.api.oig_cloud_api.tracer") + async def test_get_stats_cache(self, mock_tracer, mock_datetime, mock_session): + mock_datetime.datetime.now.return_value = mock_datetime.datetime(2025, 1, 27, 8, 34, 57) + self.api._last_update = mock_datetime.datetime(2025, 1, 27, 8, 34, 30) + self.api.last_state = {"cached_key": "cached_value"} + + result = await self.api.get_stats() + self.assertEqual(result, {"cached_key": "cached_value"}) + +if __name__ == "__main__": + unittest.main()