Merge lp:~ursinha/launchpad/bug-391569-add-last-changed-column into lp:launchpad

Proposed by Ursula Junque
Status: Merged
Approved by: Ursula Junque
Approved revision: no longer in the source branch.
Merged at revision: not available
Proposed branch: lp:~ursinha/launchpad/bug-391569-add-last-changed-column
Merge into: lp:launchpad
Diff against target: 332 lines (+91/-25)
5 files modified
lib/lp/registry/model/productseries.py (+23/-7)
lib/lp/translations/interfaces/productserieslanguage.py (+7/-2)
lib/lp/translations/model/productserieslanguage.py (+10/-1)
lib/lp/translations/templates/productseries-translations-languages.pt (+20/-0)
lib/lp/translations/tests/test_productserieslanguage.py (+31/-15)
To merge this branch: bzr merge lp:~ursinha/launchpad/bug-391569-add-last-changed-column
Reviewer Review Type Date Requested Status
Graham Binns (community) Approve
Review via email: mp+14366@code.launchpad.net

Commit message

[r=gmb][ui=none][bug=391569] Adds a Last Changed column to +translations pages.

To post a comment you must log in.
Revision history for this message
Ursula Junque (ursinha) wrote :

= Summary =

https://bugs.edge.launchpad.net/rosetta/+bug/391569

This branch adds a "Last Changed" date in +translations pages, showing
the last date a translation in a given language was touched.

== Proposed fix ==

Added a last_changed_date property to the productserieslanguages interface, and changed
productserieslanguage to also return the last date changed among all POFiles
in a product, of a language.

== Pre-implementation notes ==

Discussed with Danilo.

== Tests ==

This should work:
  bin/test -vvt lp.translations.*

(but I did a full test run just to be sure :)

== Demo and Q/A ==

To check the changed pages, go to:
 - https://translations.launchpad.dev/evolution/trunk/+translations
 - https://translations.launchpad.dev/alsa-utils/trunk

= Launchpad lint =

Checking for conflicts. and issues in doctests and templates.
Running jslint, xmllint, pyflakes, and pylint.
Using normal rules.

Linting changed files:
  lib/lp/registry/model/productseries.py
  lib/lp/translations/interfaces/productserieslanguage.py
  lib/lp/translations/tests/test_productserieslanguage.py
  lib/lp/translations/templates/productseries-translations-languages.pt
  lib/lp/translations/model/productserieslanguage.py

== Pylint notices ==

lib/lp/translations/interfaces/productserieslanguage.py
    6: [F0401] Unable to import 'lazr.restful.fields' (No module named restful)

Revision history for this message
Graham Binns (gmb) wrote :
Download full text (4.6 KiB)

Hi Ursula,

Nice branch! I've got a few comments but they're all stylistic nitpicks, so I'm happy to approve this with the changes I've requested.

> === modified file 'lib/lp/registry/model/productseries.py'
> --- lib/lp/registry/model/productseries.py 2009-10-16 15:00:55 +0000
> +++ lib/lp/registry/model/productseries.py 2009-11-03 15:00:31 +0000
> @@ -526,10 +528,21 @@
> POTemplate.iscurrent==True,
> Language.id!=english.id).group_by(Language)
>
> - for (language, imported, changed, new, unreviewed) in (
> - query.order_by(['Language.englishname'])):
> + # XXX: Ursinha 2009-11-02: The Max(POFile.date_changed) result
> + # here is a naive datetime. My guess is that it happens
> + # because UTC awareness is attibuted to the field in the POFile
> + # model class, and in this case the Max function deals directly
> + # with the value returned from the database without
> + # instantiating it.
> + # This seems to be irrelevant to what we're trying to achieve
> + # here, but making a note either way.
> +
> + for (language, imported, changed, new, unreviewed,
> + last_changed) in (
> + query.order_by(['Language.englishname'])):

This is a little hard to read. Maybe something like:

    ordered_results = query.order_by(['Language.englishname'])
    for (language, imported, changed, new, unreviewed,
        last_changed) in ordered_results:
        ...

Would be a little easier.

Also note that the indent on long loop definitions should still be four
spaces.

> psl = ProductSeriesLanguage(self, language)
> - psl.setCounts(total, imported, changed, new, unreviewed)
> + psl.setCounts(total, imported, changed, new, unreviewed,
> + last_changed)

When we wrap long method calls, we should wrap them like this:

    psl.setCounts(
        total, imported, changed, new, unreviewed, last_changed)

> results.append(psl)
>
> return results
>
> === modified file 'lib/lp/translations/tests/test_productserieslanguage.py'
> --- lib/lp/translations/tests/test_productserieslanguage.py 2009-09-12 16:07:05 +0000
> +++ lib/lp/translations/tests/test_productserieslanguage.py 2009-11-03 15:00:31 +0000
> @@ -46,6 +46,7 @@
> # Add a Serbian translation.
> serbian = getUtility(ILanguageSet).getLanguageByCode('sr')
> sr_pofile = self.factory.makePOFile(serbian.code, potemplate)
> +
> psls = list(self.productseries.productserieslanguages)
> self.assertEquals(len(psls), 1)
>
> @@ -111,7 +112,8 @@
> removeSecurityProxy(potemplate).messagecount = number_of_potmsgsets
> return potemplate
>
> - def setPOFileStatistics(self, pofile, imported, changed, new, unreviewed):
> + def setPOFileStatistics(self, pofile, imported, changed, new, unreviewed,
> + date_changed):

The wrapped lines of a method definition should start under the first
argument, thus:

    def setPOFileStatistics(self, pofile, imported, chang...

Read more...

review: Approve
Revision history for this message
Ursula Junque (ursinha) wrote :
Download full text (4.1 KiB)

> Hi Ursula,
>
> Nice branch! I've got a few comments but they're all stylistic nitpicks, so
> I'm happy to approve this with the changes I've requested.

All changes applied, incremental diff below. Thanks!

=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py 2009-11-03 04:55:45 +0000
+++ lib/lp/registry/model/productseries.py 2009-11-04 17:15:56 +0000
@@ -493,13 +493,15 @@
                 POTemplate.iscurrent==True,
                 Language.id!=english.id)

- for language, pofile in query.order_by(['Language.englishname']):
+ ordered_results = query.order_by(['Language.englishname'])
+
+ for language, pofile in ordered_results:
                 psl = ProductSeriesLanguage(self, language, pofile=pofile)
                 psl.setCounts(pofile.potemplate.messageCount(),
                               pofile.currentCount(),
                               pofile.updatesCount(),
                               pofile.rosettaCount(),
- pofile.unreviewedCount(),
+ pofile.unreviewedCount(),
                               pofile.date_changed)
                 results.append(psl)
         else:
@@ -537,12 +539,13 @@
             # This seems to be irrelevant to what we're trying to achieve
             # here, but making a note either way.

- for (language, imported, changed, new, unreviewed,
- last_changed) in (
- query.order_by(['Language.englishname'])):
+ ordered_results = query.order_by(['Language.englishname'])
+
+ for (language, imported, changed, new, unreviewed,
+ last_changed) in ordered_results:
                 psl = ProductSeriesLanguage(self, language)
- psl.setCounts(total, imported, changed, new, unreviewed,
- last_changed)
+ psl.setCounts(
+ total, imported, changed, new, unreviewed, last_changed)
                 results.append(psl)

         return results

=== modified file 'lib/lp/translations/tests/test_productserieslanguage.py'
--- lib/lp/translations/tests/test_productserieslanguage.py 2009-11-03 13:53:07 +0000
+++ lib/lp/translations/tests/test_productserieslanguage.py 2009-11-04 17:15:56 +0000
@@ -113,7 +113,7 @@
         return potemplate

     def setPOFileStatistics(self, pofile, imported, changed, new, unreviewed,
- ...

Read more...

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'lib/lp/registry/model/productseries.py'
--- lib/lp/registry/model/productseries.py 2009-10-16 15:00:55 +0000
+++ lib/lp/registry/model/productseries.py 2009-11-10 18:11:11 +0000
@@ -15,7 +15,7 @@
1515
16from sqlobject import (16from sqlobject import (
17 ForeignKey, StringCol, SQLMultipleJoin, SQLObjectNotFound)17 ForeignKey, StringCol, SQLMultipleJoin, SQLObjectNotFound)
18from storm.expr import Sum18from storm.expr import Sum, Max
19from zope.component import getUtility19from zope.component import getUtility
20from zope.interface import implements20from zope.interface import implements
21from storm.locals import And, Desc21from storm.locals import And, Desc
@@ -493,13 +493,16 @@
493 POTemplate.iscurrent==True,493 POTemplate.iscurrent==True,
494 Language.id!=english.id)494 Language.id!=english.id)
495495
496 for language, pofile in query.order_by(['Language.englishname']):496 ordered_results = query.order_by(['Language.englishname'])
497
498 for language, pofile in ordered_results:
497 psl = ProductSeriesLanguage(self, language, pofile=pofile)499 psl = ProductSeriesLanguage(self, language, pofile=pofile)
498 psl.setCounts(pofile.potemplate.messageCount(),500 psl.setCounts(pofile.potemplate.messageCount(),
499 pofile.currentCount(),501 pofile.currentCount(),
500 pofile.updatesCount(),502 pofile.updatesCount(),
501 pofile.rosettaCount(),503 pofile.rosettaCount(),
502 pofile.unreviewedCount())504 pofile.unreviewedCount(),
505 pofile.date_changed)
503 results.append(psl)506 results.append(psl)
504 else:507 else:
505 # If there is more than one template, do a single508 # If there is more than one template, do a single
@@ -517,7 +520,8 @@
517 Sum(POFile.currentcount),520 Sum(POFile.currentcount),
518 Sum(POFile.updatescount),521 Sum(POFile.updatescount),
519 Sum(POFile.rosettacount),522 Sum(POFile.rosettacount),
520 Sum(POFile.unreviewed_count)),523 Sum(POFile.unreviewed_count),
524 Max(POFile.date_changed)),
521 POFile.language==Language.id,525 POFile.language==Language.id,
522 POFile.variant==None,526 POFile.variant==None,
523 Language.visible==True,527 Language.visible==True,
@@ -526,10 +530,22 @@
526 POTemplate.iscurrent==True,530 POTemplate.iscurrent==True,
527 Language.id!=english.id).group_by(Language)531 Language.id!=english.id).group_by(Language)
528532
529 for (language, imported, changed, new, unreviewed) in (533 # XXX: Ursinha 2009-11-02: The Max(POFile.date_changed) result
530 query.order_by(['Language.englishname'])):534 # here is a naive datetime. My guess is that it happens
535 # because UTC awareness is attibuted to the field in the POFile
536 # model class, and in this case the Max function deals directly
537 # with the value returned from the database without
538 # instantiating it.
539 # This seems to be irrelevant to what we're trying to achieve
540 # here, but making a note either way.
541
542 ordered_results = query.order_by(['Language.englishname'])
543
544 for (language, imported, changed, new, unreviewed,
545 last_changed) in ordered_results:
531 psl = ProductSeriesLanguage(self, language)546 psl = ProductSeriesLanguage(self, language)
532 psl.setCounts(total, imported, changed, new, unreviewed)547 psl.setCounts(
548 total, imported, changed, new, unreviewed, last_changed)
533 results.append(psl)549 results.append(psl)
534550
535 return results551 return results
536552
=== modified file 'lib/lp/translations/interfaces/productserieslanguage.py'
--- lib/lp/translations/interfaces/productserieslanguage.py 2009-09-11 09:29:51 +0000
+++ lib/lp/translations/interfaces/productserieslanguage.py 2009-11-10 18:11:11 +0000
@@ -7,7 +7,7 @@
77
8from zope.interface import Attribute, Interface8from zope.interface import Attribute, Interface
9from zope.schema import (9from zope.schema import (
10 Choice, TextLine)10 Choice, Datetime, TextLine)
1111
12from canonical.launchpad import _12from canonical.launchpad import _
13from lp.translations.interfaces.pofile import IPOFile13from lp.translations.interfaces.pofile import IPOFile
@@ -45,6 +45,11 @@
45 "language. This includes only the real pofiles where translations "45 "language. This includes only the real pofiles where translations "
46 "exist.")46 "exist.")
4747
48
49 last_changed_date = Datetime(
50 title=_('When this file was last changed.'))
51
52
48 def getPOFilesFor(potemplates):53 def getPOFilesFor(potemplates):
49 """Return `POFiles` for each of `potemplates`, in the same order.54 """Return `POFiles` for each of `potemplates`, in the same order.
5055
@@ -52,7 +57,7 @@
52 required language, a `DummyPOFile` is provided.57 required language, a `DummyPOFile` is provided.
53 """58 """
5459
55 def setCounts(total, imported, changed, new, unreviewed):60 def setCounts(total, imported, changed, new, unreviewed, last_changed):
56 """Set aggregated message counts for ProductSeriesLanguage."""61 """Set aggregated message counts for ProductSeriesLanguage."""
5762
58 def recalculateCounts(total, imported, changed, new, unreviewed):63 def recalculateCounts(total, imported, changed, new, unreviewed):
5964
=== modified file 'lib/lp/translations/model/productserieslanguage.py'
--- lib/lp/translations/model/productserieslanguage.py 2009-09-14 11:27:37 +0000
+++ lib/lp/translations/model/productserieslanguage.py 2009-11-10 18:11:11 +0000
@@ -36,12 +36,13 @@
36 self.variant = variant36 self.variant = variant
37 self.pofile = pofile37 self.pofile = pofile
38 self.id = 038 self.id = 0
39 self._last_changed_date = None
3940
40 # Reset all cached counts.41 # Reset all cached counts.
41 self.setCounts()42 self.setCounts()
4243
43 def setCounts(self, total=None, imported=None, changed=None, new=None,44 def setCounts(self, total=None, imported=None, changed=None, new=None,
44 unreviewed=None):45 unreviewed=None, last_changed=None):
45 """See `IProductSeriesLanguage`."""46 """See `IProductSeriesLanguage`."""
46 self._messagecount = total47 self._messagecount = total
47 # "currentcount" in RosettaStats conflicts our recent terminology48 # "currentcount" in RosettaStats conflicts our recent terminology
@@ -51,6 +52,9 @@
51 self._updatescount = changed52 self._updatescount = changed
52 self._rosettacount = new53 self._rosettacount = new
53 self._unreviewed_count = unreviewed54 self._unreviewed_count = unreviewed
55 if last_changed is not None:
56 self._last_changed_date = last_changed
57
5458
55 def _getMessageCount(self):59 def _getMessageCount(self):
56 store = Store.of(self.language)60 store = Store.of(self.language)
@@ -112,6 +116,11 @@
112 return self._unreviewed_count116 return self._unreviewed_count
113117
114 @property118 @property
119 def last_changed_date(self):
120 """See `IProductSeriesLanguage`."""
121 return self._last_changed_date
122
123 @property
115 def pofiles(self):124 def pofiles(self):
116 """See `IProductSeriesLanguage`."""125 """See `IProductSeriesLanguage`."""
117 store = Store.of(self.language)126 store = Store.of(self.language)
118127
=== modified file 'lib/lp/translations/templates/productseries-translations-languages.pt'
--- lib/lp/translations/templates/productseries-translations-languages.pt 2009-09-10 07:24:24 +0000
+++ lib/lp/translations/templates/productseries-translations-languages.pt 2009-11-10 18:11:11 +0000
@@ -11,6 +11,7 @@
11 <th>Untranslated</th>11 <th>Untranslated</th>
12 <th>Needs review</th>12 <th>Needs review</th>
13 <th>Changed</th>13 <th>Changed</th>
14 <th>Last Changed</th>
14 </tr>15 </tr>
15 </thead>16 </thead>
16 <tbody>17 <tbody>
@@ -47,6 +48,25 @@
47 tal:content="language_stats/updatesCount">0</span>48 tal:content="language_stats/updatesCount">0</span>
48 <tal:value content="language_stats/updatesCount" />49 <tal:value content="language_stats/updatesCount" />
49 </td>50 </td>
51 <td>
52 <span class="sortkey"
53 tal:condition="language_stats/last_changed_date"
54 tal:content="language_stats/last_changed_date/fmt:datetime">
55 time sort key
56 </span>
57 <span
58 tal:condition="language_stats/last_changed_date"
59 tal:attributes="
60 title language_stats/last_changed_date/fmt:datetime"
61 tal:content="
62 language_stats/last_changed_date/fmt:approximatedate"
63 >
64 2007-02-10
65 </span>
66 <tal:block condition="not: language_stats/last_changed_date">
67 &mdash;
68 </tal:block>
69 </td>
50 </tr>70 </tr>
51 </tbody>71 </tbody>
52 </table>72 </table>
5373
=== modified file 'lib/lp/translations/tests/test_productserieslanguage.py'
--- lib/lp/translations/tests/test_productserieslanguage.py 2009-09-12 16:07:05 +0000
+++ lib/lp/translations/tests/test_productserieslanguage.py 2009-11-10 18:11:11 +0000
@@ -46,6 +46,7 @@
46 # Add a Serbian translation.46 # Add a Serbian translation.
47 serbian = getUtility(ILanguageSet).getLanguageByCode('sr')47 serbian = getUtility(ILanguageSet).getLanguageByCode('sr')
48 sr_pofile = self.factory.makePOFile(serbian.code, potemplate)48 sr_pofile = self.factory.makePOFile(serbian.code, potemplate)
49
49 psls = list(self.productseries.productserieslanguages)50 psls = list(self.productseries.productserieslanguages)
50 self.assertEquals(len(psls), 1)51 self.assertEquals(len(psls), 1)
5152
@@ -111,7 +112,8 @@
111 removeSecurityProxy(potemplate).messagecount = number_of_potmsgsets112 removeSecurityProxy(potemplate).messagecount = number_of_potmsgsets
112 return potemplate113 return potemplate
113114
114 def setPOFileStatistics(self, pofile, imported, changed, new, unreviewed):115 def setPOFileStatistics(self, pofile, imported, changed, new, unreviewed,
116 date_changed):
115 # Instead of creating all relevant translation messages, we117 # Instead of creating all relevant translation messages, we
116 # just fake cached statistics instead.118 # just fake cached statistics instead.
117 naked_pofile = removeSecurityProxy(pofile)119 naked_pofile = removeSecurityProxy(pofile)
@@ -119,6 +121,7 @@
119 naked_pofile.updatescount = changed121 naked_pofile.updatescount = changed
120 naked_pofile.rosettacount = new122 naked_pofile.rosettacount = new
121 naked_pofile.unreviewed_count = unreviewed123 naked_pofile.unreviewed_count = unreviewed
124 naked_pofile.date_changed = date_changed
122 naked_pofile.sync()125 naked_pofile.sync()
123126
124 def setUp(self):127 def setUp(self):
@@ -136,20 +139,22 @@
136 psl.currentCount(),139 psl.currentCount(),
137 psl.rosettaCount(),140 psl.rosettaCount(),
138 psl.updatesCount(),141 psl.updatesCount(),
139 psl.unreviewedCount()),142 psl.unreviewedCount(),
140 stats)143 psl.last_changed_date),
144 stats)
141145
142 def test_DummyProductSeriesLanguage(self):146 def test_DummyProductSeriesLanguage(self):
143 # With no templates all counts are zero.147 # With no templates all counts are zero.
144 psl = self.psl_set.getDummy(self.productseries, self.language)148 psl = self.psl_set.getDummy(self.productseries, self.language)
145 self.failUnless(verifyObject(IProductSeriesLanguage, psl))149 self.failUnless(verifyObject(IProductSeriesLanguage, psl))
146 self.assertPSLStatistics(psl, (0, 0, 0, 0, 0, 0))150 self.assertPSLStatistics(psl, (0, 0, 0, 0, 0, 0, None))
147151
148 # Adding a single template with 10 messages makes the total152 # Adding a single template with 10 messages makes the total
149 # count of messages go up to 10.153 # count of messages go up to 10.
150 potemplate = self.createPOTemplateWithPOTMsgSets(10)154 potemplate = self.createPOTemplateWithPOTMsgSets(10)
151 psl = self.psl_set.getDummy(self.productseries, self.language)155 psl = self.psl_set.getDummy(self.productseries, self.language)
152 self.assertPSLStatistics(psl, (10, 0, 0, 0, 0, 0))156 self.assertPSLStatistics(
157 psl, (10, 0, 0, 0, 0, 0, None))
153158
154 def test_OneTemplate(self):159 def test_OneTemplate(self):
155 # With only one template, statistics match those of the POFile.160 # With only one template, statistics match those of the POFile.
@@ -158,7 +163,7 @@
158163
159 # Set statistics to 4 imported, 3 new in rosetta (out of which 2164 # Set statistics to 4 imported, 3 new in rosetta (out of which 2
160 # are updates) and 5 with unreviewed suggestions.165 # are updates) and 5 with unreviewed suggestions.
161 self.setPOFileStatistics(pofile, 4, 2, 3, 5)166 self.setPOFileStatistics(pofile, 4, 2, 3, 5, pofile.date_changed)
162167
163 # Getting PSL through PSLSet gives an uninitialized object.168 # Getting PSL through PSLSet gives an uninitialized object.
164 psl = self.psl_set.getProductSeriesLanguage(169 psl = self.psl_set.getProductSeriesLanguage(
@@ -173,7 +178,8 @@
173 pofile.currentCount(),178 pofile.currentCount(),
174 pofile.rosettaCount(),179 pofile.rosettaCount(),
175 pofile.updatesCount(),180 pofile.updatesCount(),
176 pofile.unreviewedCount()))181 pofile.unreviewedCount(),
182 pofile.date_changed))
177183
178 def test_TwoTemplates(self):184 def test_TwoTemplates(self):
179 # With two templates, statistics are added up.185 # With two templates, statistics are added up.
@@ -181,27 +187,34 @@
181 pofile1 = self.factory.makePOFile(self.language.code, potemplate1)187 pofile1 = self.factory.makePOFile(self.language.code, potemplate1)
182 # Set statistics to 4 imported, 3 new in rosetta (out of which 2188 # Set statistics to 4 imported, 3 new in rosetta (out of which 2
183 # are updates) and 5 with unreviewed suggestions.189 # are updates) and 5 with unreviewed suggestions.
184 self.setPOFileStatistics(pofile1, 4, 2, 3, 5)190 self.setPOFileStatistics(pofile1, 4, 2, 3, 5, pofile1.date_changed)
185191
186 potemplate2 = self.createPOTemplateWithPOTMsgSets(20)192 potemplate2 = self.createPOTemplateWithPOTMsgSets(20)
187 pofile2 = self.factory.makePOFile(self.language.code, potemplate2)193 pofile2 = self.factory.makePOFile(self.language.code, potemplate2)
188 # Set statistics to 1 imported, 1 new in rosetta (which is also the194 # Set statistics to 1 imported, 1 new in rosetta (which is also the
189 # 1 update) and 1 with unreviewed suggestions.195 # 1 update) and 1 with unreviewed suggestions.
190 self.setPOFileStatistics(pofile2, 1, 1, 1, 1)196 self.setPOFileStatistics(pofile2, 1, 1, 1, 1, pofile2.date_changed)
191197
192 psl = self.productseries.productserieslanguages[0]198 psl = self.productseries.productserieslanguages[0]
193199
200 # The psl.last_changed_date here is a naive datetime. So, for sake of
201 # the tests, we should make pofile2 naive when checking if it matches
202 # the last calculated changed date, that should be the same as
203 # pofile2, created last.
204
194 # Total is a sum of totals in both POTemplates (10+20).205 # Total is a sum of totals in both POTemplates (10+20).
195 # Translated is a sum of imported and rosetta translations,206 # Translated is a sum of imported and rosetta translations,
196 # which adds up as (4+3)+(1+1).207 # which adds up as (4+3)+(1+1).
197 self.assertPSLStatistics(psl, (30, 9, 5, 4, 3, 6))208 self.assertPSLStatistics(psl, (30, 9, 5, 4, 3, 6,
209 pofile2.date_changed.replace(tzinfo=None)))
198 self.assertPSLStatistics(psl, (210 self.assertPSLStatistics(psl, (
199 pofile1.messageCount() + pofile2.messageCount(),211 pofile1.messageCount() + pofile2.messageCount(),
200 pofile1.translatedCount() + pofile2.translatedCount(),212 pofile1.translatedCount() + pofile2.translatedCount(),
201 pofile1.currentCount() + pofile2.currentCount(),213 pofile1.currentCount() + pofile2.currentCount(),
202 pofile1.rosettaCount() + pofile2.rosettaCount(),214 pofile1.rosettaCount() + pofile2.rosettaCount(),
203 pofile1.updatesCount() + pofile2.updatesCount(),215 pofile1.updatesCount() + pofile2.updatesCount(),
204 pofile1.unreviewedCount() + pofile2.unreviewedCount()))216 pofile1.unreviewedCount() + pofile2.unreviewedCount(),
217 pofile2.date_changed.replace(tzinfo=None)))
205218
206 def test_recalculateCounts(self):219 def test_recalculateCounts(self):
207 # Test that recalculateCounts works correctly.220 # Test that recalculateCounts works correctly.
@@ -210,21 +223,23 @@
210223
211 # Set statistics to 1 imported, 3 new in rosetta (out of which 2224 # Set statistics to 1 imported, 3 new in rosetta (out of which 2
212 # are updates) and 4 with unreviewed suggestions.225 # are updates) and 4 with unreviewed suggestions.
213 self.setPOFileStatistics(pofile1, 1, 2, 3, 4)226 self.setPOFileStatistics(pofile1, 1, 2, 3, 4, pofile1.date_changed)
214227
215 potemplate2 = self.createPOTemplateWithPOTMsgSets(20)228 potemplate2 = self.createPOTemplateWithPOTMsgSets(20)
216 pofile2 = self.factory.makePOFile(self.language.code, potemplate2)229 pofile2 = self.factory.makePOFile(self.language.code, potemplate2)
217 # Set statistics to 1 imported, 1 new in rosetta (which is also the230 # Set statistics to 1 imported, 1 new in rosetta (which is also the
218 # 1 update) and 1 with unreviewed suggestions.231 # 1 update) and 1 with unreviewed suggestions.
219 self.setPOFileStatistics(pofile2, 1, 1, 1, 1)232 self.setPOFileStatistics(pofile2, 1, 1, 1, 1, pofile2.date_changed)
220233
221 psl = self.psl_set.getProductSeriesLanguage(self.productseries,234 psl = self.psl_set.getProductSeriesLanguage(self.productseries,
222 self.language)235 self.language)
236 # recalculateCounts() doesn't recalculate the last changed date.
223 psl.recalculateCounts()237 psl.recalculateCounts()
224 # Total is a sum of totals in both POTemplates (10+20).238 # Total is a sum of totals in both POTemplates (10+20).
225 # Translated is a sum of imported and rosetta translations,239 # Translated is a sum of imported and rosetta translations,
226 # which adds up as (1+3)+(1+1).240 # which adds up as (1+3)+(1+1).
227 self.assertPSLStatistics(psl, (30, 6, 2, 4, 3, 5))241 self.assertPSLStatistics(psl, (30, 6, 2, 4, 3, 5,
242 None))
228243
229 def test_recalculateCounts_no_pofiles(self):244 def test_recalculateCounts_no_pofiles(self):
230 # Test that recalculateCounts works correctly even when there245 # Test that recalculateCounts works correctly even when there
@@ -235,7 +250,8 @@
235 self.language)250 self.language)
236 psl.recalculateCounts()251 psl.recalculateCounts()
237 # And all the counts are zero.252 # And all the counts are zero.
238 self.assertPSLStatistics(psl, (3, 0, 0, 0, 0, 0))253 self.assertPSLStatistics(psl, (3, 0, 0, 0, 0, 0,
254 None))
239255
240256
241def test_suite():257def test_suite():