from interface.tests import AccessTestCase from django.contrib.auth.models import User from interface.models import Ensemble, Project from . import models from .views.api import WorkSerializer class LibraryTestCase(AccessTestCase): USERS = ( {'username': 'admin', 'password': 'secret', 'is_superuser': True, 'is_staff': True}, {'username': 'homer', 'password': 'maggie'}, ) ENSEMBLES = ( {'name': 'The Be Sharps', 'slug': 'be-sharps', 'admins': ['homer']}, {'name': 'Lisa & the Bleeding Gums', 'slug': 'bleeding-gums'}, {'name': 'Party Posse'}, ) PROJECTS = ( {'name': 'Baker St', 'ensemble': 'bleeding-gums', 'when': -12}, {'name': 'Navy Recruitment Day', 'ensemble': 'party-posse', 'when': 6}, {'name': 'Barbershop Contest', 'ensemble': 'be-sharps', 'when': 28}, {'name': 'Open Mic Night', 'ensemble': 'bleeding-gums', 'when': 1 }, ) COLLECTIONS = ( {'name': 'Springfield Elementary Library', 'prefix': 'sel'}, {'name': 'Neds Library', 'prefix': 'ned', 'admins': ['homer']}, ) WORKS = ( {'name': 'Baby on Board', 'collection': 'ned', 'docs': [{'upload': 'local:baby_on_board.pdf'}]}, ) PROTECTED_URLS = ( '/collections/1', '/collections/1/add', '/collections/2/works/1', '/collections/2/works/1/edit', '/collections/2/works/1/partset', '/collections/2/works/1/add_to_project', '/collections/2/works/1/upload', '/collections/2/docs/1/annotate', # Need to add storage before we can test these #'/api/collections/2', #'/api/collections/2/works/1', '/admin/library/collection/', '/admin/library/document/', '/admin/library/ensembleaccess/', '/admin/library/orchestration/', '/admin/library/projectitem/', '/admin/library/work/', ) @classmethod def setUpTestData(cls): super().setUpTestData() cls.collections = {} for details in cls.COLLECTIONS: admins = details.pop('admins', []) obj = models.Collection.objects.create(**details) for admin in admins: obj.administrators.add(cls.users[admin]) cls.collections[details['prefix']] = obj cls.works = {} for details in cls.WORKS: collection = cls.collections[details.pop('collection')] #details.setdefault('docs', []) #details.setdefault('meta_info', []) #s = WorkSerializer(data=details) #assert s.is_valid(), s.errors #s.save(collection_id=collection.pk) docs = details.pop('docs', []) obj = models.Work.objects.create(collection=collection, **details) for doc in docs: obj.docs.create(**doc) cls.works[details['name']] = obj def test_integration(self): pass def test_superuser_access(self): self.login('admin', 'secret') self.assertAccess({ '/collections': True, '/collections/1': True, '/collections/2/works/1': True, }) def test_administrator_access(self): self.login('homer', 'maggie') self.assertAccess({ '/collections': True, '/collections/1': False, '/collections/2': True, '/collections/2/works/1': True, }) def test_link_access(self): self.assertAccess({ '/collections': True, '/collections/1': False, '/collections/2': False, '/collections/2/works/1': False, }) self.authorize(models.Collection, pk=2) self.assertAccess({ '/collections': True, '/collections/1': False, '/collections/2': True, '/collections/2/works/1': True, }) def test_anon_access(self): self.assertAccess({ '/collections': True, '/collections/1': False, '/collections/2': False, '/collections/2/works/1': False, }) def test_movement_from_large_work(self): ''' Will be common to store a work which has several movements, but the project is only going to play one. This also should give us the ability to store an anthology as one Work have Project reference 'no:23' ''' work = self.collections['sel'].works.create(name="Some Quartet", composer="Beethoven") for g in ('vl-1', 'vl-2', 'vla', 'vc'): doc = work.docs.create(upload=f'sel/beethoven/some_quartet/some_quartet_{g}.pdf') doc.sections.create(tag='mvmt-1', start=1, end=3) doc.sections.create(tag='mvmt-2', start=4, end=8) doc.sections.create(tag='mvmt-3', start=9, end=12) doc.sections.create(tag=g) # no tags - get nothing (should it be everything?) self.assertEqual(work.extract(), []) # single tag - should get just that range self.assertEqual(work.extract('vl-1'), [('sel/beethoven/some_quartet/some_quartet_vl-1.pdf', None, None)]) # single tag - returns all documents with that range result = work.extract('mvmt-2') self.assertEqual(len(result), 4) # multiple tags - returns the overlapping portion of all documents that have all tags self.assertEqual(work.extract('vl-1', 'mvmt-2'), [('sel/beethoven/some_quartet/some_quartet_vl-1.pdf', 4, 8)]) self.assertEqual(work.extract('vl-1', 'vl-2'), [])