Merge branch 'jim/cli-tooling' of https://github.com/jimfingal/bookwyrm into main

This commit is contained in:
Mouse Reeve 2020-11-08 20:03:27 -08:00
commit 00752232ff
12 changed files with 182 additions and 112 deletions

2
.coveragerc Normal file
View file

@ -0,0 +1,2 @@
[run]
omit = */test*,celerywyrm*,bookwyrm/migrations/*

7
.dockerignore Normal file
View file

@ -0,0 +1,7 @@
__pycache__
*.pyc
*.pyo
*.pyd
.git
.github
.pytest*

3
.gitignore vendored
View file

@ -13,3 +13,6 @@
# BookWyrm
.env
/images/
# Testing
.coverage

View file

@ -65,9 +65,8 @@ You'll have to install the Docker and docker-compose. When you're ready, run:
```bash
docker-compose build
docker-compose up
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py shell -c 'import init_db'
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py initdb
```
### Without Docker

View file

@ -0,0 +1,100 @@
from django.core.management.base import BaseCommand, CommandError
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from bookwyrm.models import Connector, User
from bookwyrm.settings import DOMAIN
def init_groups():
groups = ['admin', 'moderator', 'editor']
for group in groups:
Group.objects.create(name=group)
def init_permissions():
permissions = [{
'codename': 'edit_instance_settings',
'name': 'change the instance info',
'groups': ['admin',]
}, {
'codename': 'set_user_group',
'name': 'change what group a user is in',
'groups': ['admin', 'moderator']
}, {
'codename': 'control_federation',
'name': 'control who to federate with',
'groups': ['admin', 'moderator']
}, {
'codename': 'create_invites',
'name': 'issue invitations to join',
'groups': ['admin', 'moderator']
}, {
'codename': 'moderate_user',
'name': 'deactivate or silence a user',
'groups': ['admin', 'moderator']
}, {
'codename': 'moderate_post',
'name': 'delete other users\' posts',
'groups': ['admin', 'moderator']
}, {
'codename': 'edit_book',
'name': 'edit book info',
'groups': ['admin', 'moderator', 'editor']
}]
content_type = ContentType.objects.get_for_model(User)
for permission in permissions:
permission_obj = Permission.objects.create(
codename=permission['codename'],
name=permission['name'],
content_type=content_type,
)
# add the permission to the appropriate groups
for group_name in permission['groups']:
Group.objects.get(name=group_name).permissions.add(permission_obj)
# while the groups and permissions shouldn't be changed because the code
# depends on them, what permissions go with what groups should be editable
def init_connectors():
Connector.objects.create(
identifier=DOMAIN,
name='Local',
local=True,
connector_file='self_connector',
base_url='https://%s' % DOMAIN,
books_url='https://%s/book' % DOMAIN,
covers_url='https://%s/images/covers' % DOMAIN,
search_url='https://%s/search?q=' % DOMAIN,
priority=1,
)
Connector.objects.create(
identifier='bookwyrm.social',
name='BookWyrm dot Social',
connector_file='bookwyrm_connector',
base_url='https://bookwyrm.social' ,
books_url='https://bookwyrm.social/book',
covers_url='https://bookwyrm.social/images/covers',
search_url='https://bookwyrm.social/search?q=',
priority=2,
)
Connector.objects.create(
identifier='openlibrary.org',
name='OpenLibrary',
connector_file='openlibrary',
base_url='https://openlibrary.org',
books_url='https://openlibrary.org',
covers_url='https://covers.openlibrary.org',
search_url='https://openlibrary.org/search?q=',
priority=3,
)
class Command(BaseCommand):
help = 'Initializes the database with starter data'
def handle(self, *args, **options):
init_groups()
init_permissions()
init_connectors()

View file

@ -6,6 +6,8 @@ import pathlib
import json
import responses
import pytest
from django.test import TestCase, Client
from django.utils.http import http_date
@ -167,6 +169,7 @@ class Signature(TestCase):
response = self.send_test_request(sender=self.fake_remote)
self.assertEqual(response.status_code, 401)
@pytest.mark.integration
def test_changed_data(self):
'''Message data must match the digest header.'''
response = self.send_test_request(
@ -174,12 +177,14 @@ class Signature(TestCase):
send_data=get_follow_data(self.mouse, self.cat))
self.assertEqual(response.status_code, 401)
@pytest.mark.integration
def test_invalid_digest(self):
response = self.send_test_request(
self.mouse,
digest='SHA-256=AAAAAAAAAAAAAAAAAA')
self.assertEqual(response.status_code, 401)
@pytest.mark.integration
def test_old_message(self):
'''Old messages should be rejected to prevent replay attacks.'''
response = self.send_test_request(

View file

@ -22,6 +22,7 @@ services:
- main
web:
build: .
env_file: .env
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app

69
fr-dev
View file

@ -3,51 +3,86 @@
set -e
set -x
function clean {
docker-compose stop
docker-compose rm -f
}
function runweb {
docker-compose run --rm web "$@"
clean
}
function execdb {
docker-compose exec db $@
}
function execweb {
docker-compose exec web "$@"
}
function initdb {
execweb python manage.py migrate
execweb python manage.py initdb
}
case "$1" in
up)
docker-compose up --build
;;
run)
docker-compose run --service-ports web
docker-compose run --rm --service-ports web
;;
initdb)
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py shell -c 'import init_db'
initdb
;;
resetdb)
docker-compose stop web
docker-compose exec db dropdb -U fedireads fedireads
docker-compose exec db createdb -U fedireads fedireads
docker-compose start web
docker-compose exec web python manage.py migrate
docker-compose exec web python manage.py shell -c 'import init_db'
clean
docker-compose up --build -d
execdb dropdb -U fedireads fedireads
execdb createdb -U fedireads fedireads
initdb
clean
;;
makemigrations)
docker-compose exec web python manage.py makemigrations
execweb python manage.py makemigrations
;;
migrate)
docker-compose exec web python manage.py migrate
execweb python manage.py migrate
;;
bash)
execweb bash
;;
shell)
docker-compose exec web python manage.py shell
execweb python manage.py shell
;;
dbshell)
docker-compose exec db psql -U fedireads fedireads
execdb psql -U fedireads fedireads
;;
restart_celery)
docker-compose restart celery_worker
;;
test)
shift 1
docker-compose exec web coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@"
execweb coverage run --source='.' --omit="*/test*,celerywyrm*,bookwyrm/migrations/*" manage.py test "$@"
;;
pytest)
shift 1
execweb pytest "$@"
;;
test_report)
docker-compose exec web coverage report
execweb coverage report
;;
collectstatic)
docker-compose exec web python manage.py collectstatic --no-input
execweb python manage.py collectstatic --no-input
;;
build)
docker-compose build
;;
clean)
clean
;;
*)
echo "Unrecognised command. Try: up, initdb, resetdb, makemigrations, migrate, shell, dbshell, restart_celery, test, test_report"
echo "Unrecognised command. Try: build, clean, up, initdb, resetdb, makemigrations, migrate, bash, shell, dbshell, restart_celery, test, pytest, test_report"
;;
esac

View file

@ -1,91 +0,0 @@
''' starter data '''
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from bookwyrm.models import Connector, User
from bookwyrm.settings import DOMAIN
groups = ['admin', 'moderator', 'editor']
for group in groups:
Group.objects.create(name=group)
permissions = [{
'codename': 'edit_instance_settings',
'name': 'change the instance info',
'groups': ['admin',]
}, {
'codename': 'set_user_group',
'name': 'change what group a user is in',
'groups': ['admin', 'moderator']
}, {
'codename': 'control_federation',
'name': 'control who to federate with',
'groups': ['admin', 'moderator']
}, {
'codename': 'create_invites',
'name': 'issue invitations to join',
'groups': ['admin', 'moderator']
}, {
'codename': 'moderate_user',
'name': 'deactivate or silence a user',
'groups': ['admin', 'moderator']
}, {
'codename': 'moderate_post',
'name': 'delete other users\' posts',
'groups': ['admin', 'moderator']
}, {
'codename': 'edit_book',
'name': 'edit book info',
'groups': ['admin', 'moderator', 'editor']
}]
content_type = ContentType.objects.get_for_model(User)
for permission in permissions:
permission_obj = Permission.objects.create(
codename=permission['codename'],
name=permission['name'],
content_type=content_type,
)
# add the permission to the appropriate groups
for group_name in permission['groups']:
Group.objects.get(name=group_name).permissions.add(permission_obj)
# while the groups and permissions shouldn't be changed because the code
# depends on them, what permissions go with what groups should be editable
Connector.objects.create(
identifier=DOMAIN,
name='Local',
local=True,
connector_file='self_connector',
base_url='https://%s' % DOMAIN,
books_url='https://%s/book' % DOMAIN,
covers_url='https://%s/images/covers' % DOMAIN,
search_url='https://%s/search?q=' % DOMAIN,
priority=1,
)
Connector.objects.create(
identifier='bookwyrm.social',
name='BookWyrm dot Social',
connector_file='bookwyrm_connector',
base_url='https://bookwyrm.social' ,
books_url='https://bookwyrm.social/book',
covers_url='https://bookwyrm.social/images/covers',
search_url='https://bookwyrm.social/search?q=',
priority=2,
)
Connector.objects.create(
identifier='openlibrary.org',
name='OpenLibrary',
connector_file='openlibrary',
base_url='https://openlibrary.org',
books_url='https://openlibrary.org',
covers_url='https://covers.openlibrary.org',
search_url='https://openlibrary.org/search?q=',
priority=3,
)

6
pytest.ini Normal file
View file

@ -0,0 +1,6 @@
[pytest]
DJANGO_SETTINGS_MODULE = bookwyrm.settings
python_files = tests.py test_*.py *_tests.py
addopts = --cov=bookwyrm --cov-config=.coveragerc
markers =
integration: marks tests as requiring external resources (deselect with '-m "not integration"')

View file

@ -21,5 +21,5 @@ fi
python manage.py makemigrations fedireads
python manage.py migrate
python manage.py shell < init_db.py
python manage.py initdb
python manage.py runserver

View file

@ -7,6 +7,9 @@ flower==0.9.4
Pillow>=7.1.0
psycopg2==2.8.4
pycryptodome==3.9.4
pytest-django==4.1.0
pytest==6.1.2
pytest-cov==2.10.1
python-dateutil==2.8.1
redis==3.4.1
requests==2.22.0