def test_should_not_remove_parents_with_public_descendants(self) -> None: person = Person('P0') person.private = True child = Person('P1') child.private = False person.children.append(child) parent = Person('P2') parent.private = True person.parents.append(parent) anonymize_person(person) self.assertCountEqual([parent], person.parents)
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 = Citation('C0', source) citation.files.append(citation_file) event_as_subject = Event(None, Birth()) event_as_attendee = Event(None, 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) ancestry = Ancestry() ancestry.entities.append(person) privatize(ancestry) 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)
async def test_private(self): person = Person('P0') person.private = True expected = '<a href="/person/P0/index.html"><span class="private" title="This person\'s details are unavailable to protect their privacy.">private</span></a>' async with self._render(data={ 'person': person, }) as (actual, _): self.assertEqual(expected, actual)
async def test_private(self): person = Person('P0') person.private = True expected = '<div class="meta person-meta"><p>This person\'s details are unavailable to protect their privacy.</p></div>' async with self._render(data={ 'person': person, }) as (actual, _): self.assertEqual(expected, actual)
def test_with_private_person_should_anonymize(self, m_anonymize_person) -> None: person = Person('P0') person.private = True ancestry = Ancestry() ancestry.entities.append(person) anonymize(ancestry, AnonymousCitation(AnonymousSource())) m_anonymize_person.assert_called_once_with(person)
def test_privatize_person_without_relatives(self, expected, private, event: Optional[Event]): person = Person('P0') person.private = private if event is not None: Presence(person, Subject(), event) ancestry = Ancestry() ancestry.entities.append(person) privatize(ancestry) self.assertEquals(expected, person.private)
def test_clean_should_not_clean_person_with_public_children(self): ancestry = Ancestry() person = Person('P0') person.private = False ancestry.entities.append(person) child = Person('P1') child.private = True ancestry.entities.append(child) grandchild = Person('P2') grandchild.private = True ancestry.entities.append(grandchild) great_grandchild = Person('P3') great_grandchild.private = False ancestry.entities.append(great_grandchild) clean(ancestry) self.assertEqual(person, ancestry.entities[Person][person.id])
def test_clean_should_clean_person_with_private_children(self) -> None: ancestry = Ancestry() person = Person('P0') person.private = True ancestry.entities.append(person) child = Person('P1') child.private = True ancestry.entities.append(child) grandchild = Person('P2') grandchild.private = True ancestry.entities.append(grandchild) great_grandchild = Person('P3') great_grandchild.private = True ancestry.entities.append(great_grandchild) clean(ancestry) self.assertNotIn(person.id, ancestry.entities[Person])
def test_clean_should_not_clean_person_if_public(self): ancestry = Ancestry() person = Person('P0') person.private = False ancestry.entities.append(person) clean(ancestry) self.assertEqual(person, ancestry.entities[Person][person.id])
def test_privatize_person_with_child(self, expected, private, event: Optional[Event]): person = Person('P0') person.private = private child = Person('P1') if event is not None: Presence(child, Subject(), event) person.children.append(child) ancestry = Ancestry() ancestry.entities.append(person) privatize(ancestry) self.assertEquals(expected, person.private)
async def test_post_parse(self) -> None: person = Person('P0') person.private = True PersonName(person, 'Jane', 'Dough') with TemporaryDirectory() as output_directory_path: configuration = Configuration(output_directory_path, 'https://example.com') configuration.extensions.add(ExtensionConfiguration(Anonymizer)) async with App(configuration) as app: app.ancestry.entities.append(person) await load(app) self.assertEquals(0, len(person.names))
def test_privatize_person_with_grandparent(self, expected, private, event: Optional[Event]): person = Person('P0') person.private = private parent = Person('P1') person.parents.append(parent) grandparent = Person('P2') if event is not None: Presence(grandparent, Subject(), event) parent.parents.append(grandparent) ancestry = Ancestry() ancestry.entities.append(person) privatize(ancestry) self.assertEquals(expected, person.private)
def _privatize_person(person: Person, seen: List, lifetime_threshold: int) -> None: # Do not change existing explicit privacy declarations. if person.private is None: person.private = _person_is_private(person, lifetime_threshold) if not person.private: return for presence in person.presences: if isinstance(presence.role, Subject): _mark_private(presence.event) _privatize_event(presence.event, seen) _privatize_has_citations(person, seen) _privatize_has_files(person, seen)
def _load_person(loader: _Loader, element: ElementTree.Element): person_handle = element.get('handle') person = Person(element.get('id')) name_elements = sorted(_xpath(element, './ns:name'), key=lambda x: x.get('alt') == '1') names = [] for name_element in name_elements: is_alternative = name_element.get('alt') == '1' individual_name_element = _xpath1(name_element, './ns:first') individual_name = None if individual_name_element is None else individual_name_element.text surname_elements = [ surname_element for surname_element in _xpath(name_element, './ns:surname') if surname_element.text is not None ] if surname_elements: for surname_element in surname_elements: if not is_alternative: is_alternative = surname_element.get('prim') == '0' affiliation_name = surname_element.text surname_prefix = surname_element.get('prefix') if surname_prefix is not None: affiliation_name = '%s %s' % (surname_prefix, affiliation_name) person_name = PersonName(None, individual_name, affiliation_name) _load_citationref(loader, person_name, name_element) names.append((person_name, is_alternative)) elif individual_name is not None: person_name = PersonName(None, individual_name) _load_citationref(loader, person_name, name_element) names.append((person_name, is_alternative)) for person_name, _ in sorted(names, key=lambda x: x[1]): loader.add_entity(person_name) loader.add_association(Person, person_handle, 'names', PersonName, person_name.id) _load_eventrefs(loader, person_handle, element) if element.get('priv') == '1': person.private = True flattened_person = FlattenedEntity(person, person_handle) _load_citationref(loader, flattened_person, element) _load_objref(loader, flattened_person, element) _load_urls(person, element) _load_attribute_privacy(person, element, 'attribute') loader.add_entity(flattened_person)
async def test_private_person(self): person_id = 'P1' individual_name = 'Jane' person = Person(person_id) PersonName(person, individual_name) person.private = True with TemporaryDirectory() as output_directory_path: configuration = Configuration(output_directory_path, 'https://example.com') configuration.locales.replace([ LocaleConfiguration('en-US', 'en'), LocaleConfiguration('nl-NL', 'nl'), ]) async with App(configuration) as app: app.ancestry.entities.append(person) indexed = [item for item in Index(app).build()] self.assertEquals([], indexed)
async 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) PersonName(person, 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(Citation('the_citation', Source('The Source'))) Presence(person, Subject(), Event('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', }, ], } await self.assert_encodes(expected, person, 'person')