def test_delete_mark_obsolete(project0_disk, store0): """Tests that the in-DB Store and Directory are marked as obsolete after the on-disk file ceased to exist. Refs. #269. """ tp = TranslationProjectFactory( project=project0_disk, language=LanguageDBFactory() ) store = StoreDBFactory(translation_project=tp, parent=tp.directory) store.update(store.deserialize(store0.serialize())) store.sync() pootle_path = store.pootle_path # Remove on-disk file os.remove(store.file.path) # Update stores by rescanning TP tp.scan_files() # Now files that ceased to exist should be marked as obsolete updated_store = Store.objects.get(pootle_path=pootle_path) assert updated_store.obsolete # The units they contained are obsolete too assert not updated_store.units.exists() assert updated_store.unit_set.filter(state=OBSOLETE).exists()
def test_delete_mark_obsolete(project0_nongnu, project0, store0): """Tests that the in-DB Store and Directory are marked as obsolete after the on-disk file ceased to exist. Refs. #269. """ tp = TranslationProjectFactory( project=project0, language=LanguageDBFactory()) store = StoreDBFactory( translation_project=tp, parent=tp.directory) store.update(store.deserialize(store0.serialize())) store.sync() pootle_path = store.pootle_path # Remove on-disk file os.remove(store.file.path) # Update stores by rescanning TP tp.scan_files() # Now files that ceased to exist should be marked as obsolete updated_store = Store.objects.get(pootle_path=pootle_path) assert updated_store.obsolete # The units they contained are obsolete too assert not updated_store.units.exists() assert updated_store.unit_set.filter(state=OBSOLETE).exists()
def test_tp_tool_bad(po_directory, tp0, templates, english, no_templates_tps): other_project = ProjectDBFactory(source_language=english) other_tp = TranslationProjectFactory( project=other_project, language=LanguageDBFactory()) tp_tool = TPTool(tp0.project) with pytest.raises(ValueError): tp_tool.check_tp(other_tp) with pytest.raises(ValueError): tp_tool.set_parents(tp0.directory, other_tp.directory) with pytest.raises(ValueError): tp_tool.set_parents(other_tp.directory, tp0.directory) with pytest.raises(ValueError): tp_tool.move(other_tp, templates) with pytest.raises(ValueError): tp_tool.clone(other_tp, templates) with pytest.raises(ValueError): # cant set tp to a language if a tp already exists tp_tool.move( tp0, Language.objects.get(code="language1")) with pytest.raises(ValueError): # cant clone tp to a language if a tp already exists tp_tool.clone( tp0, Language.objects.get(code="language1"))
def test_tp_empty_stats(): """Tests if empty stats is initialized when translation project (new language) is added for a project with existing but empty template translation project. """ # Create an empty template translation project for project0. project = Project.objects.get(code="project0") english = Language.objects.get(code="en") TranslationProjectFactory(project=project, language=english) # Create a new language to test. language = LanguageDBFactory() tp = TranslationProject.objects.create(language=language, project=project) tp.init_from_templates() # There are no files on disk so TP was not automagically filled. assert list(tp.stores.all()) == [] # Check if zero stats is calculated and available. stats = tp.get_stats() assert stats['total'] == 0 assert stats['translated'] == 0 assert stats['fuzzy'] == 0 assert stats['suggestions'] == 0 assert stats['critical'] == 0
def test_admin_view_project_add_tp(project_foo, english, client, admin): assert project_foo.treestyle != 'pootle_fs' user = admin new_language = LanguageDBFactory() TranslationProjectFactory(language=english, project=project_foo) client.login(username=user.username, password=TEST_USERS["admin"]["password"]) get_response = _admin_view_get(client, project_foo) post_data = {} formset = get_response.context["formset"] forms = formset.forms + formset.extra_forms + [formset.management_form] for form in forms: for field in form.fields: post_data["%s-%s" % (form.prefix, field)] = (form.fields[field].initial or form.initial.get(field, "")) post_data["%s-language" % formset.extra_forms[0].prefix] = new_language.id post_data["%s-project" % formset.extra_forms[0].prefix] = project_foo.id response = _admin_view_post(client, project_foo, **post_data) new_tp = TranslationProject.objects.get(language=new_language, project=project_foo) assert new_tp in response.context["objects"].object_list _test_admin_view(response, project_foo)
def setup_disabled_project(self): from pytest_pootle.factories import (DirectoryFactory, ProjectDBFactory, TranslationProjectFactory) from pootle.core.contextmanagers import keep_data from pootle_format.models import Format from pootle_language.models import Language with keep_data(): source_language = Language.objects.get(code="en") project = ProjectDBFactory(code="disabled_project0", fullname="Disabled Project 0", source_language=source_language) project.filetypes.add(Format.objects.get(name="po")) project.disabled = True project.save() language = Language.objects.get(code="language0") tp = TranslationProjectFactory(project=project, language=language) tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_stores(tp, n=(1, 1)) subdir0 = DirectoryFactory(name="subdir0", parent=tp.directory, tp=tp) self._add_stores(tp, n=(1, 1), parent=subdir0)
def test_store_get_template_file_class(po_directory, templates): project = ProjectDBFactory(source_language=templates) tp = TranslationProjectFactory(language=templates, project=project) format_registry = formats.get() foo_filetype = format_registry.register("foo", "foo", template_extension="bar") tp.project.filetypes.add(foo_filetype) store = Store.objects.create(name="mystore.bar", translation_project=tp, parent=tp.directory) # oh no! not recognised by ttk with pytest.raises(ValueError): store.syncer.file_class class CustomFormatClass(object): pass @provider(format_classes) def format_class_provider(**kwargs): return dict(foo=CustomFormatClass) assert store.syncer.file_class == CustomFormatClass format_classes.disconnect(format_class_provider)
def setup_templates(self): from pootle.core.contextmanagers import keep_data from pootle.core.signals import update_data from pootle_project.models import Project from pootle_translationproject.contextmanagers import update_tp_after from pytest_pootle.factories import (LanguageDBFactory, TranslationProjectFactory) tps = [] with keep_data(): templates = LanguageDBFactory(code="templates") for project in Project.objects.all(): # add a TP to the project for each language tp = TranslationProjectFactory(project=project, language=templates) # As there are no files on the FS we have to currently unobsolete # the directory tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_template_stores(tp) tps.append(tp) for tp in tps: with update_tp_after(tp): for store in tp.stores.all(): update_data.send(store.__class__, instance=store)
def test_data_tp(english): """Test that you cant add a duplicate file extension """ tp = TranslationProjectFactory( project=ProjectDBFactory(source_language=english), language=LanguageDBFactory()) assert (repr(tp.data) == '<TPData: %s>' % tp.pootle_path)
def test_add_store_fs_by_path(english): """Add a store_fs for pootle_path """ project = ProjectDBFactory(source_language=english) language = LanguageDBFactory() tp = TranslationProjectFactory(project=project, language=language) store = StoreDBFactory( translation_project=tp, parent=tp.directory, name="example_store.po") conf = config.get(tp.project.__class__, instance=tp.project) conf.set_config("pootle_fs.fs_type", "localfs") conf.set_config("pootle_fs.fs_url", "foo") fs_path = "/some/fs/example_store.po" pootle_path = store.pootle_path store_fs = StoreFS.objects.create( pootle_path=pootle_path, path=fs_path) assert store_fs.project == project assert store_fs.store == store assert store_fs.pootle_path == pootle_path assert store_fs.path == fs_path assert store_fs.last_sync_hash is None assert store_fs.last_sync_mtime is None assert store_fs.last_sync_revision is None
def test_data_tp_checks(english): """Test that you cant add a duplicate file extension """ tp = TranslationProjectFactory( project=ProjectDBFactory(source_language=english), language=LanguageDBFactory()) check_data = TPChecksData.objects.create(tp=tp) assert (repr(check_data) == '<TPChecksData: %s>' % tp.pootle_path)
def test_store_get_or_create_templates(po_directory, templates): project = ProjectDBFactory(source_language=templates) tp = TranslationProjectFactory(language=templates, project=project) po = Format.objects.get(name="po") store = Store.objects.get_or_create(name="mystore.pot", translation_project=tp, parent=tp.directory)[0] assert store.filetype == po assert store.is_template
def numbered_po(test_fs, project0): """Create a store with numbered units.""" tp = TranslationProjectFactory(project=project0, language=LanguageDBFactory()) store = StoreDBFactory(name="numbered.po", translation_project=tp, parent=tp.directory) with test_fs.open("data/po/1234.po") as src: store.update(store.deserialize(src.read())) return store
def setup_terminology(self): from pytest_pootle.factories import (ProjectDBFactory, TranslationProjectFactory) from pootle_language.models import Language source_language = Language.objects.get(code="en") terminology = ProjectDBFactory(code="terminology", checkstyle="terminology", fullname="Terminology", source_language=source_language) for language in Language.objects.all(): TranslationProjectFactory(project=terminology, language=language)
def test_format_set_tp_from_store_filetype(po_directory, templates, language0, po, po2): project = ProjectDBFactory(source_language=templates) filetypes = project.filetype_tool registry = formats.get() templates_tp = TranslationProjectFactory(language=templates, project=project) lang_tp = TranslationProjectFactory(language=language0, project=project) template = Store.objects.create(name="mystore.pot", translation_project=templates_tp, parent=templates_tp.directory) store = Store.objects.create(name="mystore.po", translation_project=lang_tp, parent=lang_tp.directory) po3 = registry.register("special_po_3", "po3", template_extension="pot3") filetypes.add_filetype(po2) filetypes.add_filetype(po3) # this does nothing as the stores are currently po filetypes.set_tp_filetype(lang_tp, po3, from_filetype=po2) store = Store.objects.get(pk=store.pk) assert store.filetype == po assert store.name.endswith(".po") filetypes.set_tp_filetype(templates_tp, po3, from_filetype=po2) template = Store.objects.get(pk=template.pk) assert template.filetype == po assert template.name.endswith(".pot") # it works if we switch to po2 first filetypes.set_tp_filetype(lang_tp, po2, from_filetype=po) filetypes.set_tp_filetype(templates_tp, po2, from_filetype=po) filetypes.set_tp_filetype(lang_tp, po3, from_filetype=po2) store = Store.objects.get(pk=store.pk) assert store.filetype == po3 assert store.name.endswith(".po3") filetypes.set_tp_filetype(templates_tp, po3, from_filetype=po2) template = Store.objects.get(pk=template.pk) assert template.filetype == po3 assert template.name.endswith(".pot3")
def test_format_set_native_store_filetype(po_directory, templates, language0, po2, english): project = ProjectDBFactory(source_language=english) filetypes = project.filetype_tool registry = formats.get() templates_tp = TranslationProjectFactory(language=templates, project=project) lang_tp = TranslationProjectFactory(language=language0, project=project) template = Store.objects.create(name="mystore.pot3.pot", translation_project=templates_tp, parent=templates_tp.directory) store = Store.objects.create(name="mystore.po3.po", translation_project=lang_tp, parent=lang_tp.directory) # register po2 - not native template extension filetypes.add_filetype(po2) filetypes.set_store_filetype(store, po2) assert store.name.endswith(".po3.po2") assert store.filetype == po2 filetypes.set_store_filetype(template, po2) assert template.name.endswith(".pot3.pot2") assert template.filetype == po2 # register po3 - native template extension po3 = registry.register("special_po_3", "po3", template_extension="pot3") filetypes.add_filetype(po3) # in this case extension is just removed filetypes.set_store_filetype(store, po3) assert not store.name.endswith(".po3.po3") assert store.name.endswith(".po3") assert store.filetype == po3 filetypes.set_store_filetype(template, po3) assert not template.name.endswith(".pot3.pot3") assert template.name.endswith(".pot3") assert template.filetype == po3
def test_data_tp(english): """Test that you cant add a duplicate file extension """ from pytest_pootle.factories import ( LanguageDBFactory, ProjectDBFactory, TranslationProjectFactory) tp = TranslationProjectFactory( project=ProjectDBFactory(source_language=english), language=LanguageDBFactory()) data = TPData.objects.create(tp=tp) assert ( repr(data) == '<TPData: %s>' % tp.pootle_path)
def templates_project0(request, templates): """Require the templates/project0/ translation project.""" from pootle_project.models import Project from pytest_pootle.factories import TranslationProjectFactory project0 = Project.objects.get(code="project0") tp = TranslationProjectFactory(language=templates, project=project0) def _cleanup(): shutil.rmtree(tp.abs_real_path) request.addfinalizer(_cleanup) return tp
def setup_tps(self): from pootle_project.models import Project from pootle_language.models import Language from pytest_pootle.factories import TranslationProjectFactory for project in Project.objects.all(): for language in Language.objects.exclude(code="en"): # add a TP to the project for each language tp = TranslationProjectFactory(project=project, language=language) # As there are no files on the FS we have to currently unobsolete # the directory tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_stores(tp)
def test_sync(project0_nongnu, project0, store0): """Tests that the new on-disk file is created after sync for existing in-DB Store if the corresponding on-disk file ceased to exist. """ tp = TranslationProjectFactory(project=project0, language=LanguageDBFactory()) store = StoreDBFactory(translation_project=tp, parent=tp.directory) store.update(store.deserialize(store0.serialize())) assert not store.file.exists() store.sync() assert store.file.exists() os.remove(store.file.path) assert not store.file.exists() store.sync() assert store.file.exists()
def test_tp_create_with_none_treestyle(po_directory, english, templates, settings): project = ProjectDBFactory(source_language=english, treestyle='pootle_fs') language = LanguageDBFactory() TranslationProjectFactory(language=templates, project=project) tp = TranslationProject.objects.create(project=project, language=language) assert not tp.abs_real_path assert not os.path.exists( os.path.join(settings.POOTLE_TRANSLATION_DIRECTORY, project.code)) tp.save() assert not tp.abs_real_path assert not os.path.exists( os.path.join(settings.POOTLE_TRANSLATION_DIRECTORY, project.code))
def setup_templates(self): from pootle_project.models import Project from pytest_pootle.factories import (LanguageDBFactory, TranslationProjectFactory) templates = LanguageDBFactory(code="templates") for project in Project.objects.all(): # add a TP to the project for each language tp = TranslationProjectFactory(project=project, language=templates) # As there are no files on the FS we have to currently unobsolete # the directory tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_template_stores(tp)
def moz_env(post_db_setup, _django_cursor_wrapper, ios_pootle_file): from django.conf import settings from pytest_pootle.factories import (ProjectDBFactory, StoreDBFactory, TranslationProjectFactory) from pootle_fs.models import ProjectFS from pootle_language.models import Language with _django_cursor_wrapper: ios_project = ProjectDBFactory( source_language=Language.objects.get(code="en"), code="ios", localfiletype="xliff") ios_tp = TranslationProjectFactory( project=ios_project, language=Language.objects.get(code="language0")) ios_store = StoreDBFactory(parent=ios_tp.directory, translation_project=ios_tp, name="firefox-ios.xliff") ios_bytes = io.BytesIO(ios_pootle_file.encode("utf8")) ios_store.update(getclass(ios_bytes)(ios_bytes.read())) fs_dir = tempfile.mkdtemp() settings.POOTLE_FS_PATH = fs_dir repo_path = os.path.join(fs_dir, "__moz_ios_src__") Repo.init(repo_path, bare=True) with tmp_git(repo_path) as (tmp_repo_path, tmp_repo): config_file = os.path.join(tmp_repo_path, ".pootle.ini") with open(config_file, "w") as ini: config = ("[default]\n" "serializers = ios\n" "deserializers = ios\n" "translation_path = <lang>/<filename>.xliff") ini.write(config) tmp_repo.index.add([".pootle.ini"]) tmp_repo.index.commit("Add Pootle configuration") tmp_repo.remotes.origin.push("master:master") ios_fs = ProjectFS.objects.create(project=ios_project, fs_type="git", url=repo_path) ios_plugin = ios_fs.plugin ios_plugin.add_translations()
def test_add_store_bad_path(po_directory, english): """Try to create a store_fs where pootle_path and store.pootle_path dont match. """ fs_path = "/some/fs/example.po" project = ProjectDBFactory(source_language=english) language = LanguageDBFactory() tp = TranslationProjectFactory(project=project, language=language) tp.project.config["pootle_fs.fs_type"] = "localfs" tp.project.config["pootle_fs.fs_url"] = "/foo" store = StoreDBFactory(translation_project=tp, parent=tp.directory, name="example_store.po") with pytest.raises(ValidationError): StoreFS.objects.create(store=store, pootle_path="/some/other/path.po", path=fs_path)
def setup_terminology(self): from pytest_pootle.factories import ( ProjectDBFactory, StoreDBFactory, TranslationProjectFactory, UnitDBFactory ) from pootle_language.models import Language source_language = Language.objects.get(code="en") terminology = ProjectDBFactory(code="terminology", checkstyle="terminology", fullname="Terminology", source_language=source_language) for language in Language.objects.exclude(code='en'): tp = TranslationProjectFactory(project=terminology, language=language) store = StoreDBFactory(translation_project=tp, name='terminology.po') store.save() for i_ in range(0, 1): UnitDBFactory(store=store)
def test_format_set_tp_filetype(po_directory, english, language0, po2): project = ProjectDBFactory(source_language=english) filetypes = project.filetype_tool registry = formats.get() lang_tp = TranslationProjectFactory(language=language0, project=project) store = Store.objects.create(name="mystore.po", translation_project=lang_tp, parent=lang_tp.directory) filetypes.add_filetype(po2) filetypes.set_tp_filetype(lang_tp, po2) store = Store.objects.get(pk=store.pk) assert store.filetype == po2 assert store.name.endswith(".po2") po3 = registry.register("special_po_3", "po3", template_extension="pot") filetypes.add_filetype(po3) filetypes.set_tp_filetype(lang_tp, po3) store = Store.objects.get(pk=store.pk) assert store.filetype == po3 assert store.name.endswith(".po3")
def setup_tps(self): from pootle.core.contextmanagers import keep_data from pootle_project.models import Project from pootle_language.models import Language from pytest_pootle.factories import TranslationProjectFactory with keep_data(): for project in Project.objects.select_related( "source_language").all(): for language in Language.objects.exclude(code="en"): # add a TP to the project for each language tp = TranslationProjectFactory(project=project, language=language) # As there are no files on the FS we have to currently # unobsolete the directory tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_stores(tp)
def setup_disabled_project(self): from pytest_pootle.factories import (DirectoryFactory, ProjectFactory, TranslationProjectFactory) from pootle_language.models import Language source_language = Language.objects.get(code="en") project = ProjectFactory(code="disabled_project0", fullname="Disabled Project 0", source_language=source_language) project.disabled = True project.save() language = Language.objects.get(code="language0") tp = TranslationProjectFactory(project=project, language=language) tp_dir = tp.directory tp_dir.obsolete = False tp_dir.save() self._add_stores(tp, n=(1, 1)) subdir0 = DirectoryFactory(name="subdir0", parent=tp.directory) self._add_stores(tp, n=(1, 1), parent=subdir0)
def test_add_store_bad_path(english): """Try to create a store_fs where pootle_path and store.pootle_path dont match. """ fs_path = "/some/fs/example.po" project = ProjectDBFactory(source_language=english) language = LanguageDBFactory() tp = TranslationProjectFactory(project=project, language=language) conf = config.get(project.__class__, instance=project) conf.set_config("pootle_fs.fs_type", "localfs") conf.set_config("pootle_fs.fs_url", "foo") store = StoreDBFactory( translation_project=tp, parent=tp.directory, name="example_store.po") with pytest.raises(ValidationError): StoreFS.objects.create( store=store, pootle_path="/some/other/path.po", path=fs_path)
def test_add_store_fs_by_store(po_directory, english): """Add a store_fs using store= rather than pootle_path """ fs_path = "/some/fs/example_store.po" project = ProjectDBFactory(source_language=english) language = LanguageDBFactory() tp = TranslationProjectFactory(project=project, language=language) store = StoreDBFactory(translation_project=tp, parent=tp.directory, name="example_store.po") tp.project.config["pootle_fs.fs_type"] = "localfs" tp.project.config["pootle_fs.fs_url"] = "/foo" store_fs = StoreFS.objects.create(store=store, path=fs_path) assert store_fs.project == project assert store_fs.store == store assert store_fs.pootle_path == store.pootle_path assert store_fs.path == fs_path assert store_fs.last_sync_hash is None assert store_fs.last_sync_mtime is None assert store_fs.last_sync_revision is None
def setup_terminology(self): import pytest_pootle from pytest_pootle.factories import (ProjectDBFactory, StoreDBFactory, TranslationProjectFactory) from pootle_language.models import Language source_language = Language.objects.get(code="en") terminology = ProjectDBFactory(code="terminology", checkstyle="terminology", fullname="Terminology", source_language=source_language) term_file = os.path.join(os.path.dirname(pytest_pootle.__file__), *("data", "po", "terminology.po")) with open(term_file) as f: term_ttk = getclass(f)(f.read()) for language in Language.objects.all(): tp = TranslationProjectFactory(project=terminology, language=language) if language.code not in ["language0", "language1"]: continue store = StoreDBFactory(parent=tp.directory, translation_project=tp, name="terminology.po") store.update(term_ttk)
def test_language_liveness(): language = LanguageDBFactory() # Test unused language is not live. assert language.translationproject_set.count() == 0 assert language not in Language.live.all() assert language not in Language.live.get_all_queryset() # Create obsolete TP. obsolete_tp = TranslationProjectFactory( language=language, project=ProjectDBFactory(source_language=language) ) obsolete_tp.directory.makeobsolete() # Test language used only in obsolete TP is not live. assert obsolete_tp.directory.obsolete assert language.translationproject_set.count() == 1 assert language not in Language.live.all() assert language not in Language.live.get_all_queryset() # Create TP for disabled project. disabled_project = ProjectDBFactory(source_language=language) disabled_project.disabled = True disabled_project.save() disabled_project_tp = TranslationProjectFactory(language=language, project=disabled_project) # Test language used only in disabled project and obsolete TP is not live. assert disabled_project.disabled assert language.translationproject_set.count() == 2 assert language not in Language.live.all() # But live for admins. assert language in Language.live.get_all_queryset() # Create regular TP. TranslationProjectFactory( language=language, project=ProjectDBFactory(source_language=language) ) # Test language used in regular and obsolete TPs and in TP on disabled # project is live. assert language.translationproject_set.count() == 3 assert language in Language.live.all() # But live for admins. assert language in Language.live.get_all_queryset() # Delete TP for disabled project. disabled_project_tp.delete() # Test language both in obsolete and regular TP is live. assert language.translationproject_set.count() == 2 assert language in Language.live.all() assert language in Language.live.get_all_queryset() # Create again TP for disabled project and delete obsolete TP. # Delete obsolete TP. disabled_project_tp = TranslationProjectFactory(language=language, project=disabled_project) obsolete_tp.delete() # Test language both in disabled project and regular TP is live. assert language.translationproject_set.count() == 2 assert language in Language.live.all() assert language in Language.live.get_all_queryset() # Delete TP for disabled project. disabled_project_tp.delete() # Test templates language is live. assert language.translationproject_set.count() == 1 assert language in Language.live.all() assert language in Language.live.get_all_queryset()