Skip to content

Commit

Permalink
Merge pull request #2 from anexia/base_github_actions
Browse files Browse the repository at this point in the history
Add GitHub actions test, publish
  • Loading branch information
nezhar authored Oct 23, 2023
2 parents 5cbfe88 + 84d0eae commit 96491f1
Show file tree
Hide file tree
Showing 11 changed files with 154 additions and 36 deletions.
41 changes: 41 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Publish package
on:
release:
types: [created]

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.10'
architecture: 'x64'

- name: Install dependencies and package
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Build source and binary distribution package
run: |
python setup.py sdist bdist_wheel
env:
PACKAGE_VERSION: ${{ github.ref }}

- name: Check distribution package
run: |
twine check dist/*
- name: Publish distribution package
run: |
twine upload dist/*
env:
TWINE_REPOSITORY: ${{ secrets.PYPI_REPOSITORY }}
TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }}
TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }}
TWINE_NON_INTERACTIVE: yes
53 changes: 53 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Run linter and tests
on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version:
- '3.8'
- '3.9'
- '3.10'
- '3.11'
django-version:
- '3.2'
- '4.1'
- '4.2'

steps:
- uses: actions/checkout@v2

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies and package
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install django~=${{ matrix.django-version }}.0
- name: Run lint and code review with isort and black
run: |
pre-commit run --all-files
- name: Run tests with coverage
run: |
# prepare Django project: link all necessary data from the test project into the root directory
# Hint: Simply changing the directory does not work (leads to missing files in coverage report)
ln -s ./tests/core core
ln -s ./tests/testapp testapp
ln -s ./tests/manage.py manage.py
# run tests with coverage
coverage run \
--source='./django_generic_contact' \
manage.py test
coverage xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Django Generic Contact

[![PyPI version](https://img.shields.io/pypi/v/django-generic-contact.svg)](https://pypi.org/project/django-generic-contact/)
[![Run linter and tests](https://github.com/anexia/django-generic-contact/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/anexia/django-generic-contact/actions/workflows/test.yml)
[![Codecov](https://img.shields.io/codecov/c/gh/anexia/django-generic-contact)](https://codecov.io/gh/anexia/django-generic-contact)

Django module to store contact request in a structured yet generic manner within the database.

### Installation
Expand Down
1 change: 1 addition & 0 deletions django_generic_contact/admin.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django import forms
from django.contrib import admin

from django_generic_contact.models import Contact
from django_generic_contact.utils import get_help_text, get_validators

Expand Down
18 changes: 15 additions & 3 deletions django_generic_contact/migrations/0001_initial.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

initial = True

dependencies = []
Expand All @@ -13,8 +12,21 @@ class Migration(migrations.Migration):
migrations.CreateModel(
name="Contact",
fields=[
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
("creation_date", models.DateTimeField(auto_now_add=True, verbose_name="Creation date")),
(
"id",
models.BigAutoField(
auto_created=True,
primary_key=True,
serialize=False,
verbose_name="ID",
),
),
(
"creation_date",
models.DateTimeField(
auto_now_add=True, verbose_name="Creation date"
),
),
("data", models.JSONField(default=dict, verbose_name="meta data")),
("name", models.CharField(max_length=255, verbose_name="name")),
("message", models.TextField(verbose_name="message")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@


class Migration(migrations.Migration):

dependencies = [
("django_generic_contact", "0001_initial"),
]
Expand Down
2 changes: 0 additions & 2 deletions django_generic_contact/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


class GenericContact(models.Model):

creation_date = models.DateTimeField(
verbose_name=_("Creation date"),
blank=False,
Expand All @@ -24,7 +23,6 @@ class Meta:


class Contact(GenericContact):

name = models.CharField(_("name"), max_length=255)

message = models.TextField(_("message"), blank=True)
5 changes: 4 additions & 1 deletion django_generic_contact/utils.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from django.utils.translation import gettext_lazy as _

from django_generic_contact.models import GENERIC_CONTACT_DATA_SCHEMA
from django_generic_contact.validators import JSONSchemaValidator


def get_help_text():
return _("Meta data according to Schema: {schema}").format(schema=GENERIC_CONTACT_DATA_SCHEMA)
return _("Meta data according to Schema: {schema}").format(
schema=GENERIC_CONTACT_DATA_SCHEMA
)


def get_validators():
Expand Down
4 changes: 3 additions & 1 deletion django_generic_contact/validators.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
class JSONSchemaValidator(BaseValidator):
def compare(self, value, schema):
try:
jsonschema.validate(value, schema, format_checker=jsonschema.draft202012_format_checker)
jsonschema.validate(
value, schema, format_checker=jsonschema.draft202012_format_checker
)
except jsonschema.exceptions.ValidationError as e:
raise ValidationError(str(e))
58 changes: 32 additions & 26 deletions tests/testapp/tests/test_model.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from django.core.exceptions import ValidationError
from django.test import TestCase

from django_generic_contact.models import Contact, GENERIC_CONTACT_DATA_SCHEMA
from django_generic_contact.models import GENERIC_CONTACT_DATA_SCHEMA, Contact
from django_generic_contact.validators import JSONSchemaValidator


Expand All @@ -13,7 +13,7 @@ def test_successful_contact_creation(self):
data={
"email": "[email protected]",
"phone": "123456",
}
},
)

self.assertEqual(Contact.objects.count(), 1)
Expand All @@ -22,25 +22,29 @@ def test_successful_contact_creation(self):
class TestJsonSchema(TestCase):
def test_successful_jsonschema_validation(self):
validator = JSONSchemaValidator(limit_value=GENERIC_CONTACT_DATA_SCHEMA)
validator({
"email": "[email protected]",
"not_validated_phone": "+431234567",
})
validator(
{
"email": "[email protected]",
"not_validated_phone": "+431234567",
}
)

def test_failed_jsonschema_validation_invalid_email(self):
validator = JSONSchemaValidator(limit_value=GENERIC_CONTACT_DATA_SCHEMA)
with self.assertRaises(
ValidationError,
msg="'invalid_email' is not a 'email'\n\n"
"Failed validating 'format' in schema['properties']['email']:\n"
" {'format': 'email', 'type': 'string'}\n\n"
"On instance['email']:\n"
" 'invalid_email'"
ValidationError,
msg="'invalid_email' is not a 'email'\n\n"
"Failed validating 'format' in schema['properties']['email']:\n"
" {'format': 'email', 'type': 'string'}\n\n"
"On instance['email']:\n"
" 'invalid_email'",
):
validator({
"email": "invalid_email",
"not_validated_phone": "+431234567",
})
validator(
{
"email": "invalid_email",
"not_validated_phone": "+431234567",
}
)

def test_failed_jsonschema_validation_additional_fields(self):
test_schema = {
Expand All @@ -53,14 +57,16 @@ def test_failed_jsonschema_validation_additional_fields(self):
}
validator = JSONSchemaValidator(limit_value=test_schema)
with self.assertRaises(
ValidationError,
msg="'+431234567' is not of type 'integer'\n\n"
"Failed validating 'type' in schema['properties']['phone']:\n"
" {'type': 'integer'}\n\n"
"On instance['phone']:\n"
" '+431234567'"
ValidationError,
msg="'+431234567' is not of type 'integer'\n\n"
"Failed validating 'type' in schema['properties']['phone']:\n"
" {'type': 'integer'}\n\n"
"On instance['phone']:\n"
" '+431234567'",
):
validator({
"email": "[email protected]",
"phone": "+431234567",
})
validator(
{
"email": "[email protected]",
"phone": "+431234567",
}
)
3 changes: 1 addition & 2 deletions tests/testapp/tests/test_setup.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from django.test import SimpleTestCase

from django.conf import settings
from django.test import SimpleTestCase


class TestSetup(SimpleTestCase):
Expand Down

0 comments on commit 96491f1

Please sign in to comment.