Merge pull request #367 from mouse-reeve/test-ci

Adds django test runner
This commit is contained in:
Mouse Reeve 2020-11-27 14:23:24 -08:00 committed by GitHub
commit 0f851e15bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 43 deletions

68
.github/workflows/django-tests.yml vendored Normal file
View file

@ -0,0 +1,68 @@
name: Run Python Tests
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-20.04
strategy:
max-parallel: 4
matrix:
db: [postgres]
python-version: [3.9]
include:
- db: postgres
db_port: 5432
services:
postgres:
image: postgres:10
env:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: hunter2
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
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
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run Tests
env:
DB: ${{ matrix.db }}
DB_HOST: 127.0.0.1
DB_PORT: ${{ matrix.db_port }}
DB_PASSWORD: hunter2
SECRET_KEY: beepbeep
DEBUG: true
DOMAIN: your.domain.here
OL_URL: https://openlibrary.org
BOOKWYRM_DATABASE_BACKEND: postgres
MEDIA_ROOT: images/
POSTGRES_PASSWORD: hunter2
POSTGRES_USER: postgres
POSTGRES_DB: github_actions
POSTGRES_HOST: 127.0.0.1
CELERY_BROKER: ""
CELERY_RESULT_BACKEND: ""
EMAIL_HOST: "smtp.mailgun.org"
EMAIL_PORT: 587
EMAIL_HOST_USER: ""
EMAIL_HOST_PASSWORD: ""
EMAIL_USE_TLS: true
run: |
python manage.py test

View file

@ -1,3 +1,4 @@
from unittest.mock import patch
from django.test import TestCase from django.test import TestCase
from bookwyrm import models, incoming from bookwyrm import models, incoming
@ -27,7 +28,8 @@ class IncomingFollow(TestCase):
"object": "http://local.com/user/mouse" "object": "http://local.com/user/mouse"
} }
incoming.handle_follow(activity) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
incoming.handle_follow(activity)
# notification created # notification created
notification = models.Notification.objects.get() notification = models.Notification.objects.get()
@ -55,7 +57,8 @@ class IncomingFollow(TestCase):
self.local_user.manually_approves_followers = True self.local_user.manually_approves_followers = True
self.local_user.save() self.local_user.save()
incoming.handle_follow(activity) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
incoming.handle_follow(activity)
# notification created # notification created
notification = models.Notification.objects.get() notification = models.Notification.objects.get()
@ -81,7 +84,8 @@ class IncomingFollow(TestCase):
"object": "http://local.com/user/nonexistent-user" "object": "http://local.com/user/nonexistent-user"
} }
incoming.handle_follow(activity) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
incoming.handle_follow(activity)
# do nothing # do nothing
notifications = models.Notification.objects.all() notifications = models.Notification.objects.all()

View file

@ -27,9 +27,13 @@ class User(TestCase):
shelves = models.Shelf.objects.filter(user=self.user).all() shelves = models.Shelf.objects.filter(user=self.user).all()
self.assertEqual(len(shelves), 3) self.assertEqual(len(shelves), 3)
names = [s.name for s in shelves] names = [s.name for s in shelves]
self.assertEqual(names, ['To Read', 'Currently Reading', 'Read']) self.assertTrue('To Read' in names)
self.assertTrue('Currently Reading' in names)
self.assertTrue('Read' in names)
ids = [s.identifier for s in shelves] ids = [s.identifier for s in shelves]
self.assertEqual(ids, ['to-read', 'reading', 'read']) self.assertTrue('to-read' in ids)
self.assertTrue('reading' in ids)
self.assertTrue('read' in ids)
def test_activitypub_serialize(self): def test_activitypub_serialize(self):

View file

@ -1,3 +1,4 @@
from unittest.mock import patch
from django.test import TestCase from django.test import TestCase
from bookwyrm import models, outgoing from bookwyrm import models, outgoing
@ -22,7 +23,9 @@ class Following(TestCase):
def test_handle_follow(self): def test_handle_follow(self):
self.assertEqual(models.UserFollowRequest.objects.count(), 0) self.assertEqual(models.UserFollowRequest.objects.count(), 0)
outgoing.handle_follow(self.local_user, self.remote_user) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_follow(self.local_user, self.remote_user)
rel = models.UserFollowRequest.objects.get() rel = models.UserFollowRequest.objects.get()
self.assertEqual(rel.user_subject, self.local_user) self.assertEqual(rel.user_subject, self.local_user)
@ -33,7 +36,8 @@ class Following(TestCase):
def test_handle_unfollow(self): def test_handle_unfollow(self):
self.remote_user.followers.add(self.local_user) self.remote_user.followers.add(self.local_user)
self.assertEqual(self.remote_user.followers.count(), 1) self.assertEqual(self.remote_user.followers.count(), 1)
outgoing.handle_unfollow(self.local_user, self.remote_user) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_unfollow(self.local_user, self.remote_user)
self.assertEqual(self.remote_user.followers.count(), 0) self.assertEqual(self.remote_user.followers.count(), 0)
@ -45,7 +49,8 @@ class Following(TestCase):
) )
rel_id = rel.id rel_id = rel.id
outgoing.handle_accept(rel) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_accept(rel)
# request should be deleted # request should be deleted
self.assertEqual( self.assertEqual(
models.UserFollowRequest.objects.filter(id=rel_id).count(), 0 models.UserFollowRequest.objects.filter(id=rel_id).count(), 0
@ -61,7 +66,8 @@ class Following(TestCase):
) )
rel_id = rel.id rel_id = rel.id
outgoing.handle_reject(rel) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_reject(rel)
# request should be deleted # request should be deleted
self.assertEqual( self.assertEqual(
models.UserFollowRequest.objects.filter(id=rel_id).count(), 0 models.UserFollowRequest.objects.filter(id=rel_id).count(), 0

View file

@ -1,3 +1,4 @@
from unittest.mock import patch
from django.test import TestCase from django.test import TestCase
from bookwyrm import models, outgoing from bookwyrm import models, outgoing
@ -26,7 +27,8 @@ class Shelving(TestCase):
def test_handle_shelve(self): def test_handle_shelve(self):
outgoing.handle_shelve(self.user, self.book, self.shelf) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_shelve(self.user, self.book, self.shelf)
# make sure the book is on the shelf # make sure the book is on the shelf
self.assertEqual(self.shelf.books.get(), self.book) self.assertEqual(self.shelf.books.get(), self.book)
@ -34,7 +36,8 @@ class Shelving(TestCase):
def test_handle_shelve_to_read(self): def test_handle_shelve_to_read(self):
shelf = models.Shelf.objects.get(identifier='to-read') shelf = models.Shelf.objects.get(identifier='to-read')
outgoing.handle_shelve(self.user, self.book, shelf) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_shelve(self.user, self.book, shelf)
# make sure the book is on the shelf # make sure the book is on the shelf
self.assertEqual(shelf.books.get(), self.book) self.assertEqual(shelf.books.get(), self.book)
@ -42,7 +45,8 @@ class Shelving(TestCase):
def test_handle_shelve_reading(self): def test_handle_shelve_reading(self):
shelf = models.Shelf.objects.get(identifier='reading') shelf = models.Shelf.objects.get(identifier='reading')
outgoing.handle_shelve(self.user, self.book, shelf) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_shelve(self.user, self.book, shelf)
# make sure the book is on the shelf # make sure the book is on the shelf
self.assertEqual(shelf.books.get(), self.book) self.assertEqual(shelf.books.get(), self.book)
@ -50,7 +54,8 @@ class Shelving(TestCase):
def test_handle_shelve_read(self): def test_handle_shelve_read(self):
shelf = models.Shelf.objects.get(identifier='read') shelf = models.Shelf.objects.get(identifier='read')
outgoing.handle_shelve(self.user, self.book, shelf) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_shelve(self.user, self.book, shelf)
# make sure the book is on the shelf # make sure the book is on the shelf
self.assertEqual(shelf.books.get(), self.book) self.assertEqual(shelf.books.get(), self.book)
@ -59,5 +64,6 @@ class Shelving(TestCase):
self.shelf.books.add(self.book) self.shelf.books.add(self.book)
self.shelf.save() self.shelf.save()
self.assertEqual(self.shelf.books.count(), 1) self.assertEqual(self.shelf.books.count(), 1)
outgoing.handle_unshelve(self.user, self.book, self.shelf) with patch('bookwyrm.broadcast.broadcast_task.delay') as _:
outgoing.handle_unshelve(self.user, self.book, self.shelf)
self.assertEqual(self.shelf.books.count(), 0) self.assertEqual(self.shelf.books.count(), 0)

View file

@ -2,6 +2,7 @@ import time
from collections import namedtuple from collections import namedtuple
from urllib.parse import urlsplit from urllib.parse import urlsplit
import pathlib import pathlib
from unittest.mock import patch
import json import json
import responses import responses
@ -63,12 +64,14 @@ class Signature(TestCase):
send_data=None, send_data=None,
digest=None, digest=None,
date=None): date=None):
''' sends a follow request to the "rat" user '''
now = date or http_date() now = date or http_date()
data = json.dumps(get_follow_data(sender, self.rat)) data = json.dumps(get_follow_data(sender, self.rat))
digest = digest or make_digest(data) digest = digest or make_digest(data)
signature = make_signature( signature = make_signature(
signer or sender, self.rat.inbox, now, digest) signer or sender, self.rat.inbox, now, digest)
return self.send(signature, now, send_data or data, digest) with patch('bookwyrm.incoming.handle_follow.delay') as _:
return self.send(signature, now, send_data or data, digest)
def test_correct_signature(self): def test_correct_signature(self):
response = self.send_test_request(sender=self.mouse) response = self.send_test_request(sender=self.mouse)
@ -104,8 +107,9 @@ class Signature(TestCase):
status=200 status=200
) )
response = self.send_test_request(sender=self.fake_remote) with patch('bookwyrm.remote_user.get_remote_reviews.delay') as _:
self.assertEqual(response.status_code, 200) response = self.send_test_request(sender=self.fake_remote)
self.assertEqual(response.status_code, 200)
@responses.activate @responses.activate
def test_key_needs_refresh(self): def test_key_needs_refresh(self):
@ -141,21 +145,22 @@ class Signature(TestCase):
json=data, json=data,
status=200) status=200)
# Key correct: with patch('bookwyrm.remote_user.get_remote_reviews.delay') as _:
response = self.send_test_request(sender=self.fake_remote) # Key correct:
self.assertEqual(response.status_code, 200) response = self.send_test_request(sender=self.fake_remote)
self.assertEqual(response.status_code, 200)
# Old key is cached, so still works: # Old key is cached, so still works:
response = self.send_test_request(sender=self.fake_remote) response = self.send_test_request(sender=self.fake_remote)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
# Try with new key: # Try with new key:
response = self.send_test_request(sender=new_sender) response = self.send_test_request(sender=new_sender)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
# Now the old key will fail: # Now the old key will fail:
response = self.send_test_request(sender=self.fake_remote) response = self.send_test_request(sender=self.fake_remote)
self.assertEqual(response.status_code, 401) self.assertEqual(response.status_code, 401)
@responses.activate @responses.activate
@ -172,23 +177,26 @@ class Signature(TestCase):
@pytest.mark.integration @pytest.mark.integration
def test_changed_data(self): def test_changed_data(self):
'''Message data must match the digest header.''' '''Message data must match the digest header.'''
response = self.send_test_request( with patch('bookwyrm.remote_user.fetch_user_data') as _:
self.mouse, response = self.send_test_request(
send_data=get_follow_data(self.mouse, self.cat)) self.mouse,
self.assertEqual(response.status_code, 401) send_data=get_follow_data(self.mouse, self.cat))
self.assertEqual(response.status_code, 401)
@pytest.mark.integration @pytest.mark.integration
def test_invalid_digest(self): def test_invalid_digest(self):
response = self.send_test_request( with patch('bookwyrm.remote_user.fetch_user_data') as _:
self.mouse, response = self.send_test_request(
digest='SHA-256=AAAAAAAAAAAAAAAAAA') self.mouse,
self.assertEqual(response.status_code, 401) digest='SHA-256=AAAAAAAAAAAAAAAAAA')
self.assertEqual(response.status_code, 401)
@pytest.mark.integration @pytest.mark.integration
def test_old_message(self): def test_old_message(self):
'''Old messages should be rejected to prevent replay attacks.''' '''Old messages should be rejected to prevent replay attacks.'''
response = self.send_test_request( with patch('bookwyrm.remote_user.fetch_user_data') as _:
self.mouse, response = self.send_test_request(
date=http_date(time.time() - 301) self.mouse,
) date=http_date(time.time() - 301)
self.assertEqual(response.status_code, 401) )
self.assertEqual(response.status_code, 401)

3
bw-dev
View file

@ -61,7 +61,8 @@ case "$1" in
;; ;;
migrate) migrate)
execweb python manage.py rename_app fedireads bookwyrm execweb python manage.py rename_app fedireads bookwyrm
execweb python manage.py "$@" shift 1
execweb python manage.py migrate "$@"
;; ;;
bash) bash)
execweb bash execweb bash