Пример #1
0
    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)
Пример #2
0
def ordered_po(test_fs, tp0):
    """Create a store with ordered units."""

    store = StoreDBFactory(
        name="ordered.po",
        translation_project=tp0,
        parent=tp0.directory)
    with test_fs.open("data/po/ordered.po") as src:
        store.update(store.deserialize(src.read()))
    return store
Пример #3
0
    def _add_template_stores(self, tp, n=(3, 2), parent=None):
        from pytest_pootle.factories import StoreDBFactory, UnitDBFactory

        for i_ in range(0, n[0]):
            # add 3 stores
            store = StoreDBFactory(translation_project=tp)
            store.filetype = tp.project.filetype_tool.choose_filetype(store.name)
            store.save()

            # add 8 units to each store
            for i_ in range(0, 4):
                UnitDBFactory(store=store, target="")
Пример #4
0
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()
Пример #5
0
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
Пример #6
0
    def _add_stores(self, tp, n=(3, 2), parent=None):
        from pytest_pootle.factories import StoreDBFactory, UnitDBFactory

        from pootle_store.constants import UNTRANSLATED, TRANSLATED, FUZZY, OBSOLETE

        for i_ in range(0, n[0]):
            # add 3 stores
            if parent is None:
                store = StoreDBFactory(translation_project=tp)
            else:
                store = StoreDBFactory(translation_project=tp, parent=parent)
            store.filetype = tp.project.filetype_tool.choose_filetype(store.name)
            store.save()

            # add 8 units to each store
            for state in [UNTRANSLATED, TRANSLATED, FUZZY, OBSOLETE]:
                for i_ in range(0, n[1]):
                    UnitDBFactory(store=store, state=state)
Пример #7
0
    def setup_complex_po(self):
        import pytest_pootle
        from pytest_pootle.factories import StoreDBFactory
        from pootle_translationproject.models import TranslationProject

        po_file = os.path.join(
            os.path.dirname(pytest_pootle.__file__),
            *("data", "po", "complex.po"))
        with open(po_file) as f:
            ttk = getclass(f)(f.read())

        tp = TranslationProject.objects.get(
            project__code="project0",
            language__code="language0")

        store = StoreDBFactory(
            parent=tp.directory,
            translation_project=tp,
            name="complex.po")
        store.update(ttk)
Пример #8
0
    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)
Пример #9
0
    def setup_complex_po(self):
        import pytest_pootle
        from pytest_pootle.factories import StoreDBFactory
        from pootle_translationproject.models import TranslationProject

        po_file = os.path.join(
            os.path.dirname(pytest_pootle.__file__),
            *("data", "po", "complex.po"))
        with open(po_file) as f:
            ttk = getclass(f)(f.read())

        tp = TranslationProject.objects.get(
            project__code="project0",
            language__code="language0")

        store = StoreDBFactory(
            parent=tp.directory,
            translation_project=tp,
            name="complex.po")
        store.update(ttk)
Пример #10
0
def store_po(tp0):
    """An empty Store in the /language0/project0 TP"""
    from pootle_translationproject.models import TranslationProject

    tp = TranslationProject.objects.get(project__code="project0",
                                        language__code="language0")

    store = StoreDBFactory(parent=tp.directory,
                           translation_project=tp,
                           name="test_store.po")
    return store
Пример #11
0
def store_diff_tests(request, tp0, member, member2):
    from pootle.core.contextmanagers import update_data_after
    from pootle_store.diff import StoreDiff

    store = StoreDBFactory(translation_project=tp0, parent=tp0.directory)

    with update_data_after(store):
        test = _setup_store_test(store, member, member2,
                                 UPDATE_STORE_TESTS[request.param])
    test_store = create_store(units=test[1])
    return [StoreDiff(test[0], test_store, test[2])] + list(test[:3])
Пример #12
0
def complex_po(test_fs):
    """A Store with some complex Units"""
    from pootle_translationproject.models import TranslationProject

    from pytest_pootle.factories import StoreDBFactory

    tp = TranslationProject.objects.get(
        project__code="project0",
        language__code="language0")

    store = StoreDBFactory(
        parent=tp.directory,
        translation_project=tp,
        name="complex_store.po")

    with test_fs.open(("data", "po", "complex.po")) as f:
        ttk = getclass(f)(f.read())

    store.update(ttk)
    return store
Пример #13
0
def test_sync(project0_disk, 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_disk, 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()
Пример #14
0
def param_update_store_test(request, tp0, member, member2):
    from pytest_pootle.factories import StoreDBFactory

    store = StoreDBFactory(translation_project=tp0, parent=tp0.directory)
    test = _setup_store_test(store, member, member2,
                             UPDATE_STORE_TESTS[request.param])
    update_store(test[0],
                 units=test[1],
                 store_revision=test[2],
                 user=member2,
                 resolve_conflict=test[3])
    return test
Пример #15
0
def store_diff_tests(request, tp0, member, member2):
    from pytest_pootle.factories import StoreDBFactory
    from pootle_store.diff import StoreDiff

    store = StoreDBFactory(
        translation_project=tp0,
        parent=tp0.directory)

    test = _setup_store_test(store, member, member2,
                             UPDATE_STORE_TESTS[request.param])
    test_store = create_store(units=test[1])
    return [StoreDiff(test[0], test_store, test[2])] + list(test[:3])
Пример #16
0
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()
Пример #17
0
def test_data_store(tp0):
    """Test that you cant add a duplicate file extension
    """
    from pytest_pootle.factories import StoreDBFactory

    store = StoreDBFactory(
        name="foo.po",
        parent=tp0.directory,
        translation_project=tp0)
    data = StoreData.objects.create(store=store)
    assert (
        repr(data)
        == '<StoreData: %s>' % store.pootle_path)
Пример #18
0
def param_update_store_test(request, tp0, member, member2):
    from pootle.core.contextmanagers import update_data_after

    store = StoreDBFactory(translation_project=tp0, parent=tp0.directory)
    with update_data_after(store):
        test = _setup_store_test(store, member, member2,
                                 UPDATE_STORE_TESTS[request.param])
        update_store(test[0],
                     units=test[1],
                     store_revision=test[2],
                     user=member2,
                     resolve_conflict=test[3])
    return test
Пример #19
0
def test_data_store_updater_defaults(tp0):
    store = StoreDBFactory(
        name="store_with_no_units.po",
        parent=tp0.directory,
        translation_project=tp0)
    fields = store.data_tool.updater.aggregate_fields
    aggregate_data = store.data_tool.updater.get_aggregate_data(
        fields=fields)
    for k in fields:
        if k in store.data_tool.updater.aggregate_defaults:
            assert (
                aggregate_data[k]
                == store.data_tool.updater.aggregate_defaults[k])
Пример #20
0
def test_mozlang_sync(tp0):
    mozlang = Format.objects.get(name="lang")
    tp0.project.filetypes.add(mozlang)

    foo_lang = StoreDBFactory(
        name="foo.lang",
        filetype=mozlang,
        parent=tp0.directory,
        translation_project=tp0)

    store0 = tp0.stores.get(name="store0.po")

    # deserialize as source
    foo_lang.update(store0.deserialize(store0.serialize()))

    # mark the unit as fuzzy
    unit = foo_lang.units.filter(state=TRANSLATED).first()
    unit.markfuzzy()
    unit.save()

    ttk = foo_lang.deserialize(foo_lang.serialize())
    ttk_unit = ttk.findid(unit.getid())
    assert not ttk_unit.istranslated()
Пример #21
0
    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)
Пример #22
0
def test_store_sync_empty(project0_nongnu, tp0, caplog):
    store = StoreDBFactory(
        name="empty.po",
        translation_project=tp0,
        parent=tp0.directory)
    store.sync()
    assert os.path.exists(store.file.path)
    modified = os.stat(store.file.path).st_mtime
    store.sync()
    assert modified == os.stat(store.file.path).st_mtime
    # warning message - nothing changes
    store.sync(conservative=True, only_newer=False)
    assert "nothing changed" in caplog.records[-1].message
    assert modified == os.stat(store.file.path).st_mtime
Пример #23
0
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()
Пример #24
0
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)
Пример #25
0
def test_import_to_empty(import_tps, site_users):
    from pytest_pootle.factories import StoreDBFactory

    tp = import_tps
    user = site_users["user"]
    store = StoreDBFactory(translation_project=tp, name="import_to_empty.po")
    filestore = create_store(store.pootle_path, "0",
                             [("Unit Source", "Unit Target")])
    import_file(
        SimpleUploadedFile(store.name, str(filestore),
                           "text/x-gettext-translation"), user)

    allow_add_and_obsolete = (
        (tp.project.checkstyle == 'terminology' or tp.is_template_project)
        and check_user_permission(user, 'administrate', tp.directory))
    if allow_add_and_obsolete:
        assert tp.stores.get(pootle_path=store.pootle_path).units.count() == 1
    else:
        assert tp.stores.get(pootle_path=store.pootle_path).units.count() == 0
Пример #26
0
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)
Пример #27
0
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
Пример #28
0
def param_update_store_test(request, tp0, member, member2):
    from pootle.core.contextmanagers import keep_data
    from pootle.core.signals import update_data

    store = StoreDBFactory(translation_project=tp0, parent=tp0.directory)

    with keep_data():
        test = _setup_store_test(store, member, member2,
                                 UPDATE_STORE_TESTS[request.param])
    update_data.send(store.__class__, instance=store)

    with keep_data():
        update_store(test[0],
                     units=test[1],
                     store_revision=test[2],
                     user=member2,
                     resolve_conflict=test[3])
    update_data.send(store.__class__, instance=store)

    return test
Пример #29
0
    def _add_stores(self, tp, n=(3, 2), parent=None):
        from pytest_pootle.factories import StoreDBFactory, UnitDBFactory

        from pootle_store.constants import UNTRANSLATED, TRANSLATED, FUZZY, OBSOLETE

        for i_ in range(0, n[0]):
            # add 3 stores
            if parent is None:
                store = StoreDBFactory(translation_project=tp)
            else:
                store = StoreDBFactory(translation_project=tp, parent=parent)
            store.filetype = tp.project.filetype_tool.choose_filetype(
                store.name)
            store.save()

            # add 8 units to each store
            for state in [UNTRANSLATED, TRANSLATED, FUZZY, OBSOLETE]:
                for i_ in range(0, n[1]):
                    UnitDBFactory(store=store, state=state)
Пример #30
0
def test_add_store_fs_by_path(po_directory, 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
Пример #31
0
def test_import_add_and_obsolete_units(import_tps, site_users):
    from pytest_pootle.factories import StoreDBFactory, UnitDBFactory

    tp = import_tps
    user = site_users["user"]
    store = StoreDBFactory(translation_project=tp)
    unit = UnitDBFactory(store=store, state=TRANSLATED)
    filestore = create_store(
        store.pootle_path, "0",
        [(unit.source_f + " REPLACED", unit.target_f + " REPLACED")])
    import_file(
        SimpleUploadedFile("import_add_and_obsolete.po", str(filestore),
                           "text/x-gettext-translation"), user)

    allow_add_and_obsolete = (
        (tp.project.checkstyle == 'terminology' or tp.is_template_project)
        and check_user_permission(user, 'administrate', tp.directory))
    if allow_add_and_obsolete:
        assert Unit.objects.filter(store=store, state=OBSOLETE).count() == 1
        assert store.units.filter(state=TRANSLATED).count() == 1
        assert Unit.objects.filter(store=store).count() == 2
    else:
        assert store.units.all().count() == 1
Пример #32
0
def test_mozlang_sync(tp0):
    mozlang = Format.objects.get(name="lang")
    tp0.project.filetypes.add(mozlang)

    foo_lang = StoreDBFactory(name="foo.lang",
                              filetype=mozlang,
                              parent=tp0.directory,
                              translation_project=tp0)

    store0 = tp0.stores.get(name="store0.po")

    # deserialize as source
    foo_lang.update(store0.deserialize(store0.serialize()))

    # mark the unit as fuzzy
    unit = foo_lang.units.filter(state=TRANSLATED).first()
    unit.markfuzzy()
    unit.save()

    ttk = foo_lang.deserialize(foo_lang.serialize())
    ttk_unit = ttk.findid(unit.getid())
    assert not ttk_unit.istranslated()
Пример #33
0
def test_mozlang_update(tp0):
    mozlang = Format.objects.get(name="lang")
    tp0.project.filetypes.add(mozlang)

    foo_lang = StoreDBFactory(
        name="foo.lang",
        filetype=mozlang,
        parent=tp0.directory,
        translation_project=tp0)

    store0 = tp0.stores.get(name="store0.po")

    # deserialize as source
    foo_lang.update(store0.deserialize(store0.serialize()))

    # get serialized lang store
    serialized = foo_lang.serialize()

    # mark a translated unit as fuzzy
    translated = foo_lang.units.filter(state=TRANSLATED).first()
    translated.state = FUZZY
    translated.save()

    # source is translated
    foo_lang.update(foo_lang.deserialize(serialized))
    # unit is set back to TRANSLATED
    translated = Unit.objects.get(pk=translated.pk)
    assert translated.state == TRANSLATED

    translated = foo_lang.units.filter(state=TRANSLATED).first()
    translated.state = FUZZY
    translated.save()

    # set target == "" > untranslated
    ttk = foo_lang.deserialize(serialized)
    ttkunit = ttk.findid(translated.getid())
    ttkunit.target = ""
    foo_lang.update(ttk)
    # unit stays FUZZY
    translated = Unit.objects.get(pk=translated.pk)
    assert translated.state == FUZZY
Пример #34
0
def test_mozlang_update(tp0):
    mozlang = Format.objects.get(name="lang")
    tp0.project.filetypes.add(mozlang)

    foo_lang = StoreDBFactory(name="foo.lang",
                              filetype=mozlang,
                              parent=tp0.directory,
                              translation_project=tp0)

    store0 = tp0.stores.get(name="store0.po")

    # deserialize as source
    foo_lang.update(store0.deserialize(store0.serialize()))

    # get serialized lang store
    serialized = foo_lang.serialize()

    # mark a translated unit as fuzzy
    translated = foo_lang.units.filter(state=TRANSLATED).first()
    translated.state = FUZZY
    translated.save()

    # source is translated
    old_ttk = foo_lang.deserialize(serialized)
    foo_lang.update(old_ttk)
    # unit is still fuzzy
    translated.refresh_from_db()
    assert translated.state == FUZZY

    # source target changes state also gets updated
    old_ttk.findid(translated.getid()).target = "something else {ok}"
    foo_lang.update(old_ttk, store_revision=translated.revision)
    translated.refresh_from_db()
    assert translated.state == TRANSLATED

    translated = foo_lang.units.filter(state=TRANSLATED).first()
    translated.state = FUZZY
    translated.save()

    # set target == "" > untranslated
    ttk = foo_lang.deserialize(serialized)
    ttkunit = ttk.findid(translated.getid())
    ttkunit.target = ""
    foo_lang.update(ttk)
    # unit stays FUZZY
    translated = Unit.objects.get(pk=translated.pk)
    assert translated.state == FUZZY
Пример #35
0
def test_mozlang_update(tp0):
    mozlang = Format.objects.get(name="lang")
    tp0.project.filetypes.add(mozlang)

    foo_lang = StoreDBFactory(
        name="foo.lang",
        filetype=mozlang,
        parent=tp0.directory,
        translation_project=tp0)

    store0 = tp0.stores.get(name="store0.po")

    # deserialize as source
    foo_lang.update(store0.deserialize(store0.serialize()))

    # get serialized lang store
    serialized = foo_lang.serialize()

    # mark a translated unit as fuzzy
    translated = foo_lang.units.filter(state=TRANSLATED).first()
    translated.state = FUZZY
    translated.save()

    # source is translated
    old_ttk = foo_lang.deserialize(serialized)
    foo_lang.update(old_ttk)
    # unit is still fuzzy
    translated.refresh_from_db()
    assert translated.state == FUZZY

    # source target changes state also gets updated
    old_ttk.findid(translated.getid()).target = "something else {ok}"
    foo_lang.update(old_ttk, store_revision=translated.revision)
    translated.refresh_from_db()
    assert translated.state == TRANSLATED

    translated = foo_lang.units.filter(state=TRANSLATED).first()
    translated.state = FUZZY
    translated.save()

    # set target == "" > untranslated
    ttk = foo_lang.deserialize(serialized)
    ttkunit = ttk.findid(translated.getid())
    ttkunit.target = ""
    foo_lang.update(ttk)
    # unit stays FUZZY
    translated = Unit.objects.get(pk=translated.pk)
    assert translated.state == FUZZY