~launchpad-pqm/launchpad/devel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
PO Import test with a .po file that has a PO-Revision-Date not updated
======================================================================

When we import a .po file with a 'PO-Revision-Date' that has an older
value than the one stored in IPOFile.header, we should detect it and
notify the user that they should update that field or we assume that
such file is an old version that should not be imported. That way, they
have a chance to fix it.

We have to make an exception for files coming from upstream, though, because
the user may not be able to get the file fixed upstream or the file is older
because a user upload occured before the upstream file made it to Launchpad.
In either case we assume that the upstream file is OK and accept it for
upload.

In this test, we are going to check that we detect these situations and
notify the user about them.

Here are some imports we need to get this test running.

    >>> from lp.app.interfaces.launchpad import ILaunchpadCelebrities
    >>> from lp.registry.interfaces.person import IPersonSet
    >>> from lp.translations.interfaces.translationimportqueue import (
    ...     ITranslationImportQueue)
    >>> from lp.translations.model.potemplate import POTemplateSubset
    >>> import datetime
    >>> import pytz
    >>> UTC = pytz.timezone('UTC')
    >>> translation_import_queue = getUtility(ITranslationImportQueue)
    >>> rosetta_experts = getUtility(ILaunchpadCelebrities).rosetta_experts

And also, the DBSchema to change the imports status

    >>> from lp.translations.enums import RosettaImportStatus

Login as an admin to be able to do changes to the import queue.

    >>> login('carlos@canonical.com')

Here's the person who'll be doing the import.

    >>> person_set = getUtility(IPersonSet)
    >>> person = person_set.getByName('mark')

Now it's time to create the new potemplate

    >>> from lp.registry.model.productrelease import ProductRelease
    >>> release = ProductRelease.get(3)
    >>> release.productseries.product.name
    u'firefox'
    >>> series = release.productseries
    >>> subset = POTemplateSubset(productseries=series)
    >>> potemplate = subset.new(
    ...     name='firefox',
    ...     translation_domain='firefox',
    ...     path='po/firefox.pot',
    ...     owner=person)

We create the POFile object where we are going to attach the .po file.

    >>> pofile = potemplate.newPOFile('cy')

First, we do a valid import.

    >>> pofile_contents = r'''
    ... msgid ""
    ... msgstr ""
    ... "PO-Revision-Date: 2005-05-03 20:41+0100\n"
    ... "Last-Translator: Carlos Perello Marin <carlos@canonical.com>\n"
    ... "Content-Type: text/plain; charset=UTF-8\n"
    ... "Plural-Forms: nplurals=4; plural=n==1) "
    ...     "? 0 : n==2 ? 1 : (n != 8 || n != 11) ? 2 : 3;\n"
    ... "X-Rosetta-Export-Date: %s\n"
    ...
    ... msgid "foo"
    ... msgstr "blah"
    ... ''' % datetime.datetime.now(UTC).isoformat()
    >>> by_maintainer = False
    >>> entry = translation_import_queue.addOrUpdateEntry(
    ...     pofile.path, pofile_contents, by_maintainer, person,
    ...     productseries=series, potemplate=potemplate, pofile=pofile)
    >>> transaction.commit()

We must approve the entry to be able to import it.

    >>> entry.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)

We do the import.  This succeeds without errors.

    >>> (subject, message) = pofile.importFromQueue(entry)
    >>> print entry.error_output
    None

The status is now IMPORTED:

    >>> entry.status == RosettaImportStatus.IMPORTED
    True

(The procedure also generates a confirmation email, but that is tested
in `poimport.txt`.)

We can see that the header has the same 'PO-Revision-Date' as the
file we just imported.

    >>> print pofile.header
    Project-Id-Version:...
    PO-Revision-Date: 2005-05-03 20:41+0100
    ...

Now, we are going to import a .po file that has a 'PO-Revision-Date'
field with a date older than a previous .po import.

    >>> pofile_contents = r'''
    ... msgid ""
    ... msgstr ""
    ... "PO-Revision-Date: 2005-05-03 19:41+0100\n"
    ... "Last-Translator: Carlos Perello Marin <carlos@canonical.com>\n"
    ... "Content-Type: text/plain; charset=UTF-8\n"
    ... "Plural-Forms: nplurals=4; plural=n==1) "
    ...     "? 0 : n==2 ? 1 : (n != 8 || n != 11) ? 2 : 3;\n"
    ... "X-Rosetta-Export-Date: %s\n"
    ...
    ... msgid "foo"
    ... msgstr "blah"
    ... ''' % datetime.datetime.now(UTC).isoformat()
    >>> by_maintainer = False
    >>> entry = translation_import_queue.addOrUpdateEntry(
    ...     pofile.path, pofile_contents, by_maintainer, person,
    ...     productseries=series, potemplate=potemplate, pofile=pofile)
    >>> transaction.commit()

We must approve the entry to be able to import it.

    >>> entry.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)

We do the import.

    >>> (subject, message) = pofile.importFromQueue(entry)

This fails because the file's timestamp was not updated.

    >>> entry.status == RosettaImportStatus.FAILED
    True

    >>> print entry.error_output
    Outdated translation.  The last imported version of this file was dated
    2005-05-03 20:41:00+01:00; the timestamp in the file you uploaded is
    2005-05-03 19:41:00+01:00.

We can see that the header remains unchanged

    >>> print pofile.header
    Project-Id-Version:...
    PO-Revision-Date: 2005-05-03 20:41+0100
    ...

The code also generated an email about the error we produced.

    >>> subject
    u'Import problem - Welsh (cy) - firefox in Mozilla Firefox trunk'
    >>> print message
    Hello Mark Shuttleworth,
    <BLANKLINE>
    On ..., you uploaded a file with
    Welsh (cy) translations for firefox in Mozilla Firefox trunk in
    Launchpad.
    <BLANKLINE>
    We were unable to import your translations because you did not update
    the timestamp in its header to state when you added your translations.
    <BLANKLINE>
    The last imported version of this file was dated
    2005-05-03 20:41:00+01:00; the timestamp in the file you uploaded is
    2005-05-03 19:41:00+01:00.
    <BLANKLINE>
    To fix this problem, please upload the file again, but with the
    'PO-Revision-Date' field updated.
    <BLANKLINE>
    For your convenience, you can get the file you uploaded at:
    http://.../firefox-cy.po
    <BLANKLINE>
    Thank you,
    <BLANKLINE>
    The Launchpad team
    <BLANKLINE>

Finally we are going to import the same po file with the old
'PO-Revision-Date' field but mark it as a file uploaded by the maintainer.

    >>> by_maintainer = True
    >>> entry = translation_import_queue.addOrUpdateEntry(
    ...     pofile.path, pofile_contents, by_maintainer, person,
    ...     productseries=series, potemplate=potemplate, pofile=pofile)
    >>> transaction.commit()

We approve the entry and import it.

    >>> entry.setStatus(RosettaImportStatus.APPROVED, rosetta_experts)
    >>> (subject, message) = pofile.importFromQueue(entry)

This succeeds although the file's timestamp is older than that of the
previous import.

    >>> entry.status == RosettaImportStatus.IMPORTED
    True
    >>> print entry.error_output
    None

But the header remains unchanged, so that the older date is not recorded.

    >>> print pofile.header
    Project-Id-Version:...
    PO-Revision-Date: 2005-05-03 20:41+0100
    ...