Merge lp:~jtv/launchpad/recife-new-resetcurrenttranslation into lp:~launchpad/launchpad/recife

Proposed by Jeroen T. Vermeulen
Status: Merged
Approved by: Michael Nelson
Approved revision: no longer in the source branch.
Merged at revision: 9164
Proposed branch: lp:~jtv/launchpad/recife-new-resetcurrenttranslation
Merge into: lp:~launchpad/launchpad/recife
Diff against target: 406 lines (+188/-90)
4 files modified
lib/lp/translations/browser/translationmessage.py (+15/-16)
lib/lp/translations/interfaces/potmsgset.py (+23/-10)
lib/lp/translations/model/potmsgset.py (+39/-17)
lib/lp/translations/tests/test_potmsgset.py (+111/-47)
To merge this branch: bzr merge lp:~jtv/launchpad/recife-new-resetcurrenttranslation
Reviewer Review Type Date Requested Status
Michael Nelson (community) code Approve
Review via email: mp+33747@code.launchpad.net

Commit message

resetCurrentTranslation

Description of the change

= resetCurrentTranslation =

For the Recife feature branch, upon discussion with Danilo. This re-implements POTMsgSet.resetCurrentTranslation based on the new data model.

However that change breaks a view test. The breakage would have been hard to fix (without getting very dirty and making it very brittle) because the one call to resetCurrentTranslation, from a view, is right next to POTMsgSet.updateTranslation. That's the huge, complex, convoluted, unmaintainable and inscrutable method that we're trying to get rid of with the old model. No matter what we do, a view method that combines the old-model updateTranslation and the new-model resetCurrentTranslation will be wrong.

So I renamed the old resetCurrentTranslation to old_resetCurrentTranslation and kept its tests (those that still make sense) for a fresh, totally revised, new-world version of resetCurrentTranslation. Once we rip out the updateTranslation-based view code and replace it with proper new-model code, that code will use the new resetCurrentTranslation.

You will see a few things in this branch that may shock you, dear reviewer:

1. old_resetCurrentTranslation is _not_ an acceptable method name.

2. There are no tests for old_resetCurrentTranslation.

How do I look myself in the mirror? Well, I feel it all makes sense if you'll give me a chance to explain.

First, we want old_resetCurrentTranslation to die. Quickly and painlessly, but die nonetheless. The more it stands out as a Thing That Should Not Be™, the less likely it is that we'll be forgetting to get rid of it, or uncertain about whether it can be cleaned out, or using it in more places, or tolerating its presence. So in this case, a bad name is a good one.

Second, we want old_resetCurrentTranslation to die. It has but a single callsite, and that needs to be completely rewritten. The only reason to keep the old method around is to satisfy existing tests until we can get the new model in place. In a shameless reversal of the normal relationships between working code and tests, the acceptance tests are what we really want to preserve here and old_resetCurrentTranslation is there only to make sure that we can. If future changes required this method to stand on its head and recite Shakespeare in order for the view tests to pass, I would happily make it do that—without a single unit test—and still sleep well at night.

With that I conclude my case. I hope I managed to convey the fact that we want old_resetCurrentTranslation to die. And if anything, we are the victims here. Trust us.

To test:
{{{
./bin/test -vvc -m lp.translations.tests.test_potmsgset
./bin/test -vvc -m lp.translations -t pofile-translate-needs-review-flags-preserved
}}}

No lint left, apart from a few pre-existing complaints about comments surrounded by blank lines. In all of the cases I didn't fix, I felt the code had a legitimate need for creative license. Plus, I don't want to avoid _too_ many conflicts with other people's ongoing work!

Jeroen

To post a comment you must log in.
Revision history for this message
Michael Nelson (michael.nelson) wrote :
Download full text (4.0 KiB)

Heh... I enjoyed reading your MP description :)

And yes, I've been in that position before too... the one case (a transition to new infrastructure) where a bad name is a good one.

I've just got one question below about "the other side". But r=me. And great tests :)

> === modified file 'lib/lp/translations/browser/translationmessage.py'
> --- lib/lp/translations/browser/translationmessage.py 2010-08-23 08:35:29 +0000
> +++ lib/lp/translations/browser/translationmessage.py 2010-08-26 10:24:07 +0000
> @@ -300,16 +299,16 @@
>
> if self.request.method == 'POST':
> if self.user is None:
> - raise UnexpectedFormData, (
> - 'Anonymous users or users who are not accepting our '
> - 'licensing terms cannot do POST submissions.')
> + raise UnexpectedFormData(
> + "Anonymous users or users who are not accepting our "
> + "licensing terms cannot do POST submissions.")

Out of interest, is switching to double-quotes by default a personal
preference or a new LP coding recommendation?

> === modified file 'lib/lp/translations/model/potmsgset.py'
> --- lib/lp/translations/model/potmsgset.py 2010-08-24 11:39:06 +0000
> +++ lib/lp/translations/model/potmsgset.py 2010-08-26 10:24:07 +0000
> @@ -1295,25 +1295,47 @@
>
> return message
>
> - def resetCurrentTranslation(self, pofile, lock_timestamp):
> - """See `IPOTMsgSet`."""
> -
> - assert(lock_timestamp is not None)
> -
> + def old_resetCurrentTranslation(self, pofile, lock_timestamp):
> + """See `POTMsgSet`.
> +
> + This message is OBSOLETE in the Recife feature branch. It's
> + still here only until we replace its one call with the new
> + method.
> + """
> + assert lock_timestamp is not None, "No lock timestamp given."
> current = self.getCurrentTranslationMessage(
> pofile.potemplate, pofile.language)
> -
> - if (current is not None):
> - # Check for translation conflicts and update the required
> - # attributes.
> - self._maybeRaiseTranslationConflict(current, lock_timestamp)
> - current.is_current_ubuntu = False
> - # Converge the current translation only if it is diverged and not
> - # current upstream.
> - is_diverged = current.potemplate is not None
> - if is_diverged and not current.is_current_upstream:
> - current.potemplate = None
> - pofile.date_changed = UTC_NOW
> + if current is None:
> + return

Nice... I prefer guard code like this too :)

> +
> + # Check for translation conflicts and update the required
> + # attributes.
> + self._maybeRaiseTranslationConflict(current, lock_timestamp)
> + current.is_current_ubuntu = False
> + # Converge the current translation only if it is diverged and
> + # not current upstream.
> + if current.is_diverged and not current.is_current_upstream:
> + current.potemplate = None
> + pofile.markChanged()
> +
> + def resetCurrentTranslation(...

Read more...

review: Approve (code)
Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :
Download full text (3.4 KiB)

Thanks for the review, and glad you enjoyed the MP. :)

> > === modified file 'lib/lp/translations/browser/translationmessage.py'
> > --- lib/lp/translations/browser/translationmessage.py 2010-08-23 08:35:29
> +0000
> > +++ lib/lp/translations/browser/translationmessage.py 2010-08-26 10:24:07
> +0000
> > @@ -300,16 +299,16 @@
> >
> > if self.request.method == 'POST':
> > if self.user is None:
> > - raise UnexpectedFormData, (
> > - 'Anonymous users or users who are not accepting our '
> > - 'licensing terms cannot do POST submissions.')
> > + raise UnexpectedFormData(
> > + "Anonymous users or users who are not accepting our "
> > + "licensing terms cannot do POST submissions.")
>
> Out of interest, is switching to double-quotes by default a personal
> preference or a new LP coding recommendation?

Personal preference. But I do think it's sensible for free-form text where an apostrophe would be perfectly appropriate. IIRC one of these strings even went so far as to backslash-escape an apostrophe. For God's sake, why!?

Personally I use single quotes (to minimize "ink on the page") for identifiers and such, where an apostrophe would not be appropriate, or for empty strings and things close to it.

> > === modified file 'lib/lp/translations/model/potmsgset.py'
> > --- lib/lp/translations/model/potmsgset.py 2010-08-24 11:39:06 +0000
> > +++ lib/lp/translations/model/potmsgset.py 2010-08-26 10:24:07 +0000

> > +
> > + # Check for translation conflicts and update the required
> > + # attributes.
> > + self._maybeRaiseTranslationConflict(current, lock_timestamp)
> > + current.is_current_ubuntu = False
> > + # Converge the current translation only if it is diverged and
> > + # not current upstream.
> > + if current.is_diverged and not current.is_current_upstream:
> > + current.potemplate = None
> > + pofile.markChanged()
> > +
> > + def resetCurrentTranslation(self, pofile, lock_timestamp=None,
> > + share_with_other_side=False):
>
> OK, I forgot to mention this on the IFace declaration, but I have no idea what
> the other side is (maybe the interface description could say a bit more to
> cater for non-translation folk?). From your tests, it looks like it is
> upstream/downstream?

Pretty much, yes: "project" and "Ubuntu." A TranslationMessage is selected as current on the "project" side if it has the is_current_upstream flag set, and on the Ubuntu side if it has the is_current_ubuntu flag set. See lp.translations.interfaces.side.

> > + """See `IPOTMsgSet`."""
> > + traits = getUtility(ITranslationSideTraitsSet).getTraits(
> > + pofile.potemplate.translation_side)
> > + current_message = traits.getCurrentMessage(
> > + self, pofile.potemplate, pofile.language)
> > +
> > + if current_message is None:
> > + # Nothing to do here.
>
> Is this an error? If a reset is called on a translation that doesn't yet have
> a translation? I'm sure you've though...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/translations/browser/translationmessage.py'
--- lib/lp/translations/browser/translationmessage.py 2010-08-23 08:35:29 +0000
+++ lib/lp/translations/browser/translationmessage.py 2010-08-26 09:18:44 +0000
@@ -1,4 +1,4 @@
1# Copyright 2009 Canonical Ltd. This software is licensed under the1# Copyright 2009-2010 Canonical Ltd. This software is licensed under the
2# GNU Affero General Public License version 3 (see the file LICENSE).2# GNU Affero General Public License version 3 (see the file LICENSE).
33
4# pylint: disable-msg=W04044# pylint: disable-msg=W0404
@@ -25,7 +25,6 @@
25import re25import re
26import urllib26import urllib
2727
28import gettextpo
29import pytz28import pytz
30from z3c.ptcompat import ViewPageTemplateFile29from z3c.ptcompat import ViewPageTemplateFile
31from zope import datetime as zope_datetime30from zope import datetime as zope_datetime
@@ -300,16 +299,16 @@
300299
301 if self.request.method == 'POST':300 if self.request.method == 'POST':
302 if self.user is None:301 if self.user is None:
303 raise UnexpectedFormData, (302 raise UnexpectedFormData(
304 'Anonymous users or users who are not accepting our '303 "Anonymous users or users who are not accepting our "
305 'licensing terms cannot do POST submissions.')304 "licensing terms cannot do POST submissions.")
306 translations_person = ITranslationsPerson(self.user)305 translations_person = ITranslationsPerson(self.user)
307 if (translations_person.translations_relicensing_agreement306 if (translations_person.translations_relicensing_agreement
308 is not None and307 is not None and
309 not translations_person.translations_relicensing_agreement):308 not translations_person.translations_relicensing_agreement):
310 raise UnexpectedFormData, (309 raise UnexpectedFormData(
311 'Users who do not agree to licensing terms '310 "Users who do not agree to licensing terms "
312 'cannot do POST submissions.')311 "cannot do POST submissions.")
313 try:312 try:
314 # Try to get the timestamp when the submitted form was313 # Try to get the timestamp when the submitted form was
315 # created. We use it to detect whether someone else updated314 # created. We use it to detect whether someone else updated
@@ -320,9 +319,9 @@
320 except zope_datetime.DateTimeError:319 except zope_datetime.DateTimeError:
321 # invalid format. Either we don't have the timestamp in the320 # invalid format. Either we don't have the timestamp in the
322 # submitted form or it has the wrong format.321 # submitted form or it has the wrong format.
323 raise UnexpectedFormData, (322 raise UnexpectedFormData(
324 'We didn\'t find the timestamp that tells us when was'323 "We didn't find the timestamp that tells us when was"
325 ' generated the submitted form.')324 " generated the submitted form.")
326325
327 # Check if this is really the form we are listening for..326 # Check if this is really the form we are listening for..
328 if self.request.form.get("submit_translations"):327 if self.request.form.get("submit_translations"):
@@ -436,13 +435,14 @@
436 force_suggestion=force_suggestion,435 force_suggestion=force_suggestion,
437 force_diverged=force_diverge)436 force_diverged=force_diverge)
438437
439 # If suggestions were forced and user has the rights to do it,
440 # reset the current translation.
441 empty_suggestions = self._areSuggestionsEmpty(translations)438 empty_suggestions = self._areSuggestionsEmpty(translations)
442 if (force_suggestion and439 if (force_suggestion and
443 self.user_is_official_translator and440 self.user_is_official_translator and
444 empty_suggestions):441 empty_suggestions):
445 potmsgset.resetCurrentTranslation(442 # The user requested that the message be reviewed,
443 # without suggesting a new translation. Reset the
444 # current translation so that it can be reviewed again.
445 potmsgset.old_resetCurrentTranslation(
446 self.pofile, self.lock_timestamp)446 self.pofile, self.lock_timestamp)
447447
448 except TranslationConflict:448 except TranslationConflict:
@@ -1481,7 +1481,6 @@
1481 return "%s_dismissable_button" % self.html_id1481 return "%s_dismissable_button" % self.html_id
14821482
14831483
1484
1485class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):1484class CurrentTranslationMessageZoomedView(CurrentTranslationMessageView):
1486 """A view that displays a `TranslationMessage`, but zoomed in.1485 """A view that displays a `TranslationMessage`, but zoomed in.
14871486
@@ -1515,7 +1514,6 @@
1515# Pseudo-content class1514# Pseudo-content class
1516#1515#
15171516
1518
1519class TranslationMessageSuggestions:1517class TranslationMessageSuggestions:
1520 """See `ITranslationMessageSuggestions`."""1518 """See `ITranslationMessageSuggestions`."""
15211519
@@ -1563,6 +1561,7 @@
1563class Submission:1561class Submission:
1564 """A submission generated from a TranslationMessage"""1562 """A submission generated from a TranslationMessage"""
15651563
1564
1566def convert_translationmessage_to_submission(1565def convert_translationmessage_to_submission(
1567 message, current_message, plural_form, pofile, legal_warning_needed,1566 message, current_message, plural_form, pofile, legal_warning_needed,
1568 is_empty=False, packaged=False):1567 is_empty=False, packaged=False):
15691568
=== modified file 'lib/lp/translations/interfaces/potmsgset.py'
--- lib/lp/translations/interfaces/potmsgset.py 2010-08-24 11:39:06 +0000
+++ lib/lp/translations/interfaces/potmsgset.py 2010-08-26 09:18:44 +0000
@@ -298,16 +298,29 @@
298 that this change is based on.298 that this change is based on.
299 """299 """
300300
301 def resetCurrentTranslation(pofile, lock_timestamp):301 def old_resetCurrentTranslation(pofile, lock_timestamp):
302 """Reset the currently used translation.302 """Reset a translation.
303303
304 This will set the "is_current_ubuntu" attribute to False and if the304 OBSOLETE in Recife. In the new model, use the new
305 message is diverged, will try to converge it.305 `resetCurrentTranslation` implementation instead.
306 :param pofile: a `POFile` to dismiss suggestions from.306 """
307 :param lock_timestamp: the timestamp when we checked the values we307
308 want to update.308 def resetCurrentTranslation(pofile, lock_timestamp=None,
309309 share_with_other_side=False):
310 If a translation conflict is detected, TranslationConflict is raised.310 """Turn the current translation back into a suggestion.
311
312 This deactivates the message's current translation. The message
313 becomes untranslated or, if it was diverged, reverts to its
314 shared translation.
315
316 The previously current translation becomes visible as a new
317 suggestion again, as do all suggestions that came after it.
318
319 :param pofile: The `POFile` to make the change in.
320 :param lock_timestamp: Timestamp of the original translation state
321 that this change is based on.
322 :param share_with_other_side: Make the same change on the other
323 translation side.
311 """324 """
312325
313 def clearCurrentTranslation(pofile, submitter, origin,326 def clearCurrentTranslation(pofile, submitter, origin,
314327
=== modified file 'lib/lp/translations/model/potmsgset.py'
--- lib/lp/translations/model/potmsgset.py 2010-08-24 11:39:06 +0000
+++ lib/lp/translations/model/potmsgset.py 2010-08-26 09:18:44 +0000
@@ -1295,25 +1295,47 @@
12951295
1296 return message1296 return message
12971297
1298 def resetCurrentTranslation(self, pofile, lock_timestamp):1298 def old_resetCurrentTranslation(self, pofile, lock_timestamp):
1299 """See `IPOTMsgSet`."""1299 """See `POTMsgSet`.
13001300
1301 assert(lock_timestamp is not None)1301 This message is OBSOLETE in the Recife feature branch. It's
13021302 still here only until we replace its one call with the new
1303 method.
1304 """
1305 assert lock_timestamp is not None, "No lock timestamp given."
1303 current = self.getCurrentTranslationMessage(1306 current = self.getCurrentTranslationMessage(
1304 pofile.potemplate, pofile.language)1307 pofile.potemplate, pofile.language)
13051308 if current is None:
1306 if (current is not None):1309 return
1307 # Check for translation conflicts and update the required1310
1308 # attributes.1311 # Check for translation conflicts and update the required
1309 self._maybeRaiseTranslationConflict(current, lock_timestamp)1312 # attributes.
1310 current.is_current_ubuntu = False1313 self._maybeRaiseTranslationConflict(current, lock_timestamp)
1311 # Converge the current translation only if it is diverged and not1314 current.is_current_ubuntu = False
1312 # current upstream.1315 # Converge the current translation only if it is diverged and
1313 is_diverged = current.potemplate is not None1316 # not current upstream.
1314 if is_diverged and not current.is_current_upstream:1317 if current.is_diverged and not current.is_current_upstream:
1315 current.potemplate = None1318 current.potemplate = None
1316 pofile.date_changed = UTC_NOW1319 pofile.markChanged()
1320
1321 def resetCurrentTranslation(self, pofile, lock_timestamp=None,
1322 share_with_other_side=False):
1323 """See `IPOTMsgSet`."""
1324 traits = getUtility(ITranslationSideTraitsSet).getTraits(
1325 pofile.potemplate.translation_side)
1326 current_message = traits.getCurrentMessage(
1327 self, pofile.potemplate, pofile.language)
1328
1329 if current_message is None:
1330 # Nothing to do here.
1331 return
1332
1333 self._checkForConflict(current_message, lock_timestamp)
1334 traits.setFlag(current_message, False)
1335 if share_with_other_side:
1336 traits.other_side_traits.setFlag(current_message, False)
1337 current_message.shareIfPossible()
1338 pofile.markChanged()
13171339
1318 def clearCurrentTranslation(self, pofile, submitter, origin,1340 def clearCurrentTranslation(self, pofile, submitter, origin,
1319 share_with_other_side=False,1341 share_with_other_side=False,
13201342
=== modified file 'lib/lp/translations/tests/test_potmsgset.py'
--- lib/lp/translations/tests/test_potmsgset.py 2010-08-24 11:39:06 +0000
+++ lib/lp/translations/tests/test_potmsgset.py 2010-08-26 09:18:44 +0000
@@ -31,6 +31,7 @@
31 POTMsgSetInIncompatibleTemplatesError,31 POTMsgSetInIncompatibleTemplatesError,
32 TranslationCreditsType,32 TranslationCreditsType,
33 )33 )
34from lp.translations.interfaces.side import ITranslationSideTraitsSet
34from lp.translations.interfaces.translationfileformat import (35from lp.translations.interfaces.translationfileformat import (
35 TranslationFileFormat,36 TranslationFileFormat,
36 )37 )
@@ -943,6 +944,12 @@
943 yield now944 yield now
944 now += timedelta(milliseconds=1)945 now += timedelta(milliseconds=1)
945946
947 def _getCurrentMessage(self):
948 traits = getUtility(ITranslationSideTraitsSet).getTraits(
949 self.potemplate.translation_side)
950 return traits.getCurrentMessage(
951 self.potmsgset, self.potemplate, self.pofile.language)
952
946 def setUp(self):953 def setUp(self):
947 # Create a product with all the boilerplate objects to be able to954 # Create a product with all the boilerplate objects to be able to
948 # create TranslationMessage objects.955 # create TranslationMessage objects.
@@ -960,59 +967,117 @@
960 self.pofile = self.factory.makePOFile('eo', template)967 self.pofile = self.factory.makePOFile('eo', template)
961968
962 def test_resetCurrentTranslation_shared(self):969 def test_resetCurrentTranslation_shared(self):
963 # Resetting a shared current translation will change iscurrent=False970 # Resetting a shared current translation deactivates it, and
964 # and there will be no other current translations for this POTMsgSet.971 # leaves no other current translation in its place.
965972 translation = self.factory.makeCurrentTranslationMessage(
966 translation = self.factory.makeTranslationMessage(973 pofile=self.pofile, potmsgset=self.potmsgset)
967 self.pofile, self.potmsgset, translations=[u'Shared translation'],974
968 reviewer=self.factory.makePerson(),975 self.potmsgset.resetCurrentTranslation(self.pofile)
969 is_current_upstream=False, force_diverged=False,976
970 date_updated=self.now())977 current = self._getCurrentMessage()
971
972 self.potmsgset.resetCurrentTranslation(self.pofile, self.now())
973 current = self.potmsgset.getCurrentTranslationMessage(
974 self.potemplate, self.pofile.language)
975 self.assertTrue(current is None)978 self.assertTrue(current is None)
976 self.assertFalse(translation.is_current_ubuntu)979 self.assertFalse(translation.is_current_ubuntu)
977 self.assertFalse(translation.is_current_upstream)980 self.assertFalse(translation.is_current_upstream)
978 self.assertTrue(translation.potemplate is None)981 self.assertFalse(translation.is_diverged)
979982
980 def test_resetCurrentTranslation_diverged_not_imported(self):983 def test_resetCurrentTranslation_diverged_not_imported(self):
981 # Resetting a diverged current translation that was not984 # Resetting a diverged current translation disables it and makes
982 # imported, will change is_current_ubuntu to False and will make985 # it shared. In other words, it becomes a suggestion.
983 # it shared.986 translation = self.factory.makeCurrentTranslationMessage(
984 translation = self.factory.makeTranslationMessage(987 pofile=self.pofile, potmsgset=self.potmsgset)
985 self.pofile, self.potmsgset, translations=[u'Diverged text'],988
986 reviewer=self.factory.makePerson(),989 self.potmsgset.resetCurrentTranslation(self.pofile)
987 is_current_upstream=False, force_diverged=True,990
988 date_updated=self.now())991 current = self._getCurrentMessage()
989
990 self.potmsgset.resetCurrentTranslation(self.pofile, self.now())
991 current = self.potmsgset.getCurrentTranslationMessage(
992 self.potemplate, self.pofile.language)
993 self.assertTrue(current is None)992 self.assertTrue(current is None)
994 self.assertFalse(translation.is_current_ubuntu)993 self.assertFalse(translation.is_current_ubuntu)
995 self.assertFalse(translation.is_current_upstream)994 self.assertFalse(translation.is_current_upstream)
996 self.assertTrue(translation.potemplate is None)995 self.assertFalse(translation.is_diverged)
997996
998 def test_resetCurrentTranslation_diverged_imported(self):997 def test_resetCurrentTranslation_unmasks_shared(self):
999 # Resetting a diverged current translation that was imported in998 # Resetting a diverged translation reverts the POTMsgSet to its
1000 # Launchpad will change iscurrent to False but the translation999 # current shared translation.
1001 # message will be still diverged.1000 shared = self.factory.makeCurrentTranslationMessage(
10021001 pofile=self.pofile, potmsgset=self.potmsgset)
1003 translation = self.factory.makeTranslationMessage(1002 diverged = self.factory.makeDivergedTranslationMessage(
1004 self.pofile, self.potmsgset, translations=[u'Imported diverged'],1003 pofile=self.pofile, potmsgset=self.potmsgset)
1005 reviewer=self.factory.makePerson(),1004
1006 is_current_upstream=True, force_diverged=True,1005 self.assertNotEqual(shared, diverged)
1007 date_updated=self.now())1006 self.assertTrue(diverged.is_current_upstream)
10081007 self.assertTrue(shared.is_current_upstream)
1009 self.potmsgset.resetCurrentTranslation(self.pofile, self.now())1008 self.assertEqual(diverged, self._getCurrentMessage())
1010 current = self.potmsgset.getCurrentTranslationMessage(1009
1011 self.potemplate, self.pofile.language)1010 self.potmsgset.resetCurrentTranslation(self.pofile)
1012 self.assertTrue(current is None)1011
1013 self.assertFalse(translation.is_current_ubuntu)1012 self.assertEqual(shared, self._getCurrentMessage())
1014 self.assertTrue(translation.is_current_upstream)1013
1015 self.assertFalse(translation.potemplate is None)1014 def test_resetCurrentTranslation_resets_one_side(self):
1015 # By default, resetting a translation works only on one
1016 # translation side.
1017 current = self.factory.makeCurrentTranslationMessage(
1018 pofile=self.pofile, potmsgset=self.potmsgset, current_other=True)
1019 traits = getUtility(ITranslationSideTraitsSet).getTraits(
1020 self.potemplate.translation_side)
1021
1022 self.assertTrue(traits.getFlag(current))
1023 self.assertTrue(traits.other_side_traits.getFlag(current))
1024
1025 self.potmsgset.resetCurrentTranslation(
1026 self.pofile, share_with_other_side=False)
1027
1028 self.assertFalse(traits.getFlag(current))
1029 self.assertTrue(traits.other_side_traits.getFlag(current))
1030
1031 def test_resetCurrentTranslation_resets_both_sides(self):
1032 # The share_with_other_side parameter lets you reset a current
1033 # translation on both translation sides.
1034 current = self.factory.makeCurrentTranslationMessage(
1035 pofile=self.pofile, potmsgset=self.potmsgset, current_other=True)
1036
1037 self.assertTrue(current.is_current_upstream)
1038 self.assertTrue(current.is_current_ubuntu)
1039
1040 self.potmsgset.resetCurrentTranslation(
1041 self.pofile, share_with_other_side=True)
1042
1043 self.assertFalse(current.is_current_upstream)
1044 self.assertFalse(current.is_current_ubuntu)
1045
1046 def test_resetCurrentTranslation_does_not_override_other_message(self):
1047 # Resetting a message does not reset the current translation on
1048 # the other translation side if it's not the same one as on this
1049 # side.
1050 self.assertIs(None, self.potemplate.distroseries)
1051 other_potemplate = self.factory.makePOTemplate(
1052 distroseries=self.factory.makeDistroSeries(),
1053 sourcepackagename=self.factory.makeSourcePackageName())
1054 other_pofile = self.factory.makePOFile(
1055 self.pofile.language.code, potemplate=other_potemplate)
1056
1057 message_this = self.factory.makeCurrentTranslationMessage(
1058 pofile=self.pofile, potmsgset=self.potmsgset)
1059 message_other = self.factory.makeCurrentTranslationMessage(
1060 pofile=other_pofile, potmsgset=self.potmsgset)
1061 traits = getUtility(ITranslationSideTraitsSet).getTraits(
1062 self.potemplate.translation_side)
1063
1064 self.assertTrue(traits.other_side_traits.getFlag(message_other))
1065
1066 self.potmsgset.resetCurrentTranslation(
1067 self.pofile, share_with_other_side=True)
1068
1069 self.assertTrue(traits.other_side_traits.getFlag(message_other))
1070
1071 def test_resetCurrentTranslation_detects_conflict(self):
1072 now = self.now()
1073 current = self.factory.makeCurrentTranslationMessage(
1074 pofile=self.pofile, potmsgset=self.potmsgset)
1075 current.markReviewed(self.factory.makePerson(), now)
1076
1077 self.assertRaises(
1078 TranslationConflict,
1079 self.potmsgset.resetCurrentTranslation,
1080 self.pofile, now - timedelta(1))
10161081
10171082
1018class TestPOTMsgSetCornerCases(TestCaseWithFactory):1083class TestPOTMsgSetCornerCases(TestCaseWithFactory):
@@ -1587,8 +1652,7 @@
1587 def _makeTranslations(self, potmsgset, forms=1):1652 def _makeTranslations(self, potmsgset, forms=1):
1588 return removeSecurityProxy(potmsgset)._findPOTranslations([1653 return removeSecurityProxy(potmsgset)._findPOTranslations([
1589 self.factory.getUniqueString()1654 self.factory.getUniqueString()
1590 for counter in xrange(forms)1655 for counter in xrange(forms)])
1591 ])
15921656
1593 def test_baseline(self):1657 def test_baseline(self):
1594 # setCurrentTranslation sets the current upstream translation1658 # setCurrentTranslation sets the current upstream translation

Subscribers

People subscribed via source and target branches