Exemplo n.º 1
0
 async def test_post_parse(self) -> None:
     event = Event('E0', Birth())
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         configuration.extensions.add(ExtensionConfiguration(Cleaner))
         async with App(configuration) as app:
             app.ancestry.entities.append(event)
             await load(app)
             self.assertEquals([], list(app.ancestry.entities[Event]))
Exemplo n.º 2
0
 async def _parse(self, xml: str) -> Ancestry:
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         async with Site(configuration) as site:
             with NamedTemporaryFile(mode='r+') as f:
                 f.write(xml.strip())
                 f.seek(0)
                 parse_xml(site, f.name)
                 return site.ancestry
Exemplo n.º 3
0
    async def test_post_parse(self):
        person = Person('P0')
        reference_presence = Presence(person, Subject(), Event(Residence()))
        reference_presence.event.date = Date(1970, 1, 1)

        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.extensions[Deriver] = None
            async with App(configuration) as app:
                app.ancestry.people[person.id] = person
                await load(app)

        self.assertEquals(3, len(person.presences))
        self.assertEquals(
            DateRange(None, Date(1970, 1, 1), end_is_boundary=True),
            person.start.date)
        self.assertEquals(DateRange(Date(1970, 1, 1), start_is_boundary=True),
                          person.end.date)
Exemplo n.º 4
0
    def test_post_render_config_with_content_negotiation(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(
                output_directory_path, 'http://example.com')
            configuration.content_negotiation = True
            configuration.plugins[Nginx] = {}
            site = Site(configuration)
            render(site)
            expected = '''server {
	listen 80;
	server_name example.com;
	root %s;
	add_header Cache-Control "max-age=86400";
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_types text/css application/javascript application/json application/xml;

        set_by_lua_block $content_type_extension {
            local available_content_types = {'text/html', 'application/json'}
            local content_type_extensions = {}
            content_type_extensions['text/html'] = 'html'
            content_type_extensions['application/json'] = 'json'
            local content_type = require('cone').negotiate(ngx.req.get_headers()['Accept'], available_content_types)
            return content_type_extensions[content_type]
        }
    index index.$content_type_extension;

        location / {
            # Handle HTTP error responses.
            error_page 401 /.error/401.$content_type_extension;
            error_page 403 /.error/403.$content_type_extension;
            error_page 404 /.error/404.$content_type_extension;
            location /.error {
                internal;
            }

            try_files $uri $uri/ =404;
        }
}''' % configuration.www_directory_path  # noqa: E101 W191
            with open(join(configuration.output_directory_path, 'nginx', 'nginx.conf')) as f:  # noqa: E101
                self.assertEquals(expected, f.read())
Exemplo n.º 5
0
 async def setUpClass(cls) -> None:
     TestCase.setUpClass()
     # @todo Convert each test method to use self._load(), so we can remove this shared XML file.
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         async with App(configuration) as app:
             cls.ancestry = app.ancestry
             xml_file_path = Path(__file__).parent / 'assets' / 'data.xml'
             with open(xml_file_path) as f:
                 load_xml(app.ancestry, f.read(), rootname(xml_file_path))
Exemplo n.º 6
0
 def test_generate_multilingual(self):
     configuration = Configuration('/tmp', 'https://example.com')
     configuration.locales.replace([
         LocaleConfiguration('nl'),
         LocaleConfiguration('en'),
     ])
     sut = LocalizedPathUrlGenerator(configuration)
     self.assertEquals('/nl/index.html',
                       sut.generate('/index.html', 'text/html'))
     self.assertEquals(
         '/en/index.html', sut.generate('/index.html', 'text/html', locale='en'))
Exemplo n.º 7
0
 async def test_load(self):
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path, 'https://example.com')
         configuration.extensions.add(ExtensionConfiguration(Demo))
         async with App(configuration) as app:
             await load(app)
         self.assertNotEqual(0, len(app.ancestry.entities[Person]))
         self.assertNotEqual(0, len(app.ancestry.entities[Place]))
         self.assertNotEqual(0, len(app.ancestry.entities[Event]))
         self.assertNotEqual(0, len(app.ancestry.entities[Source]))
         self.assertNotEqual(0, len(app.ancestry.entities[Citation]))
Exemplo n.º 8
0
async def test_generate_window_close_button_should_close_window(assert_not_window, navigate, qtbot, tmpdir) -> None:
    configuration = Configuration(tmpdir, 'https://example.com')
    async with App(configuration) as app:
        sut = _GenerateWindow(app)
        qtbot.addWidget(sut)

        with qtbot.waitSignal(sut._thread.finished):
            sut.show()

        qtbot.mouseClick(sut._close_button, QtCore.Qt.LeftButton)
        assert_not_window(_GenerateWindow)
Exemplo n.º 9
0
 async def test_citation(self):
     configuration = Configuration(self._output_directory.name,
                                   'https://ancestry.example.com')
     app = App(configuration)
     citation = Citation('CITATION1', Source('A Little Birdie'))
     app.ancestry.entities.append(citation)
     async with app:
         await generate(app)
     self.assert_betty_html(app, '/citation/%s/index.html' % citation.id)
     self.assert_betty_json(app, '/citation/%s/index.json' % citation.id,
                            'citation')
Exemplo n.º 10
0
    def test_person_with_individual_and_affiliation_names(
            self, expected: str, locale: str):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.locales['en-US'] = LocaleConfiguration('en-US', 'en')
            configuration.locales['nl-NL'] = LocaleConfiguration('nl-NL', 'nl')
            site = Site(configuration)
            environment = create_environment(site, locale)
            person_id = 'P1'
            individual_name = 'Jane'
            affiliation_name = 'Doughnut'
            person = Person(person_id)
            person.names.append(PersonName(individual_name, affiliation_name))
            site.ancestry.people[person_id] = person

            indexed = list(index(site, environment))

            self.assertEquals('jane doughnut', indexed[0]['text'])
            self.assertIn(expected, indexed[0]['result'])
Exemplo n.º 11
0
 async def setUpClass(cls) -> None:
     TestCase.setUpClass()
     # @todo Convert each test method to use self._parse(), so we can remove this shared XML file.
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         async with Site(configuration) as site:
             cls.ancestry = site.ancestry
             parse_xml(
                 site, join(dirname(abspath(__file__)), 'assets',
                            'data.xml'))
Exemplo n.º 12
0
 async def test_source(self):
     configuration = Configuration(self._output_directory.name,
                                   'https://ancestry.example.com')
     app = App(configuration)
     source = Source('SOURCE1', 'A Little Birdie')
     app.ancestry.entities.append(source)
     async with app:
         await generate(app)
     self.assert_betty_html(app, '/source/%s/index.html' % source.id)
     self.assert_betty_json(app, '/source/%s/index.json' % source.id,
                            'source')
Exemplo n.º 13
0
 async def test_person(self):
     configuration = Configuration(self._output_directory.name,
                                   'https://ancestry.example.com')
     app = App(configuration)
     async with app:
         person = Person('PERSON1')
         app.ancestry.entities.append(person)
         await generate(app)
     self.assert_betty_html(app, '/person/%s/index.html' % person.id)
     self.assert_betty_json(app, '/person/%s/index.json' % person.id,
                            'person')
Exemplo n.º 14
0
 def test(self, expected, template, file):
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         environment = create_environment(Site(configuration))
         actual = environment.from_string(template).render(file=file)
         self.assertEquals(expected, actual)
         for file_path in actual.split(':'):
             self.assertTrue(
                 exists(
                     join(configuration.www_directory_path, file_path[1:])))
Exemplo n.º 15
0
 async def _render(
     self,
     data: Optional[Dict] = None,
     template_file: Optional[Template] = None,
     template_string: Optional[str] = None,
     update_configuration: Optional[Callable[[Configuration], None]] = None
 ) -> Tuple[str, App]:
     if template_string is not None and template_file is not None:
         raise RuntimeError(
             'You must define either `template_string` or `template_file`, but not both.'
         )
     if template_string is not None:
         template = template_string
         template_factory = Environment.from_string
     elif template_file is not None:
         template = template_file
         template_factory = Environment.get_template
     elif self.template_string is not None:
         template = self.template_string
         template_factory = Environment.from_string
     elif self.template_file is not None:
         template = self.template_file
         template_factory = Environment.get_template
     else:
         class_name = self.__class__.__name__
         raise RuntimeError(
             f'You must define one of `template_string`, `template_file`, `{class_name}.template_string`, or `{class_name}.template_file`.'
         )
     if data is None:
         data = {}
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path,
                                       'https://example.com')
         configuration.debug = True
         if update_configuration is not None:
             update_configuration(configuration)
         async with App(configuration) as app:
             rendered = template_factory(app.jinja2_environment,
                                         template).render(**data)
             await app.wait()
             yield rendered, app
Exemplo n.º 16
0
async def test_generate_window_serve_button_should_open_serve_window(assert_window, mocker, navigate, qtbot, tmpdir) -> None:
    mocker.patch('webbrowser.open_new_tab')
    configuration = Configuration(tmpdir, 'https://example.com')
    async with App(configuration) as app:
        sut = _GenerateWindow(app)
        qtbot.addWidget(sut)

        with qtbot.waitSignal(sut._thread.finished):
            sut.show()

        qtbot.mouseClick(sut._serve_button, QtCore.Qt.LeftButton)
        assert_window(_ServeAppWindow)
Exemplo n.º 17
0
 async def test_file(self):
     configuration = Configuration(self._output_directory.name,
                                   'https://ancestry.example.com')
     app = App(configuration)
     async with app:
         with NamedTemporaryFile() as f:
             file = File('FILE1', Path(f.name))
             app.ancestry.entities.append(file)
             await generate(app)
         self.assert_betty_html(app, '/file/%s/index.html' % file.id)
         self.assert_betty_json(app, '/file/%s/index.json' % file.id,
                                'file')
Exemplo n.º 18
0
 async def test_root_redirect(self):
     configuration = Configuration(self._output_directory.name,
                                   'https://ancestry.example.com')
     configuration.locales.replace([
         LocaleConfiguration('nl'),
         LocaleConfiguration('en'),
     ])
     async with App(configuration) as app:
         await generate(app)
     with open(self.assert_betty_html(app, '/index.html')) as f:
         meta_redirect = '<meta http-equiv="refresh" content="0; url=/nl/index.html">'
         self.assertIn(meta_redirect, f.read())
Exemplo n.º 19
0
 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))
Exemplo n.º 20
0
    async def test_empty(self):
        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:
                indexed = [item for item in Index(app).build()]

        self.assertEquals([], indexed)
Exemplo n.º 21
0
 async def test_extensions_with_comes_after_without_other_extension(
         self) -> None:
     configuration = Configuration(**self._MINIMAL_CONFIGURATION_ARGS)
     configuration.extensions.add(
         ExtensionConfiguration(
             ComesAfterNonConfigurableExtensionExtension))
     async with App(configuration) as sut:
         carrier = []
         await sut.dispatcher.dispatch(Tracker, 'track')(carrier)
         self.assertEquals(1, len(carrier))
         self.assertEquals(ComesAfterNonConfigurableExtensionExtension,
                           type(carrier[0]))
Exemplo n.º 22
0
    def test_post_render_config_with_https(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(
                output_directory_path, 'https://example.com')
            configuration.plugins[Nginx] = {}
            site = Site(configuration)
            render(site)
            expected = '''    server {
        listen 80;
        server_name example.com;
        return 301 https://$host$request_uri;
    }
server {
	listen 443 ssl http2;
	server_name example.com;
	root %s;
        add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
	add_header Cache-Control "max-age=86400";
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_types text/css application/javascript application/json application/xml;

        set $content_type_extension html;
    index index.$content_type_extension;

        location / {
            # Handle HTTP error responses.
            error_page 401 /.error/401.$content_type_extension;
            error_page 403 /.error/403.$content_type_extension;
            error_page 404 /.error/404.$content_type_extension;
            location /.error {
                internal;
            }

            try_files $uri $uri/ =404;
        }
}''' % configuration.www_directory_path  # noqa: E101 W191
            with open(join(configuration.output_directory_path, 'nginx', 'nginx.conf')) as f:  # noqa: E101
                self.assertEquals(expected, f.read())
Exemplo n.º 23
0
    async def test_post_render_config_with_content_negotiation(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'http://example.com')
            configuration.content_negotiation = True
            configuration.plugins[Nginx] = {}
            expected = r'''
server {
    listen 80;
    server_name example.com;
    root %s;
    add_header Cache-Control "max-age=86400";
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_types text/css application/javascript application/json application/xml;

    set_by_lua_block $media_type_extension {
        local available_media_types = {'text/html', 'application/json'}
        local media_type_extensions = {}
        media_type_extensions['text/html'] = 'html'
        media_type_extensions['application/json'] = 'json'
        local media_type = require('cone').negotiate(ngx.req.get_headers()['Accept'], available_media_types)
        return media_type_extensions[media_type]
    }
    index index.$media_type_extension;

    location / {
        # Handle HTTP error responses.
        error_page 401 /.error/401.$media_type_extension;
        error_page 403 /.error/403.$media_type_extension;
        error_page 404 /.error/404.$media_type_extension;
        location /.error {
            internal;
        }

        try_files $uri $uri/ =404;
    }
}''' % configuration.www_directory_path
            await self._assert_configuration_equals(expected, configuration)
Exemplo n.º 24
0
    async def test_post_render_config_with_overridden_www_directory_path(self):
        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.extensions[Nginx] = Nginx.configuration_schema(
                {'www_directory_path': '/tmp/overridden-www'})
            expected = r'''
server {
    listen 80;
    server_name example.com;
    return 301 https://$host$request_uri;
}
server {
    listen 443 ssl http2;
    server_name example.com;
    root /tmp/overridden-www;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
    add_header Cache-Control "max-age=86400";
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_types text/css application/javascript application/json application/xml;

    set $media_type_extension html;
    index index.$media_type_extension;

    location / {
        # Handle HTTP error responses.
        error_page 401 /.error/401.$media_type_extension;
        error_page 403 /.error/403.$media_type_extension;
        error_page 404 /.error/404.$media_type_extension;
        location /.error {
            internal;
    }

    try_files $uri $uri/ =404;
    }
}
'''
            await self._assert_configuration_equals(expected, configuration)
Exemplo n.º 25
0
    def test_post_render_config_without_clean_urls(self):
        self.maxDiff = None

        with TemporaryDirectory() as output_directory_path:
            configuration = Configuration(output_directory_path,
                                          'https://example.com')
            configuration.plugins[Nginx] = {}
            site = Site(configuration)
            render(site)
            expected = '''server {
	# The port to listen to.
	listen 80;
	# The publicly visible hostname.
	server_name example.com;
	# The path to the local web root.
	root %s;
	# The cache lifetime.
	add_header Cache-Control "max-age=86400";

	# Handle HTTP error responses.
	error_page 401 /.error/401.html;
	error_page 403 /.error/403.html;
	error_page 404 /.error/404.html;
	location /.error {
		internal;
	}

	# When directories are requested, serve their index.html contents.
	location / {
		if ($request_method = OPTIONS) {
			add_header Allow "OPTIONS, GET";
			return 200;
		}
		index index.html;
		try_files $uri $uri/ =404;
	}
}''' % configuration.www_directory_path  # noqa: E101 W191
            with open(join(configuration.output_directory_path,
                           'nginx.conf')) as f:  # noqa: E101
                self.assertEquals(expected, f.read())
Exemplo n.º 26
0
 async def test_validate(self):
     configuration = Configuration(self._output_directory.name,
                                   'https://ancestry.example.com')
     async with App(configuration) as app:
         await generate(app)
     with open(
             Path(__file__).parent / 'test_generate_assets' /
             'sitemap.xsd') as f:
         schema_doc = etree.parse(f)
     schema = etree.XMLSchema(schema_doc)
     with open(app.configuration.www_directory_path / 'sitemap.xml') as f:
         sitemap_doc = etree.parse(f)
     schema.validate(sitemap_doc)
Exemplo n.º 27
0
 async def test_extensions_with_one_configurable_extension(self) -> None:
     configuration = Configuration(**self._MINIMAL_CONFIGURATION_ARGS)
     check = 1337
     configuration.extensions.add(
         ExtensionConfiguration(
             ConfigurableExtension, True,
             ConfigurableExtensionConfiguration(check=check, )))
     async with App(configuration) as sut:
         self.assertIsInstance(sut.extensions[ConfigurableExtension],
                               ConfigurableExtension)
         self.assertEquals(
             check,
             sut.extensions[ConfigurableExtension]._configuration.check)
Exemplo n.º 28
0
 async def test_render_file_should_ignore_non_sass_or_scss(self) -> None:
     with TemporaryDirectory() as output_directory_path:
         configuration = Configuration(output_directory_path, 'https://ancestry.example.com')
         async with Site(configuration) as site:
             sut = Jinja2Renderer(site.jinja2_environment, configuration)
             template = '{% if true %}true{% endif %}'
             with TemporaryDirectory() as working_directory_path:
                 template_file_path = path.join(working_directory_path, 'betty.txt')
                 with open(template_file_path, 'w') as f:
                     f.write(template)
                 await sut.render_file(template_file_path)
                 with open(path.join(working_directory_path, 'betty.txt')) as f:
                     self.assertEquals(template, f.read())
Exemplo n.º 29
0
 def new_project(self) -> None:
     configuration_file_path, _ = QFileDialog.getSaveFileName(
         self, 'Save your new project to...', '',
         _CONFIGURATION_FILE_FILTER)
     if not configuration_file_path:
         return
     configuration = Configuration(
         path.join(path.dirname(configuration_file_path), 'output'),
         'https://example.com')
     with open(configuration_file_path, 'w') as f:
         to_file(f, configuration)
     project_window = ProjectWindow(configuration_file_path)
     project_window.show()
     self.close()
Exemplo n.º 30
0
 async def start(self) -> None:
     self._output_directory = TemporaryDirectory()
     configuration = Configuration(self._output_directory.name,
                                   'https://example.com')
     configuration.extensions[Demo] = None
     # The Nginx extension allows content negotiation if Docker is also available.
     configuration.extensions[Nginx] = {}
     # Include all of the translations Betty ships with.
     locale_configurations = [
         LocaleConfiguration('en-US', 'en'),
         LocaleConfiguration('nl-NL', 'nl'),
         LocaleConfiguration('fr-FR', 'fr'),
         LocaleConfiguration('uk', 'uk'),
     ]
     for locale_configuration in locale_configurations:
         configuration.locales[
             locale_configuration.locale] = locale_configuration
     self._app = App(configuration)
     self._server = None
     await self._app.enter()
     await load.load(self._app)
     await generate.generate(self._app)
     self._server = serve.AppServer(self._app)
     await self._server.start()