class Test(TemplateTestCase): template_file = 'label/place.html.j2' @parameterized.expand([ ('<address><a href="/place/P0/index.html"><span>The Place</span></a></address>', { 'place': Place('P0', [PlaceName('The Place')]), }), ('<address><a href="/place/P0/index.html"><span lang="en">The Place</span></a></address>', { 'place': Place('P0', [PlaceName('The Place', 'en')]), }), ('<address><a href="/place/P0/index.html"><span lang="nl">De Plaats</span></a></address>', { 'place': Place('P0', [PlaceName('The Place', 'en'), PlaceName('De Plaats', 'nl')]), 'locale': 'nl', }), ('<address><span>The Place</span></address>', { 'place': Place('P0', [PlaceName('The Place')]), 'embedded': True, }), ('<address><a href="/place/P0/index.html"><span lang="nl">De Nieuwe Plaats</span></a></address>', { 'place': Place('P0', [PlaceName('The Old Place', 'en', date=DateRange(None, Date(1969, 12, 31))), PlaceName('De Nieuwe Plaats', 'nl', date=DateRange(Date(1970, 1, 1)))]), 'locale': 'nl', 'date_context': Date(1970, 1, 1), }) ]) @sync async def test(self, expected, data): async with self._render(data=data) as (actual, _): self.assertEqual(expected, actual)
def test_enclosed_by_should_sync_references(self): sut = Place('1', [LocalizedName('one')]) enclosing_place = Place('2', [LocalizedName('two')]) sut.enclosed_by = enclosing_place self.assertEquals(enclosing_place, sut.enclosed_by) self.assertIn(sut, enclosing_place.encloses) sut.enclosed_by = None self.assertIsNone(sut.enclosed_by) self.assertCountEqual([], enclosing_place.encloses)
def test_enclosed_by_should_sync_references(self): sut = Place('1', [PlaceName('one')]) enclosing_place = Place('2', [PlaceName('two')]) enclosure = Enclosure(sut, enclosing_place) self.assertIn(enclosure, sut.enclosed_by) self.assertEquals(sut, enclosure.encloses) sut.enclosed_by.remove(enclosure) self.assertCountEqual([], sut.enclosed_by) self.assertIsNone(enclosure.encloses)
def test_encloses_should_sync_references(self): sut = Place('1', [LocalizedName('one')]) enclosed_place = Place('2', [LocalizedName('two')]) sut.encloses.append(enclosed_place) self.assertIn(enclosed_place, sut.encloses) self.assertEquals(sut, enclosed_place.enclosed_by) sut.encloses.remove(enclosed_place) self.assertCountEqual([], sut.encloses) self.assertEquals(None, enclosed_place.enclosed_by)
def test_encloses(self) -> None: sut = Place('P1', [PlaceName('The Place')]) self.assertCountEqual([], sut.encloses) enclosed_place = Place('P2', [PlaceName('The Other Place')]) enclosure = Enclosure(enclosed_place, sut) self.assertIn(enclosure, sut.encloses) self.assertEquals(sut, enclosure.enclosed_by) sut.encloses.remove(enclosure) self.assertCountEqual([], sut.encloses) self.assertIsNone(enclosure.enclosed_by)
async def test_with_enclosing_place_without_place_context(self): place = Place('P0', [PlaceName('The Place')]) enclosing_place = Place('P1', [PlaceName('The Enclosing Place')]) Enclosure(place, enclosing_place) all_enclosing_place = Place('P2', [PlaceName('The All-enclosing Place')]) Enclosure(enclosing_place, all_enclosing_place) expected = '<div class="meta">in <address><a href="/place/P1/index.html"><span>The Enclosing Place</span></a></address>, <address><a href="/place/P2/index.html"><span>The All-enclosing Place</span></a></address></div>' async with self._render(data={ 'place': place, }) as (actual, _): self.assertEqual(expected, actual)
def _parse_place(element: Element) -> Tuple[str, _IntermediatePlace]: handle = _xpath1(element, './@handle') properties = {'name': _xpath1(element, './ns:pname/@value')} place = Place(_xpath1(element, './@id'), **properties) coordinates = _parse_coordinates(element) if coordinates: place.coordinates = coordinates # Set the first place reference as the place that encloses this place. enclosed_by_handle = _xpath1(element, './ns:placeref/@hlink') _parse_urls(place, element) return handle, _IntermediatePlace(place, enclosed_by_handle)
async def test_without_enclosing_places(self): place = Place('P0', [PlaceName('The Place')]) expected = '<div class="meta"></div>' async with self._render(data={ 'place': place, }) as (actual, _): self.assertEqual(expected, actual)
def test_ancestry_should_encode_full(self): ancestry = Ancestry() place_id = 'the_place' place_name = 'The Place' place = Place(place_id, place_name) ancestry.places[place_id] = place person_id = 'the_person' person_family_name = 'Person' person_individual_name = 'The' person = Person(person_id, person_individual_name, person_family_name) ancestry.people[person_id] = person expected = { 'places': { place_id: { 'id': place_id, 'name': place_name, }, }, 'people': { person_id: { 'id': person_id, 'family_name': person_family_name, 'individual_name': person_individual_name, 'parent_ids': [], 'child_ids': [], 'private': None, }, }, } self.assert_encodes(expected, ancestry)
class TestResourceTest(TemplateTestCase): @parameterized.expand([ ('true', Person, Person('P1')), ('false', Person, Place('P1', [PlaceName('The Place')])), ('true', Place, Place('P1', [PlaceName('The Place')])), ('false', Place, Person('P1')), ('false', Place, 999), ('false', Person, object()), ]) @sync async def test(self, expected, resource_type: Type[Resource], data) -> None: template = f'{{% if data is {resource_type.resource_type_name()}_resource %}}true{{% else %}}false{{% endif %}}' async with self._render(template_string=template, data={ 'data': data, }) as (actual, _): self.assertEquals(expected, actual)
class DelegatingUrlGeneratorTest(TestCase): @parameterized.expand([ ('/index.html', '/index.html'), ('/index.html', '<front>'), ('/person/index.html', '<person>'), ('/person/P1/index.html', Person('P1')), ('/event/index.html', '<event>'), ('/event/E1/index.html', Event('E1', Event.Type.DEATH)), ('/place/index.html', '<place>'), ('/place/P1/index.html', Place('P1', 'Place 1')), ('/file/index.html', '<file>'), ('/file/F1/index.html', File('F1', '/tmp')), ('/source/index.html', '<source>'), ('/source/S1/index.html', Source('S1', 'Source 1')), ('/citation/index.html', '<citation>'), ('/citation/C1/index.html', Citation('C1')), ]) def test_generate(self, expected: str, resource: Any): configuration = Configuration('/tmp', 'https://example.com') sut = DelegatingUrlGenerator(configuration) self.assertEquals(expected, sut.generate(resource)) def test_generate_with_invalid_value(self): configuration = Configuration('/tmp', 'https://example.com') sut = DelegatingUrlGenerator(configuration) with self.assertRaises(ValueError): sut.generate(9)
def setUpClass(cls): cls._outputDirectory = TemporaryDirectory() configuration = Configuration(cls._outputDirectory.name, 'https://ancestry.example.com') cls.site = Site(configuration) place1 = Place('PLACE1', 'one') event1 = Event('EVENT1', Event.Type.BIRTH) event1.place = place1 event1_person_1_presence = Presence(Presence.Role.SUBJECT) event1_person_1_presence.event = event1 person1 = Person('PERSON1', 'Janet', 'Dough') person1.presences.add(event1_person_1_presence) source1 = Source('SOURCE1', 'A Little Birdie') places = [place1] cls.site.ancestry.places.update({place.id: place for place in places}) events = [event1] cls.site.ancestry.events.update({event.id: event for event in events}) people = [person1] cls.site.ancestry.people.update( {person.id: person for person in people}) sources = [source1] cls.site.ancestry.sources.update( {source.id: source for source in sources}) render(cls.site)
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_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')
async def test_with_place(self): event = Event(Birth()) event.place = Place('P0', [PlaceName('The Place')]) expected = 'in <address><a href="/place/P0/index.html"><span>The Place</span></a></address>' async with self._render(data={ 'event': event, }) as (actual, _): self.assertEqual(expected, actual)
def test_place_should_encode_full(self): place_id = 'the_place' name = 'The Place' latitude = 12.345 longitude = -54.321 coordinates = Point(latitude, longitude) place = Place(place_id, name) place.coordinates = coordinates expected = { 'id': place_id, 'name': name, 'coordinates': { 'latitude': latitude, 'longitude': longitude, } } self.assert_encodes(expected, place)
def test_events_should_sync_references(self): sut = Place('1', 'one') event = Event('1', Event.Type.BIRTH) sut.events.add(event) self.assertIn(event, sut.events) self.assertEquals(sut, event.place) sut.events.remove(event) self.assertCountEqual([], sut.events) self.assertEquals(None, event.place)
def test_place_should_encode_minimal(self): place_id = 'the_place' name = 'The Place' place = Place(place_id, name) expected = { 'id': place_id, 'name': name, } self.assert_encodes(expected, place)
def test_place_should_sync_references(self): place = Place('1', 'one') sut = Event('1', Event.Type.BIRTH) sut.place = place self.assertEquals(place, sut.place) self.assertIn(sut, place.events) sut.place = None self.assertEquals(None, sut.place) self.assertNotIn(sut, place.events)
def test_place(self) -> None: place = Place('1', [PlaceName('one')]) sut = Event(Mock(EventType)) sut.place = place self.assertEquals(place, sut.place) self.assertIn(sut, place.events) sut.place = None self.assertEquals(None, sut.place) self.assertNotIn(sut, place.events)
def test_place_should_sync_references(self): place = Place('1', [PlaceName('one')]) sut = IdentifiableEvent('1', Birth()) sut.place = place self.assertEquals(place, sut.place) self.assertIn(sut, place.events) sut.place = None self.assertEquals(None, sut.place) self.assertNotIn(sut, place.events)
def test_events(self) -> None: sut = Place('P1', [PlaceName('The Place')]) event = IdentifiableEvent('1', Birth()) sut.events.append(event) self.assertIn(event, sut.events) self.assertEquals(sut, event.place) sut.events.remove(event) self.assertCountEqual([], sut.events) self.assertEquals(None, event.place)
def test_events_should_sync_references(self): sut = Place('1', [PlaceName('one')]) event = IdentifiableEvent('1', Birth()) sut.events.append(event) self.assertIn(event, sut.events) self.assertEquals(sut, event.place) sut.events.remove(event) self.assertCountEqual([], sut.events) self.assertEquals(None, event.place)
def test_place_should_sync_references(self): place = Place('1', [LocalizedName('one')]) sut = IdentifiableEvent('1', Event.Type.BIRTH) sut.place = place self.assertEquals(place, sut.place) self.assertIn(sut, place.events) sut.place = None self.assertEquals(None, sut.place) self.assertNotIn(sut, place.events)
def test_clean(self): ancestry = Ancestry() onymous_event = Event('E0', Event.Type.BIRTH) onymous_event_presence = Presence(Presence.Role.SUBJECT) onymous_event_presence.person = Person('P0') onymous_event.presences.add(onymous_event_presence) ancestry.events[onymous_event.id] = onymous_event anonymous_event = Event('E1', Event.Type.BIRTH) ancestry.events[anonymous_event.id] = anonymous_event onymous_place = Place('P0', 'Amsterdam') onymous_place.events.add(onymous_event) ancestry.places[onymous_place.id] = onymous_place anonymous_place = Place('P1', 'Almelo') ancestry.places[anonymous_place.id] = anonymous_place onmyous_place_because_encloses_onmyous_places = Place( 'P3', 'Netherlands') onmyous_place_because_encloses_onmyous_places.encloses.add( onymous_place) onmyous_place_because_encloses_onmyous_places.encloses.add( anonymous_place) ancestry.places[onmyous_place_because_encloses_onmyous_places. id] = onmyous_place_because_encloses_onmyous_places clean(ancestry) self.assertDictEqual({ onymous_event.id: onymous_event, }, ancestry.events) self.assertDictEqual( { onymous_place.id: onymous_place, onmyous_place_because_encloses_onmyous_places.id: onmyous_place_because_encloses_onmyous_places, }, ancestry.places) self.assertNotIn( anonymous_place, onmyous_place_because_encloses_onmyous_places.encloses)
async def test_with_place_is_place_context(self): event = Event(Birth()) place = Place('P0', [PlaceName('The Place')]) event.place = place expected = '' async with self._render(data={ 'event': event, 'place_context': place, }) as (actual, _): self.assertEqual(expected, actual)
def test_clean(self) -> None: ancestry = Ancestry() onymous_event = IdentifiableEvent('E0', Event.Type.BIRTH) Presence(Person('P0'), Presence.Role.SUBJECT, onymous_event) ancestry.events[onymous_event.id] = onymous_event anonymous_event = IdentifiableEvent('E1', Event.Type.BIRTH) ancestry.events[anonymous_event.id] = anonymous_event onymous_place = Place('P0', [LocalizedName('Amsterdam')]) onymous_place.events.append(onymous_event) ancestry.places[onymous_place.id] = onymous_place anonymous_place = Place('P1', [LocalizedName('Almelo')]) ancestry.places[anonymous_place.id] = anonymous_place onmyous_place_because_encloses_onmyous_places = Place( 'P3', [LocalizedName('Netherlands')]) onmyous_place_because_encloses_onmyous_places.encloses.append( onymous_place) onmyous_place_because_encloses_onmyous_places.encloses.append( anonymous_place) ancestry.places[onmyous_place_because_encloses_onmyous_places. id] = onmyous_place_because_encloses_onmyous_places clean(ancestry) self.assertDictEqual({ onymous_event.id: onymous_event, }, ancestry.events) self.assertDictEqual( { onymous_place.id: onymous_place, onmyous_place_because_encloses_onmyous_places.id: onmyous_place_because_encloses_onmyous_places, }, ancestry.places) self.assertNotIn( anonymous_place, onmyous_place_because_encloses_onmyous_places.encloses)
async def test_embedded(self): event = Event(Birth()) event.date = Date(1970) event.place = Place('P0', [PlaceName('The Place')]) event.citations.append(Citation(Source('The Source'))) expected = '1970 in <address><span>The Place</span></address>' async with self._render(data={ 'event': event, 'embedded': True, }) as (actual, _): self.assertEqual(expected, actual)
def test_clean(self) -> None: ancestry = Ancestry() onymous_event = IdentifiableEvent('E0', Birth()) Presence(Person('P0'), Subject(), onymous_event) ancestry.events[onymous_event.id] = onymous_event anonymous_event = IdentifiableEvent('E1', Birth()) ancestry.events[anonymous_event.id] = anonymous_event onymous_place = Place('P0', [PlaceName('Amsterdam')]) onymous_place.events.append(onymous_event) ancestry.places[onymous_place.id] = onymous_place anonymous_place = Place('P1', [PlaceName('Almelo')]) ancestry.places[anonymous_place.id] = anonymous_place onmyous_place_because_encloses_onmyous_places = Place( 'P3', [PlaceName('Netherlands')]) Enclosure(onymous_place, onmyous_place_because_encloses_onmyous_places) Enclosure(anonymous_place, onmyous_place_because_encloses_onmyous_places) ancestry.places[onmyous_place_because_encloses_onmyous_places. id] = onmyous_place_because_encloses_onmyous_places clean(ancestry) self.assertDictEqual({ onymous_event.id: onymous_event, }, ancestry.events) self.assertDictEqual( { onymous_place.id: onymous_place, onmyous_place_because_encloses_onmyous_places.id: onmyous_place_because_encloses_onmyous_places, }, ancestry.places) self.assertNotIn( anonymous_place, onmyous_place_because_encloses_onmyous_places.encloses)