aboutsummaryrefslogtreecommitdiffstats
path: root/tests/backend.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/backend.py')
-rw-r--r--tests/backend.py326
1 files changed, 326 insertions, 0 deletions
diff --git a/tests/backend.py b/tests/backend.py
new file mode 100644
index 00000000..6346744d
--- /dev/null
+++ b/tests/backend.py
@@ -0,0 +1,326 @@
+
+import os
+import json
+import pytest
+import fatcat
+import fatcat.sql
+from fatcat.models import *
+import unittest
+import tempfile
+
+## Helpers ##################################################################
+
+def check_entity_fields(e):
+ for key in ('rev', 'is_live', 'redirect_id'):
+ assert key in e
+ for key in ('id',):
+ assert e[key] is not None
+
+def check_release(e):
+ for key in ('work', 'release_type'):
+ assert key in e
+ for key in ('title'):
+ assert e[key] is not None
+ for key in ('refs', 'creators'):
+ assert type(e[key]) == list
+
+def check_creator(e):
+ for key in ('name',):
+ assert e[key] is not None
+
+def check_container(e):
+ for key in ('name',):
+ assert e[key] is not None
+
+def check_file(e):
+ for key in ('size', 'sha1'):
+ assert e[key] is not None
+
+@pytest.fixture
+def app():
+ fatcat.app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
+ fatcat.app.testing = True
+ fatcat.app.debug = True
+ fatcat.db.session.remove()
+ fatcat.db.drop_all()
+ fatcat.db.create_all()
+ fatcat.sql.populate_db()
+ return fatcat.app.test_client()
+
+
+## Model Tests ###############################################################
+
+def test_example_works(app):
+ fatcat.dummy.insert_example_works()
+
+def test_random_works(app):
+ fatcat.dummy.insert_random_works()
+
+def test_load_crossref(app):
+ with open('./tests/files/crossref-works.2018-01-21.badsample.json', 'r') as f:
+ raw = [json.loads(l) for l in f.readlines() if len(l) > 3]
+ for obj in raw:
+ fatcat.sql.add_crossref_via_model(obj)
+
+def test_schema_release_rev(app):
+ assert ReleaseRev.query.count() == 0
+ e = {
+ "title": "Bogus title",
+ "release_type": "book",
+ "creators": [],
+ "refs": [],
+ }
+ model = release_rev_schema.load(e)
+ fatcat.db.session.add(model.data)
+ fatcat.db.session.commit()
+ assert ReleaseRev.query.count() == 1
+ model_after = ReleaseRev.query.first()
+ serial = release_rev_schema.dump(model_after).data
+ #check_release(serial)
+ for k in e.keys():
+ assert e[k] == serial[k]
+
+def test_schema_creator_rev(app):
+ assert ReleaseRev.query.count() == 0
+ e = {
+ "name": "Robin (Batman)",
+ }
+ model = creator_rev_schema.load(e)
+ fatcat.db.session.add(model.data)
+ fatcat.db.session.commit()
+ assert CreatorRev.query.count() == 1
+ model_after = CreatorRev.query.first()
+ serial = creator_rev_schema.dump(model_after).data
+ check_creator(serial)
+ for k in e.keys():
+ assert e[k] == serial[k]
+
+def test_schema_container_rev(app):
+ assert ReleaseRev.query.count() == 0
+ e = {
+ "name": "Papers Monthly",
+ }
+ model = container_rev_schema.load(e)
+ fatcat.db.session.add(model.data)
+ fatcat.db.session.commit()
+ assert ContainerRev.query.count() == 1
+ model_after = ContainerRev.query.first()
+ serial = container_rev_schema.dump(model_after).data
+ check_container(serial)
+ for k in e.keys():
+ assert e[k] == serial[k]
+
+def test_schema_file_rev(app):
+ assert ReleaseRev.query.count() == 0
+ e = {
+ "sha1": "asdf",
+ "size": 6,
+ }
+ model = file_rev_schema.load(e)
+ print(model)
+ fatcat.db.session.add(model.data)
+ fatcat.db.session.commit()
+ assert FileRev.query.count() == 1
+ model_after = FileRev.query.first()
+ serial = file_rev_schema.dump(model_after).data
+ check_file(serial)
+ for k in e.keys():
+ assert e[k] == serial[k]
+
+## API Tests #################################################################
+
+def test_health(app):
+ rv = app.get('/health')
+ obj = json.loads(rv.data.decode('utf-8'))
+ assert obj['ok']
+
+def test_api_work(app):
+ fatcat.dummy.insert_example_works()
+
+ # Invalid Id
+ rv = app.get('/v0/work/_')
+ assert rv.status_code == 404
+
+ # Random
+ rv = app.get('/v0/work/random')
+ rv = app.get(rv.location)
+ work = json.loads(rv.data.decode('utf-8'))
+ check_entity_fields(work)
+ print(work)
+ assert work['title']
+ assert work['work_type']
+
+ # Valid Id (from random above)
+ rv = app.get('/v0/work/{}'.format(work['id']))
+ assert rv.status_code == 200
+
+ # Missing Id
+ rv = app.get('/v0/work/r3zga5b9cd7ef8gh084714iljk')
+ assert rv.status_code == 404
+
+def test_api_work_create(app):
+ assert WorkIdent.query.count() == 0
+ assert WorkRev.query.count() == 0
+ assert WorkEdit.query.count() == 0
+ assert ExtraJson.query.count() == 0
+ rv = app.post('/v0/work',
+ data=json.dumps(dict(title="dummy", work_type="thing", extra=dict(a=1, b="zing"))),
+ headers={"content-type": "application/json"})
+ print(rv)
+ assert rv.status_code == 200
+ assert WorkIdent.query.count() == 1
+ assert WorkRev.query.count() == 1
+ assert WorkEdit.query.count() == 1
+ assert ExtraJson.query.count() == 1
+ # not alive yet
+ assert WorkIdent.query.filter(WorkIdent.is_live==True).count() == 0
+
+def test_api_rich_create(app):
+
+ # TODO: create user?
+
+ rv = app.post('/v0/editgroup',
+ data=json.dumps(dict(
+ extra=dict(q=1, u="zing"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ editgroup_id = obj['id']
+
+ for cls in (WorkIdent, WorkRev, WorkEdit,
+ ContainerIdent, ContainerRev, ContainerEdit,
+ CreatorIdent, CreatorRev, CreatorEdit,
+ ReleaseIdent, ReleaseRev, ReleaseEdit,
+ FileIdent, FileRev, FileEdit,
+ ChangelogEntry):
+ assert cls.query.count() == 0
+
+ rv = app.post('/v0/container',
+ data=json.dumps(dict(
+ name="schmournal",
+ publisher="society of authors",
+ issn="2222-3333",
+ editgroup=editgroup_id,
+ extra=dict(a=2, i="zing"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ container_id = obj['id']
+
+ rv = app.post('/v0/creator',
+ data=json.dumps(dict(
+ name="anon y. mouse",
+ orcid="0000-0002-1825-0097",
+ editgroup=editgroup_id,
+ extra=dict(w=1, q="zing"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ creator_id = obj['id']
+
+ rv = app.post('/v0/work',
+ data=json.dumps(dict(
+ title="dummy work",
+ work_type="book",
+ editgroup=editgroup_id,
+ extra=dict(a=3, b="zing"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ work_id = obj['id']
+
+ # this stub work will be referenced
+ rv = app.post('/v0/release',
+ data=json.dumps(dict(
+ title="derivative work",
+ work_type="journal-article",
+ work=work_id,
+ creators=[creator_id],
+ doi="10.1234/58",
+ editgroup=editgroup_id,
+ refs=[
+ dict(stub="some other journal article"),
+ ],
+ extra=dict(f=7, b="zing"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ stub_release_id = obj['id']
+
+ rv = app.post('/v0/release',
+ data=json.dumps(dict(
+ title="dummy work",
+ work_type="book",
+ work=work_id,
+ container=container_id,
+ creators=[creator_id],
+ doi="10.1234/5678",
+ editgroup=editgroup_id,
+ refs=[
+ dict(stub="some book", target=stub_release_id),
+ ],
+ extra=dict(f=7, b="loopy"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ release_id = obj['id']
+
+ rv = app.post('/v0/file',
+ data=json.dumps(dict(
+ sha1="deadbeefdeadbeef",
+ size=1234,
+ releases=[release_id],
+ editgroup=editgroup_id,
+ extra=dict(f=4, b="zing"))),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ obj = json.loads(rv.data.decode('utf-8'))
+ file_id = obj['id']
+
+ for cls in (WorkIdent, WorkRev, WorkEdit,
+ ContainerIdent, ContainerRev, ContainerEdit,
+ CreatorIdent, CreatorRev, CreatorEdit,
+ FileIdent, FileRev, FileEdit):
+ assert cls.query.count() == 1
+ for cls in (ReleaseIdent, ReleaseRev, ReleaseEdit):
+ assert cls.query.count() == 2
+
+ for cls in (WorkIdent,
+ ContainerIdent,
+ CreatorIdent,
+ ReleaseIdent,
+ FileIdent):
+ assert cls.query.filter(cls.is_live==True).count() == 0
+
+ assert ChangelogEntry.query.count() == 0
+ rv = app.post('/v0/editgroup/{}/accept'.format(editgroup_id),
+ headers={"content-type": "application/json"})
+ assert rv.status_code == 200
+ assert ChangelogEntry.query.count() == 1
+
+ for cls in (WorkIdent, WorkRev, WorkEdit,
+ ContainerIdent, ContainerRev, ContainerEdit,
+ CreatorIdent, CreatorRev, CreatorEdit,
+ FileIdent, FileRev, FileEdit):
+ assert cls.query.count() == 1
+ for cls in (ReleaseIdent, ReleaseRev, ReleaseEdit):
+ assert cls.query.count() == 2
+
+ for cls in (WorkIdent,
+ ContainerIdent,
+ CreatorIdent,
+ FileIdent):
+ assert cls.query.filter(cls.is_live==True).count() == 1
+ assert ReleaseIdent.query.filter(ReleaseIdent.is_live==True).count() == 2
+
+ # Test that foreign key relations worked
+ release_rv = json.loads(app.get('/v0/release/{}'.format(release_id)).data.decode('utf-8'))
+ print(release_rv)
+ assert(release_rv['creators'][0]['creator'] == creator_id)
+ assert(release_rv['container']['id'] == container_id)
+ assert(release_rv['work']['id'] == work_id)
+ assert(release_rv['refs'][0]['target'] == stub_release_id)
+
+ file_rv = json.loads(app.get('/v0/file/{}'.format(file_id)).data.decode('utf-8'))
+ print(file_rv)
+ assert(file_rv['releases'][0]['release'] == release_id)