~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
= Adding and editing milestones =

We have a "milestones" portlet which shows active milestones for a
structural object (product, project, distroseries, productseries). This
utility function will print out the milestones in that portlet:

    >>> def milestones_in_portlet(browser):
    ...     portlet = find_portlet(browser.contents, 'Active milestones')
    ...     if portlet is None:
    ...         return 'NO MILESTONE PORTLET'
    ...     return extract_text(portlet.find('table'))

== Adding a milestone ==

Let's make Sample Person the owner of Ubuntu and alsa-utils for this
story.

    >>> admin_browser.open('http://launchpad.dev/ubuntu/+reassign')
    >>> admin_browser.getControl(name='field.owner').value = 'name12'
    >>> admin_browser.getControl('Change').click()

    >>> admin_browser.open('http://launchpad.dev/alsa-utils/+edit-people')
    >>> admin_browser.getControl(name='field.owner').value = 'name12'
    >>> admin_browser.getControl('Save changes').click()

Milestone creations is restricted to the project owner, or to the series
owner or driver. This means that No Privileges Person won't be able to
see the link to add a milestone nor access the page directly.

    >>> user_browser.open('http://launchpad.dev/alsa-utils/trunk')
    >>> user_browser.getLink('Create milestone').click()
    Traceback (most recent call last):
      ...
    LinkNotFoundError
    >>> user_browser.open(
    ...     'http://launchpad.dev/alsa-utils/trunk/+addmilestone')
    Traceback (most recent call last):
      ...
    Unauthorized: ...

    >>> user_browser.open('http://launchpad.dev/ubuntu/hoary')
    >>> user_browser.getLink('Create milestone').click()
    Traceback (most recent call last):
      ...
    LinkNotFoundError
    >>> user_browser.open('http://launchpad.dev/ubuntu/hoary/+addmilestone')
    Traceback (most recent call last):
      ...
    Unauthorized: ...

But Sample Person will be able to use the 'Create milestone' link to
create a new milestone.

    >>> test_browser = setupBrowser(auth='Basic test@canonical.com:test')
    >>> test_browser.open('http://launchpad.dev/alsa-utils/trunk')
    >>> test_browser.getLink('Create milestone').click()
    >>> test_browser.url
    'http://launchpad.dev/alsa-utils/trunk/+addmilestone'

    >>> test_browser.open('http://launchpad.dev/ubuntu/hoary')
    >>> test_browser.getLink('Create milestone').click()
    >>> test_browser.url
    'http://launchpad.dev/ubuntu/hoary/+addmilestone'


== Milestone bug subscriptions ==

To receive email notifications about bugs pretaining to a milestone, we
can create structural bug subscriptions.

    >>> user_browser.open('http://launchpad.dev/firefox/+milestone/1.0')
    >>> user_browser.getLink('Subscribe to bug mail').click()
    >>> print user_browser.url
    http://launchpad.dev/firefox/+milestone/1.0/+subscribe
    >>> print user_browser.title
    Subscribe to Bugs in Mozilla Firefox 1.0

But we can't subscribe to project milestones, since they are not real objects.

    >>> user_browser.open('http://launchpad.dev/mozilla/+milestone/1.0')
    >>> user_browser.getLink('Subscribe to bug mail')
    Traceback (most recent call last):
    ...
    LinkNotFoundError


== Deleting milestones ==

The series page lists all the active and releases milestones targeted to
the series.

    >>> driver_browser = setupBrowser(auth='Basic test@canonical.com:test')
    >>> driver_browser.open('http://launchpad.dev/firefox/trunk')
    >>> print driver_browser.title
    Series trunk : Mozilla Firefox
    >>> print extract_text(find_tag_by_id(
    ...     driver_browser.contents, 'series-trunk'))
    Version                   Expected  Released                   Summary
    Mozilla Firefox 0.9.2...  Set date  Change details 2004-10-16
    ...
    Mozilla Firefox 0.9.1...
    ...
    Mozilla Firefox 0.9...
    ...
    Mozilla Firefox 1.0
    ...

A user with launchpad.Edit rights for a release can see the delete link and
access the delete page. Sample Person is the driver so he has those rights.

    >>> driver_browser.getLink('0.9.2').click()
    >>> print driver_browser.title
    0.9.2 "One (secure) Tree Hill" : Mozilla Firefox

    >>> driver_browser.getLink('Delete milestone').click()
    >>> print driver_browser.title
    Delete Mozilla Firefox 0.9.2...

The 0.9.2 release has a release and files associated with it. Sample
Person reads that they will be deleted too.

    >>> print extract_text(find_main_content(driver_browser.contents))
    Delete Mozilla Firefox 0.9.2 "One (secure) Tree Hill"
    ...
    The associated 0.9.2 release "One (secure) Tree Hill" and its files
    will be also be deleted:
    firefox_0.9.2.orig.tar.gz ...

Sample Person chooses the delete button, then reads that the action is
successful.

    >>> from canonical.testing.layers import MemcachedLayer

    >>> MemcachedLayer.purge()
    >>> driver_browser.getControl('Delete Milestone').click()
    >>> print driver_browser.title
    Series trunk : Mozilla Firefox

    >>> for message in get_feedback_messages(driver_browser.contents):
    ...     print message
    Milestone 0.9.2 deleted.
    >>> print extract_text(find_tag_by_id(
    ...     driver_browser.contents, 'series-trunk'))
    Version                Expected   Released     Summary
    Mozilla Firefox 0.9.1 ...
    Mozilla Firefox 0.9 ...
    Mozilla Firefox 1.0 ...