Added testing and code coverage

This commit is contained in:
Chris Caron 2020-01-04 15:50:00 -05:00
parent 39336ca6a4
commit 7ec068657d
7 changed files with 108 additions and 10 deletions

32
.travis.yml Normal file
View File

@ -0,0 +1,32 @@
language: python
dist: xenial
matrix:
include:
- python: "3.4"
env: TOXENV=py34
- python: "3.5"
env: TOXENV=py35
- python: "3.6"
env: TOXENV=py36
- python: "3.7"
env: TOXENV=py37
- python: "pypy3.5-6.0"
env: TOXENV=pypy3
install:
- pip install codecov
- pip install -r dev-requirements.txt
- pip install -r requirements.txt
# run tests
script:
- tox
after_success:
- tox -e coverage-report
- codecov
notifications:
email: false

View File

@ -10,6 +10,8 @@ Apprise API was designed to easily fit into existing (and new) eco-systems that
[![Paypal](https://img.shields.io/badge/paypal-donate-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MHANV39UZNQ5E) [![Paypal](https://img.shields.io/badge/paypal-donate-green.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=MHANV39UZNQ5E)
[![Discord](https://img.shields.io/discord/558793703356104724.svg?colorB=7289DA&label=Discord&logo=Discord&logoColor=7289DA&style=flat-square)](https://discord.gg/MMPeN2D)<br/> [![Discord](https://img.shields.io/discord/558793703356104724.svg?colorB=7289DA&label=Discord&logo=Discord&logoColor=7289DA&style=flat-square)](https://discord.gg/MMPeN2D)<br/>
[![Build Status](https://travis-ci.org/caronc/apprise-api.svg?branch=master)](https://travis-ci.org/caronc/apprise-api)
[![CodeCov Status](https://codecov.io/github/caronc/apprise-pai/branch/master/graph/badge.svg)](https://codecov.io/github/caronc/apprise-api)
[![Docker Pulls](https://img.shields.io/docker/pulls/caronc/apprise.svg?style=flat-square)](https://hub.docker.com/r/caronc/apprise) [![Docker Pulls](https://img.shields.io/docker/pulls/caronc/apprise.svg?style=flat-square)](https://hub.docker.com/r/caronc/apprise)
## Screenshots ## Screenshots
@ -58,8 +60,8 @@ docker-compose up
- `{KEY}` must be 1-64 alphanumeric characters in length. In addition to this, the underscore (`_`) and dash (`-`) are also accepted. - `{KEY}` must be 1-64 alphanumeric characters in length. In addition to this, the underscore (`_`) and dash (`-`) are also accepted.
- You must `POST` to URLs defined above in order for them to respond. - You must `POST` to URLs defined above in order for them to respond.
- Specify the `Content-Type` of `application/json` to use the JSON support. - Specify the `Content-Type` of `application/json` to use the JSON support.
- There is no authentication required to use this API; this is by design. It's intention is to be a lightweight and fast micro-service parked behind the systems designed to handle security. - There is no authentication (or SSL encryption) required to use this API; this is by design. The intentio here to be a lightweight and fast micro-service that can be parked behind another tier that was designed to handle security.
- There are no persistent store dependencies for the purpose of simplicity. Configuration is hashed and written straight to disk. - There are no additional dependencies should you choose to use the optional persistent store (mounted as `/config`).
### Environment Variables ### Environment Variables
@ -67,8 +69,8 @@ The use of environment variables allow you to provide over-rides to default sett
| Variable | Description | | Variable | Description |
|--------------------- | ----------- | |--------------------- | ----------- |
| `APPRISE_CONFIG_DIR` | Defines the persistent store location of all configuration files saved. By default:<br/> - Content is written to the `apprise_api/var/config` directory when just using the _Django_ `manage runserver` script. | `APPRISE_CONFIG_DIR` | Defines the persistent store location of all configuration files saved. By default:<br/> - Configuration is written to the `apprise_api/var/config` directory when just using the _Django_ `manage runserver` script.
| `APPRISE_STATELESS_URLS` | A default set of URLs to notify when using the stateless `/notify` reference (no reference to `{KEY}` variables). | `APPRISE_STATELESS_URLS` | A default set of URLs to notify when using the stateless `/notify` reference (no reference to `{KEY}` variables). Use this option if you don't intend to use the persistent store at all.
| `SECRET_KEY` | A Django variable acting as a *salt* for most things that require security. This API uses it for the hash sequences when writing the configuration files to disk. | `SECRET_KEY` | A Django variable acting as a *salt* for most things that require security. This API uses it for the hash sequences when writing the configuration files to disk.
| `ALLOWED_HOSTS` | A list of strings representing the host/domain names that this API can serve. This is a security measure to prevent HTTP Host header attacks, which are possible even under many seemingly-safe web server configurations. By default this is set to `*` allowing any host. Use space to delimit more then one host. | `ALLOWED_HOSTS` | A list of strings representing the host/domain names that this API can serve. This is a security measure to prevent HTTP Host header attacks, which are possible even under many seemingly-safe web server configurations. By default this is set to `*` allowing any host. Use space to delimit more then one host.
| `DEBUG` | This defaults to `False` however can be set to `True`if defined with a non-zero value (such as `1`). | `DEBUG` | This defaults to `False` however can be set to `True`if defined with a non-zero value (such as `1`).

View File

@ -25,7 +25,7 @@
import apprise import apprise
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
# Define our potential configuration types # Define our potential configuration types
CONFIG_FORMATS = ( CONFIG_FORMATS = (

View File

@ -29,7 +29,7 @@ from django.conf import settings
from django.utils.decorators import method_decorator from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache from django.views.decorators.cache import never_cache
from django.views.decorators.gzip import gzip_page from django.views.decorators.gzip import gzip_page
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import gettext_lazy as _
from .utils import ConfigCache from .utils import ConfigCache
from .forms import AddByUrlForm from .forms import AddByUrlForm
from .forms import AddByConfigForm from .forms import AddByConfigForm
@ -127,7 +127,7 @@ class AddView(View):
# Prepare our default response # Prepare our default response
try: try:
# load our JSON content # load our JSON content
content = json.loads(request.body) content = json.loads(request.body.decode('utf-8'))
except (AttributeError, ValueError): except (AttributeError, ValueError):
# could not parse JSON response... # could not parse JSON response...
@ -338,7 +338,7 @@ class NotifyView(View):
# Prepare our default response # Prepare our default response
try: try:
# load our JSON content # load our JSON content
content = json.loads(request.body) content = json.loads(request.body.decode('utf-8'))
except (AttributeError, ValueError): except (AttributeError, ValueError):
# could not parse JSON response... # could not parse JSON response...
@ -456,7 +456,7 @@ class StatelessNotifyView(View):
# Prepare our default response # Prepare our default response
try: try:
# load our JSON content # load our JSON content
content = json.loads(request.body) content = json.loads(request.body.decode('utf-8'))
except (AttributeError, ValueError): except (AttributeError, ValueError):
# could not parse JSON response... # could not parse JSON response...

View File

@ -1,4 +1,6 @@
pytest
flake8 flake8
mock
pytest-django pytest-django
pytest
pytest-cov pytest-cov
tox

62
tox.ini Normal file
View File

@ -0,0 +1,62 @@
[tox]
envlist = py34,py35,py36,py37,pypy3,coverage-report
skipsdist = true
[testenv]
# Prevent random setuptools/pip breakages like
# https://github.com/pypa/setuptools/issues/1042 from breaking our builds.
setenv =
VIRTUALENV_NO_DOWNLOAD=1
deps=
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
commands =
coverage run --parallel -m pytest {posargs} apprise_api
flake8 apprise_api --count --show-source --statistics
[testenv:py34]
deps=
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
commands =
coverage run --parallel -m pytest {posargs} apprise_api
flake8 apprise_api --count --show-source --statistics
[testenv:py35]
deps=
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
commands =
coverage run --parallel -m pytest {posargs} apprise_api
flake8 apprise_api --count --show-source --statistics
[testenv:py36]
deps=
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
commands =
coverage run --parallel -m pytest {posargs} apprise_api
flake8 apprise_api --count --show-source --statistics
[testenv:py37]
deps=
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
commands =
coverage run --parallel -m pytest {posargs} apprise_api
flake8 apprise_api --count --show-source --statistics
[testenv:pypy3]
deps=
-r{toxinidir}/requirements.txt
-r{toxinidir}/dev-requirements.txt
commands =
coverage run --parallel -m pytest {posargs} apprise_api
flake8 apprise_api --count --show-source --statistics
[testenv:coverage-report]
deps = coverage
skip_install = true
commands=
coverage combine apprise_api
coverage report apprise_api