diff --git a/.github/tests/__init__.py b/.github/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.github/tests/test_signals.py b/.github/tests/test_signals.py new file mode 100644 index 0000000..627b07d --- /dev/null +++ b/.github/tests/test_signals.py @@ -0,0 +1,86 @@ +import dataclasses +from unittest import mock + +import pytest +from django.dispatch import receiver + +from unified_signals.signals import UnifiedSignal +from unified_signals.exceptions import UnifiedSignalMessageTypeError + + +@dataclasses.dataclass +class DataMock: + required_field: int + optional_field: int = 5 + + +class SenderMock: + pass + + +def test_event_signal(): + signal = UnifiedSignal(DataMock) + assert True + + +def test_send_signal_without_data(): + # given + signal = UnifiedSignal(DataMock) + + # when, then + with pytest.raises(UnifiedSignalMessageTypeError): + signal.send(SenderMock) + + +def test_send_signal_with_wrong_data_type(): + # given + signal = UnifiedSignal(DataMock) + + @dataclasses.dataclass + class OtherDataMock: + pass + + # when, then + with pytest.raises(UnifiedSignalMessageTypeError): + signal.send(SenderMock, OtherDataMock()) + + +def test_send_signal_with_proper_data_type(): + # given + signal = UnifiedSignal(DataMock) + + @receiver(signal) + def handle_signal(sender, message: DataMock, **kwargs): + assert message.required_field == 10 + assert message.__class__ == DataMock + + # when + signal.send( + mock.Mock(), + DataMock( + required_field=10, + ), + ) + + +def test_send_robust_signal(): + signal = UnifiedSignal(DataMock) + + @receiver(signal) + def handle_signal(sender, message: DataMock, **kwargs): + assert message.required_field == 10 + assert message.__class__ == DataMock + + signal.send_robust( + mock.Mock(), + DataMock( + required_field=10, + ), + ) + + +def test_send_robus_signal_checks_for_wrong_type(): + signal = UnifiedSignal(DataMock) + + with pytest.raises(UnifiedSignalMessageTypeError): + signal.send_robust(mock.Mock(), 10) diff --git a/.github/tests/testapp/__init__.py b/.github/tests/testapp/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/.github/tests/testapp/settings.py b/.github/tests/testapp/settings.py new file mode 100644 index 0000000..aa76679 --- /dev/null +++ b/.github/tests/testapp/settings.py @@ -0,0 +1,3 @@ +# minimal settings for running tests + +SECRET_KEY = "Some secret key" diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..7077e15 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,54 @@ +name: Continuous Integration + +on: + push: + branches: + - master + pull_request: + paths-ignore: + - '**.md' + - 'LICENSE' + +permissions: read-all + +jobs: + checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Set up Python + uses: actions/setup-python@master + with: + python-version: '3.11' + - name: Install dependencies + run: pip install tox poetry + - name: Safety Check + run: tox -e safety + - name: License Check + run: tox -e liccheck + - name: Code style check + run: | + tox -e black + - name: Static type check + run: tox -e mypy + - name: Coverage Check + run: tox -e coverage + + unit-tests: + runs-on: ubuntu-latest + + strategy: + matrix: + python-version: ["3.9", "3.10", "3.11"] + django-version: ["4.0", "4.1", "4.2"] + + steps: + - uses: actions/checkout@master + - uses: actions/setup-python@master + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: pip install tox poetry + - name: Unit tests and coverage + run: | + tox -e py${{ matrix.python-version }}-dj${{ matrix.django-version }} diff --git a/.github/workflows/workflow_security.yaml b/.github/workflows/workflow_security.yaml new file mode 100644 index 0000000..0ad01cf --- /dev/null +++ b/.github/workflows/workflow_security.yaml @@ -0,0 +1,28 @@ +name: Workflows security checks + +on: + push: + branches: + - master + paths: + - ".github/**/*" + pull_request: + paths: + - ".github/**/*" + +permissions: read-all + +jobs: + checkov: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@master + - name: Set up Python + uses: actions/setup-python@master + with: + python-version: '3.11' + - name: Install dependencies + run: pip install tox checkov + - name: Workflow safety check + run: | + checkov -d .github