async def test_post_parse(self): person = Person('P0') Presence(person, Subject(), Event(Birth())) source_file = File('F0', __file__) source = IdentifiableSource('S0', 'The Source') source.private = True source.files.append(source_file) citation_file = File('F0', __file__) citation_source = Source('The Source') citation = IdentifiableCitation('C0', citation_source) citation.private = True citation.files.append(citation_file) with TemporaryDirectory() as output_directory_path: configuration = Configuration(output_directory_path, 'https://example.com') configuration.plugins[Privatizer] = None async with Site(configuration) as site: site.ancestry.people[person.id] = person site.ancestry.sources[source.id] = source site.ancestry.citations[citation.id] = citation await parse(site) self.assertTrue(person.private) self.assertTrue(source_file.private) self.assertTrue(citation_file.private)
def test_citation_should_encode_full(self): citation = IdentifiableCitation( 'the_citation', IdentifiableSource('the_source', 'The Source')) citation.description = 'The Source Description' citation.facts.append(IdentifiableEvent('the_event', Birth())) expected = { '$schema': '/schema.json#/definitions/citation', '@type': 'https://schema.org/Thing', 'id': 'the_citation', 'source': '/en/source/the_source/index.json', 'facts': ['/en/event/the_event/index.json'], 'links': [ { 'url': '/en/citation/the_citation/index.json', 'relationship': 'canonical', 'mediaType': 'application/json', }, { 'url': '/nl/citation/the_citation/index.json', 'relationship': 'alternate', 'locale': 'nl-NL', }, { 'url': '/en/citation/the_citation/index.html', 'relationship': 'alternate', 'mediaType': 'text/html', }, ], } self.assert_encodes(expected, citation, 'citation')
def test_with_private_citation_should_anonymize( self, m_anonymize_citation) -> None: source = Source('The Source') citation = IdentifiableCitation('C0', source) citation.private = True ancestry = Ancestry() ancestry.citations[citation.id] = citation anonymize(ancestry) m_anonymize_citation.assert_called_once_with(citation, ANY)
def test_with_public_citation_should_not_anonymize( self, m_anonymize_citation) -> None: source = Source('The Source') citation = IdentifiableCitation('C0', source) citation.private = False ancestry = Ancestry() ancestry.citations[citation.id] = citation anonymize(ancestry) m_anonymize_citation.assert_not_called()
def test_privatize_citation_should_not_privatize_if_public(self): source_file = File('F0', __file__) source = Source('The Source') source.files.append(source_file) citation_file = File('F1', __file__) citation = IdentifiableCitation('C0', source) citation.private = False citation.files.append(citation_file) privatize_citation(citation) self.assertEqual(False, citation.private) self.assertIsNone(source.private) self.assertIsNone(citation_file.private) self.assertIsNone(source_file.private)
def test_privatize_citation_should_privatize_if_private(self): source_file = File('F0', __file__) source = Source('The Source') source.files.append(source_file) citation_file = File('F1', __file__) citation = IdentifiableCitation('C0', source) citation.private = True citation.files.append(citation_file) privatize_citation(citation) self.assertTrue(citation.private) self.assertTrue(source.private) self.assertTrue(citation_file.private) self.assertTrue(source_file.private)
def _load_citation(loader: _Loader, element: ElementTree.Element) -> None: handle = element.get('handle') source_handle = _xpath1(element, './ns:sourceref').get('hlink') citation = IdentifiableCitation(element.get('id'), loader._sources[source_handle]) citation.date = _load_date(element) _load_objref(loader, citation, element) _load_attribute_privacy(citation, element, 'srcattribute') page = _xpath1(element, './ns:page') if page is not None: citation.location = page.text loader._citations[handle] = citation
def test_privatize_person_should_privatize_if_private(self): source_file = File('F0', __file__) source = Source('The Source') source.files.append(source_file) citation_file = File('F1', __file__) citation = IdentifiableCitation('C0', source) citation.files.append(citation_file) event_as_subject = Event(Birth()) event_as_attendee = Event(Marriage()) person_file = File('F2', __file__) person = Person('P0') person.private = True person.citations.append(citation) person.files.append(person_file) Presence(person, Subject(), event_as_subject) Presence(person, Attendee(), event_as_attendee) privatize_person(person, 125) self.assertTrue(person.private) self.assertTrue(citation.private) self.assertTrue(source.private) self.assertTrue(person_file.private) self.assertTrue(citation_file.private) self.assertTrue(source_file.private) self.assertTrue(event_as_subject.private) self.assertIsNone(event_as_attendee.private)
def test_clean_should_not_clean_event_with_presences_with_people( self) -> None: ancestry = Ancestry() source = IdentifiableSource('S1', 'The Source') ancestry.sources[source.id] = source citation = IdentifiableCitation('C1', source) ancestry.citations[citation.id] = citation file = File('F1', __file__) ancestry.files[file.id] = file place = Place('P0', [PlaceName('The Place')]) ancestry.places[place.id] = place person = Person('P0') event = IdentifiableEvent('E0', Birth()) event.citations.append(citation) event.files.append(file) event.place = place ancestry.events[event.id] = event Presence(person, Subject(), event) clean(ancestry) self.assertEqual(event, ancestry.events[event.id]) self.assertIn(event, place.events) self.assertEqual(place, ancestry.places[place.id]) self.assertIn(event, citation.facts) self.assertEqual(citation, ancestry.citations[citation.id]) self.assertIn(event, file.resources) self.assertEqual(file, ancestry.files[file.id])
def test_clean_should_clean_event(self) -> None: ancestry = Ancestry() source = IdentifiableSource('S1', 'The Source') ancestry.sources[source.id] = source citation = IdentifiableCitation('C1', source) ancestry.citations[citation.id] = citation file = File('F1', __file__) ancestry.files[file.id] = file place = Place('P0', [PlaceName('The Place')]) ancestry.places[place.id] = place event = IdentifiableEvent('E0', Birth()) event.citations.append(citation) event.files.append(file) event.place = place ancestry.events[event.id] = event clean(ancestry) self.assertNotIn(event.id, ancestry.events) self.assertIsNone(event.place) self.assertNotIn(event, place.events) self.assertNotIn(place.id, ancestry.places) self.assertNotIn(event, citation.facts) self.assertNotIn(citation.id, ancestry.citations) self.assertNotIn(event, file.resources) self.assertNotIn(file.id, ancestry.files)
def test_citation_should_encode_minimal(self): citation = IdentifiableCitation('the_citation', Source('The Source')) expected = { '$schema': '/schema.json#/definitions/citation', '@type': 'https://schema.org/Thing', 'id': 'the_citation', 'facts': [], 'links': [ { 'url': '/en/citation/the_citation/index.json', 'relationship': 'canonical', 'mediaType': 'application/json', }, { 'url': '/nl/citation/the_citation/index.json', 'relationship': 'alternate', 'locale': 'nl-NL', }, { 'url': '/en/citation/the_citation/index.html', 'relationship': 'alternate', 'mediaType': 'text/html', }, ], } self.assert_encodes(expected, citation, 'citation')
def test_should_remove_source(self) -> None: source = Source('The Source') citation = IdentifiableCitation('C0', source) anonymous_source = AnonymousSource() anonymous_citation = AnonymousCitation(anonymous_source) anonymize_citation(citation, anonymous_citation) self.assertIsNone(citation.source)
async def test_citation(self): citation = IdentifiableCitation('CITATION1', Source('A Little Birdie')) self.site.ancestry.citations[citation.id] = citation await generate(self.site) self.assert_betty_html('/citation/%s/index.html' % citation.id) self.assert_betty_json('/citation/%s/index.json' % citation.id, 'citation')
def _parse_citation(ancestry: _IntermediateAncestry, element: Element) -> None: handle = _xpath1(element, './@handle') source_handle = _xpath1(element, './ns:sourceref/@hlink') citation = IdentifiableCitation(_xpath1(element, './@id'), ancestry.sources[source_handle]) citation.date = _parse_date(element) _parse_objref(ancestry, citation, element) _parse_attribute_privacy(citation, element, 'srcattribute') page = _xpath1(element, './ns:page') if page is not None: citation.location = page.text ancestry.citations[handle] = citation
def test_privatize_person_should_not_privatize_if_public(self): source_file = File('F0', __file__) source = Source('The Source') source.files.append(source_file) citation_file = File('F1', __file__) citation = IdentifiableCitation('C0', source) citation.files.append(citation_file) event_as_subject = Event(Birth()) event_as_attendee = Event(Marriage()) person_file = File('F2', __file__) person = Person('P0') person.private = False person.citations.append(citation) person.files.append(person_file) Presence(person, Subject(), event_as_subject) Presence(person, Attendee(), event_as_attendee) ancestry = Ancestry() ancestry.people[person.id] = person privatize(ancestry) self.assertEqual(False, person.private) self.assertIsNone(citation.private) self.assertIsNone(source.private) self.assertIsNone(person_file.private) self.assertIsNone(citation_file.private) self.assertIsNone(source_file.private) self.assertIsNone(event_as_subject.private) self.assertIsNone(event_as_attendee.private)
def test_event_should_encode_full(self): event = IdentifiableEvent('the_event', Birth()) event.date = DateRange(Date(2000, 1, 1), Date(2019, 12, 31)) event.place = Place('the_place', [PlaceName('The Place')]) Presence(Person('the_person'), Subject(), event) event.citations.append( IdentifiableCitation('the_citation', Source('The Source'))) expected = { '$schema': '/schema.json#/definitions/event', '@context': { 'place': 'https://schema.org/location', }, '@type': 'https://schema.org/Event', 'id': 'the_event', 'type': 'birth', 'presences': [ { '@context': { 'person': 'https://schema.org/actor', }, 'role': 'subject', 'person': '/en/person/the_person/index.json', }, ], 'citations': [ '/en/citation/the_citation/index.json', ], 'date': { 'start': { 'year': 2000, 'month': 1, 'day': 1, }, 'end': { 'year': 2019, 'month': 12, 'day': 31, }, }, 'place': '/en/place/the_place/index.json', 'links': [ { 'url': '/en/event/the_event/index.json', 'relationship': 'canonical', 'mediaType': 'application/json', }, { 'url': '/nl/event/the_event/index.json', 'relationship': 'alternate', 'locale': 'nl-NL', }, { 'url': '/en/event/the_event/index.html', 'relationship': 'alternate', 'mediaType': 'text/html', }, ], } self.assert_encodes(expected, event, 'event')
def test_source_should_encode_full(self): source = IdentifiableSource('the_source', 'The Source') source.author = 'The Author' source.publisher = 'The Publisher' source.date = Date(2000, 1, 1) source.contained_by = IdentifiableSource( 'the_containing_source', 'The Containing Source') link = Link('https://example.com/the-source') link.label = 'The Source Online' source.links.add(link) source.contains.append( IdentifiableSource('the_contained_source', 'The Contained Source')) IdentifiableCitation('the_citation', source) expected = { '$schema': '/schema.json#/definitions/source', '@context': { 'name': 'https://schema.org/name', }, '@type': 'https://schema.org/Thing', 'id': 'the_source', 'name': 'The Source', 'author': 'The Author', 'publisher': 'The Publisher', 'contains': [ '/en/source/the_contained_source/index.json', ], 'citations': [ '/en/citation/the_citation/index.json', ], 'containedBy': '/en/source/the_containing_source/index.json', 'date': { 'year': 2000, 'month': 1, 'day': 1, }, 'links': [ { 'url': '/en/source/the_source/index.json', 'relationship': 'canonical', 'mediaType': 'application/json', }, { 'url': '/nl/source/the_source/index.json', 'relationship': 'alternate', 'locale': 'nl-NL', }, { 'url': '/en/source/the_source/index.html', 'relationship': 'alternate', 'mediaType': 'text/html', }, { 'url': 'https://example.com/the-source', 'label': 'The Source Online', }, ], } self.assert_encodes(expected, source, 'source')
def test_should_remove_facts(self) -> None: source = Source('The Source') citation = IdentifiableCitation('C0', source) fact = PersonName('Jane') citation.facts.append(fact) anonymous_source = AnonymousSource() anonymous_citation = AnonymousCitation(anonymous_source) anonymize_citation(citation, anonymous_citation) self.assertEquals(0, len(citation.facts)) self.assertIn(fact, anonymous_citation.facts)
def test_should_remove_files(self) -> None: source = Source('The Source') citation = IdentifiableCitation('C0', source) file = File('F0', __file__) citation.files.append(file) anonymous_source = AnonymousSource() anonymous_citation = AnonymousCitation(anonymous_source) anonymize_citation(citation, anonymous_citation) self.assertEquals(0, len(citation.files)) self.assertIn(file, anonymous_citation.files)
async def test_populate_should_ignore_resource_without_link_support( self, m_retriever) -> None: source = Source('The Source') resource = IdentifiableCitation('the_citation', source) with TemporaryDirectory() as output_directory_path: with TemporaryDirectory() as cache_directory_path: configuration = Configuration(output_directory_path, 'https://example.com') configuration.cache_directory_path = cache_directory_path async with Site(configuration) as site: site.ancestry.citations[resource.id] = resource sut = _Populator(site, m_retriever) await sut.populate()
def test_clean_should_clean_citation(self) -> None: ancestry = Ancestry() source = IdentifiableSource('S0', 'The source') ancestry.sources[source.id] = source citation = IdentifiableCitation('C0', source) ancestry.citations[citation.id] = citation clean(ancestry) self.assertNotIn(citation.id, ancestry.citations) self.assertNotIn(citation, source.citations)
def test_clean_should_not_clean_source_with_citations(self) -> None: ancestry = Ancestry() source = IdentifiableSource('S0', 'The Source') ancestry.sources[source.id] = source citation = IdentifiableCitation('C0', source) citation.facts.append(PersonName('Jane')) ancestry.citations[citation.id] = citation clean(ancestry) self.assertEqual(source, ancestry.sources[source.id]) self.assertEqual(source, citation.source) self.assertEqual(citation, ancestry.citations[citation.id])
def test_clean_should_not_clean_file_with_citations(self) -> None: ancestry = Ancestry() source = Source() citation = IdentifiableCitation('C1', source) ancestry.citations[citation.id] = citation file = File('F0', __file__) file.citations.append(citation) ancestry.files[file.id] = file clean(ancestry) self.assertEqual(file, ancestry.files[file.id]) self.assertIn(citation, file.citations) self.assertEqual(citation, ancestry.citations[citation.id])
def test_clean_should_not_clean_citation_with_files(self) -> None: ancestry = Ancestry() source = IdentifiableSource('S0', 'The Source') ancestry.sources[source.id] = source file = File('F0', __file__) ancestry.files[file.id] = file citation = IdentifiableCitation('C0', source) citation.files.append(file) ancestry.citations[citation.id] = citation clean(ancestry) self.assertEqual(citation, ancestry.citations[citation.id]) self.assertEqual(file, ancestry.files[file.id]) self.assertIn(citation, source.citations) self.assertEqual(source, ancestry.sources[source.id])
def test_clean_should_not_clean_citation_with_facts(self) -> None: ancestry = Ancestry() source = IdentifiableSource('S0', 'The Source') ancestry.sources[source.id] = source citation = IdentifiableCitation('C0', source) citation.facts.append(PersonName('Jane')) ancestry.citations[citation.id] = citation fact = Person('P0') fact.citations.append(citation) ancestry.people[fact.id] = fact clean(ancestry) self.assertEqual(citation, ancestry.citations[citation.id]) self.assertIn(citation, fact.citations) self.assertEqual(fact, ancestry.people[fact.id])
class SiteUrlGeneratorTest(TestCase): @parameterized.expand([ ('/index.html', '/index.html'), ('/person/P1/index.html', Person('P1')), ('/event/E1/index.html', IdentifiableEvent('E1', Death())), ('/place/P1/index.html', Place('P1', [PlaceName('Place 1')])), ('/file/F1/index.html', File('F1', '/tmp')), ('/source/S1/index.html', IdentifiableSource('S1', 'Source 1')), ('/citation/C1/index.html', IdentifiableCitation('C1', Source('Source 1'))), ]) def test_generate(self, expected: str, resource: Any): configuration = Configuration('/tmp', 'https://example.com') sut = SiteUrlGenerator(configuration) self.assertEquals(expected, sut.generate(resource, 'text/html')) def test_generate_with_invalid_value(self): configuration = Configuration('/tmp', 'https://example.com') sut = SiteUrlGenerator(configuration) with self.assertRaises(ValueError): sut.generate(9, 'text/html')
def test_privatize_event_should_privatize_if_private(self): source_file = File('F0', __file__) source = Source('The Source') source.files.append(source_file) citation_file = File('F1', __file__) citation = IdentifiableCitation('C0', source) citation.files.append(citation_file) event_file = File('F1', __file__) event = Event(Birth()) event.private = True event.citations.append(citation) event.files.append(event_file) person = Person('P0') Presence(person, Subject(), event) privatize_event(event) self.assertTrue(event.private) self.assertTrue(event_file.private) self.assertTrue(citation.private) self.assertTrue(source.private) self.assertTrue(citation_file.private) self.assertTrue(source_file.private) self.assertIsNone(person.private)
def test_privatize_event_should_not_privatize_if_public(self): source_file = File('F0', __file__) source = Source('The Source') source.files.append(source_file) citation_file = File('F1', __file__) citation = IdentifiableCitation('C0', source) citation.files.append(citation_file) event_file = File('F1', __file__) event = IdentifiableEvent('E1', Birth()) event.private = False event.citations.append(citation) event.files.append(event_file) person = Person('P0') Presence(person, Subject(), event) ancestry = Ancestry() ancestry.events[event.id] = event privatize(ancestry) self.assertEqual(False, event.private) self.assertIsNone(event_file.private) self.assertIsNone(citation.private) self.assertIsNone(source.private) self.assertIsNone(citation_file.private) self.assertIsNone(source_file.private) self.assertIsNone(person.private)
def test_id(self) -> None: citation_id = 'C1' sut = IdentifiableCitation(citation_id, Mock(Source)) self.assertEquals(citation_id, sut.id)
def test_person_should_encode_full(self): parent_id = 'the_parent' parent = Person(parent_id) child_id = 'the_child' child = Person(child_id) sibling_id = 'the_sibling' sibling = Person(sibling_id) sibling.parents.append(parent) person_id = 'the_person' person_affiliation_name = 'Person' person_individual_name = 'The' person = Person(person_id) person.names.append( PersonName(person_individual_name, person_affiliation_name)) person.parents.append(parent) person.children.append(child) person.private = False link = Link('https://example.com/the-person') link.label = 'The Person Online' person.links.add(link) person.citations.append( IdentifiableCitation('the_citation', Source('The Source'))) Presence(person, Subject(), IdentifiableEvent('the_event', Birth())) expected = { '$schema': '/schema.json#/definitions/person', '@context': { 'parents': 'https://schema.org/parent', 'children': 'https://schema.org/child', 'siblings': 'https://schema.org/sibling', }, '@type': 'https://schema.org/Person', 'id': person_id, 'names': [ { '@context': { 'individual': 'https://schema.org/givenName', 'affiliation': 'https://schema.org/familyName', }, 'individual': person_individual_name, 'affiliation': person_affiliation_name, }, ], 'parents': [ '/en/person/the_parent/index.json', ], 'children': [ '/en/person/the_child/index.json', ], 'siblings': [ '/en/person/the_sibling/index.json', ], 'private': False, 'presences': [ { '@context': { 'event': 'https://schema.org/performerIn', }, 'role': 'subject', 'event': '/en/event/the_event/index.json', }, ], 'citations': [ '/en/citation/the_citation/index.json', ], 'links': [ { 'url': '/en/person/the_person/index.json', 'relationship': 'canonical', 'mediaType': 'application/json', }, { 'url': '/nl/person/the_person/index.json', 'relationship': 'alternate', 'locale': 'nl-NL', }, { 'url': '/en/person/the_person/index.html', 'relationship': 'alternate', 'mediaType': 'text/html', }, { 'url': 'https://example.com/the-person', 'label': 'The Person Online', }, ], } self.assert_encodes(expected, person, 'person')