~launchpad-pqm/launchpad/devel

« back to all changes in this revision

Viewing changes to lib/lp/bugs/browser/tests/bugtarget-filebug-views.txt

Merge from devel

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
= Filebug view classes =
 
1
Filebug view classes
 
2
====================
2
3
 
3
4
The base class used for all the filebug pages is FileBugViewBase. It
4
5
contains enough functionality to file bug, the classes inheriting from
36
37
    >>> filebug_view = create_view(ubuntu_firefox, LaunchpadTestRequest())
37
38
    >>> filebug_view.validate(bug_data) is None
38
39
    True
 
40
 
39
41
    >>> filebug_view.submit_bug_action.success(bug_data)
40
42
    >>> filebug_view.added_bug.title
41
43
    u'Test Title'
 
44
 
42
45
    >>> filebug_view.added_bug.description
43
46
    u'Test description.'
44
47
 
45
48
 
46
 
== URLs to additional FileBug elements ==
 
49
URLs to additional FileBug elements
 
50
-----------------------------------
47
51
 
48
52
FileBugViewBase's inline_filebug_base_url returns the base URL for all
49
53
inline +filebug work.
90
94
    http://launchpad.dev/evolution/+filebug-show-similar
91
95
 
92
96
 
93
 
== Adding extra info to filed bugs ==
 
97
Adding extra info to filed bugs
 
98
-------------------------------
94
99
 
95
100
It's possible for bug reporting tools to upload a file with debug
96
101
information to Launchpad, and pass that information to the filebug page.
103
108
the Content-Disposition header tells Launchpad what to do with the
104
109
different parts.
105
110
 
106
 
=== First inline part ==
 
111
 
 
112
First inline part
 
113
.................
107
114
 
108
115
The first inline part will be appended to the bug description.
109
116
 
113
120
    ... --boundary
114
121
    ... Content-disposition: inline
115
122
    ... Content-type: text/plain; charset=utf-8
116
 
    ...
 
123
    ... 
117
124
    ... This should be added to the description.
118
125
    ...
119
126
    ... --boundary--
120
127
    ... """
121
 
 
122
128
    >>> import transaction
123
129
    >>> from canonical.launchpad.interfaces.temporaryblobstorage import ITemporaryStorageManager
124
130
    >>> token = getUtility(ITemporaryStorageManager).new(debug_data)
143
149
    ...     job.job.complete()
144
150
    >>> process_blob(token)
145
151
 
146
 
Now, if we pass the token to the filebug view, the extra_data
147
 
attribute will be set with the actual data.
 
152
Now, if we pass the token to the filebug view, the extra_data attribute
 
153
will be set with the actual data.
148
154
 
149
155
    >>> filebug_view = create_initialized_view(ubuntu_firefox, '+filebug')
150
156
    >>> filebug_view.publishTraverse(
156
162
 
157
163
    >>> filebug_view.validate(bug_data) is None
158
164
    True
 
165
 
159
166
    >>> filebug_view.submit_bug_action.success(bug_data)
160
167
    >>> filebug_view.added_bug.title
161
168
    u'Test Title'
 
169
 
162
170
    >>> print filebug_view.added_bug.description #doctest: -NORMALIZE_WHITESPACE
163
171
    Test description.
164
172
    <BLANKLINE>
172
180
    Additional information was added to the bug description.
173
181
 
174
182
 
175
 
=== Other inline parts ===
 
183
Other inline parts
 
184
..................
176
185
 
177
186
If there are more than one inline part, those will be added as comments
178
187
to the bug.
183
192
    ... --boundary
184
193
    ... Content-disposition: inline
185
194
    ... Content-type: text/plain; charset=utf-8
186
 
    ...
 
195
    ... 
187
196
    ... This should be added to the description.
188
197
    ...
189
198
    ... --boundary
190
199
    ... Content-disposition: inline
191
200
    ... Content-type: text/plain; charset=utf-8
192
 
    ...
 
201
    ... 
193
202
    ... This should be added as a comment.
194
203
    ...
195
204
    ... --boundary
196
205
    ... Content-disposition: inline
197
206
    ... Content-type: text/plain; charset=utf-8
198
 
    ...
 
207
    ... 
199
208
    ... This should be added as another comment.
200
209
    ...
201
210
    ... --boundary--
208
217
    >>> filebug_view.publishTraverse(filebug_view.request,
209
218
    ...     token) is filebug_view
210
219
    True
 
220
 
211
221
    >>> filebug_view.validate(bug_data) is None
212
222
    True
 
223
 
213
224
    >>> filebug_view.submit_bug_action.success(bug_data)
214
225
 
215
226
    >>> filebug_view.added_bug.title
216
227
    u'Test Title'
 
228
 
217
229
    >>> print filebug_view.added_bug.description #doctest: -NORMALIZE_WHITESPACE
218
230
    Test description.
219
231
    <BLANKLINE>
235
247
    A comment with additional information was added to the bug report.
236
248
 
237
249
 
238
 
=== Attachments ===
 
250
Attachments
 
251
...........
239
252
 
240
 
All the parts that have a 'Content-disposition: attachment' header
241
 
will get added as attachments to the bug. The attachment description can
242
 
be specified using a Content-description header, but it's not required.
 
253
All the parts that have a 'Content-disposition: attachment' header will
 
254
get added as attachments to the bug. The attachment description can be
 
255
specified using a Content-description header, but it's not required.
243
256
 
244
257
    >>> debug_data = """MIME-Version: 1.0
245
258
    ... Content-type: multipart/mixed; boundary=boundary
247
260
    ... --boundary
248
261
    ... Content-disposition: attachment; filename='attachment1'
249
262
    ... Content-type: text/plain; charset=utf-8
250
 
    ...
 
263
    ... 
251
264
    ... This is an attachment.
252
265
    ...
253
266
    ... --boundary
254
267
    ... Content-disposition: attachment; filename='attachment2'
255
268
    ... Content-description: Attachment description.
256
269
    ... Content-type: text/plain; charset=ISO-8859-1
257
 
    ...
 
270
    ... 
258
271
    ... This is another attachment, with a description.
259
272
    ...
260
273
    ... --boundary--
267
280
    >>> filebug_view.publishTraverse(filebug_view.request,
268
281
    ...     token) is filebug_view
269
282
    True
 
283
 
270
284
    >>> filebug_view.validate(bug_data) is None
271
285
    True
 
286
 
272
287
    >>> filebug_view.submit_bug_action.success(bug_data)
273
288
 
274
289
Since the attachments are stored in the Librarian, we need to commit the
278
293
 
279
294
    >>> filebug_view.added_bug.title
280
295
    u'Test Title'
 
296
 
281
297
    >>> print filebug_view.added_bug.description
282
298
    Test description.
283
299
 
319
335
    Comment by No Privileges Person: 2 attachment(s)
320
336
 
321
337
 
322
 
=== Private Bugs ===
 
338
Private Bugs
 
339
............
323
340
 
324
 
We can specify whether a bug is private by providing Private field in the
325
 
message.
 
341
We can specify whether a bug is private by providing Private field in
 
342
the message.
326
343
 
327
344
    >>> debug_data = """MIME-Version: 1.0
328
345
    ... Content-type: multipart/mixed; boundary=boundary
331
348
    ... --boundary
332
349
    ... Content-disposition: inline
333
350
    ... Content-type: text/plain; charset=utf-8
334
 
    ...
 
351
    ... 
335
352
    ... This bug should be private.
336
353
    ...
337
354
    ... --boundary--
344
361
    >>> filebug_view.publishTraverse(filebug_view.request,
345
362
    ...     token) is filebug_view
346
363
    True
 
364
 
347
365
    >>> filebug_view.extra_data.extra_description
348
366
    u'This bug should be private.'
 
367
 
349
368
    >>> filebug_view.extra_data.private
350
369
    True
351
370
 
352
371
    >>> filebug_view.validate(bug_data) is None
353
372
    True
 
373
 
354
374
    >>> filebug_view.submit_bug_action.success(bug_data)
355
375
    >>> filebug_view.added_bug.title
356
376
    u'Test Title'
 
377
 
357
378
    >>> print filebug_view.added_bug.description #doctest: -NORMALIZE_WHITESPACE
358
379
    Test description.
359
380
    <BLANKLINE>
360
381
    This bug should be private.
 
382
 
361
383
    >>> filebug_view.added_bug.private
362
384
    True
 
385
 
363
386
    >>> filebug_view.added_bug.security_related
364
387
    False
365
388
 
366
 
Since the bug was marked private before it was filed, only the bug reporter has
367
 
been subscribed to the bug and there should be no indirect subscribers.
 
389
Since the bug was marked private before it was filed, only the bug
 
390
reporter has been subscribed to the bug and there should be no indirect
 
391
subscribers.
368
392
 
369
393
    >>> for subscriber in filebug_view.added_bug.getDirectSubscribers():
370
394
    ...     print subscriber.displayname
387
411
    ... --boundary
388
412
    ... Content-disposition: inline
389
413
    ... Content-type: text/plain; charset=utf-8
390
 
    ...
 
414
    ... 
391
415
    ... This bug should be public.
392
416
    ...
393
417
    ... --boundary--
400
424
    >>> filebug_view.publishTraverse(filebug_view.request,
401
425
    ...     token) is filebug_view
402
426
    True
 
427
 
403
428
    >>> filebug_view.extra_data.extra_description
404
429
    u'This bug should be public.'
 
430
 
405
431
    >>> filebug_view.extra_data.private
406
432
    False
407
433
 
408
434
    >>> filebug_view.validate(bug_data) is None
409
435
    True
 
436
 
410
437
    >>> filebug_view.submit_bug_action.success(bug_data)
411
438
    >>> filebug_view.added_bug.title
412
439
    u'Test Title'
 
440
 
413
441
    >>> print filebug_view.added_bug.description #doctest: -NORMALIZE_WHITESPACE
414
442
    Test description.
415
443
    <BLANKLINE>
416
444
    This bug should be public.
 
445
 
417
446
    >>> filebug_view.added_bug.private
418
447
    False
419
448
 
420
 
Since this bug is public, both the reporter and the bug supervisor have been
421
 
subscribed.
 
449
Since this bug is public, both the reporter and the bug supervisor have
 
450
been subscribed.
422
451
 
423
452
    >>> for subscriber in filebug_view.added_bug.getDirectSubscribers():
424
453
    ...     print subscriber.displayname
430
459
    Ubuntu Team
431
460
 
432
461
 
433
 
=== Subscriptions ===
 
462
Subscriptions
 
463
.............
434
464
 
435
 
We can also subscribe someone to this bug when we file it by using a Subscribe
436
 
field in the message. Multiple people can be specified and they can be
437
 
identified by their Launchpad name or their e-mail address.
 
465
We can also subscribe someone to this bug when we file it by using a
 
466
Subscribe field in the message. Multiple people can be specified and
 
467
they can be identified by their Launchpad name or their e-mail address.
438
468
 
439
469
    >>> debug_data = """MIME-Version: 1.0
440
470
    ... Content-type: multipart/mixed; boundary=boundary
443
473
    ... --boundary
444
474
    ... Content-disposition: inline
445
475
    ... Content-type: text/plain; charset=utf-8
446
 
    ...
 
476
    ... 
447
477
    ... Other people are interested in this bug.
448
478
    ...
449
479
    ... --boundary--
467
497
 
468
498
    >>> filebug_view.validate(bug_data) is None
469
499
    True
 
500
 
470
501
    >>> filebug_view.submit_bug_action.success(bug_data)
471
502
    >>> filebug_view.added_bug.title
472
503
    u'Test Title'
 
504
 
473
505
    >>> print filebug_view.added_bug.description #doctest: -NORMALIZE_WHITESPACE
474
506
    Test description.
475
507
    <BLANKLINE>
495
527
    Sample Person has been subscribed to this bug.
496
528
 
497
529
 
498
 
=== Subscribers to Private bugs ===
 
530
Subscribers to Private bugs
 
531
...........................
499
532
 
500
 
The Private and Subscriber fields are intended to be used together to subscribe
501
 
certain people and teams to bugs when they are filed.
 
533
The Private and Subscriber fields are intended to be used together to
 
534
subscribe certain people and teams to bugs when they are filed.
502
535
 
503
536
    >>> debug_data = """MIME-Version: 1.0
504
537
    ... Content-type: multipart/mixed; boundary=boundary
508
541
    ... --boundary
509
542
    ... Content-disposition: inline
510
543
    ... Content-type: text/plain; charset=utf-8
511
 
    ...
 
544
    ... 
512
545
    ... This bug should be private, and Mark Shuttleworth subscribed.
513
546
    ...
514
547
    ... --boundary--
546
579
 
547
580
    >>> filebug_view.added_bug.private
548
581
    True
 
582
 
549
583
    >>> filebug_view.added_bug.security_related
550
584
    False
551
585
 
552
 
As well as the reporter, Mark Shuttleworth should have been subscribed to the
553
 
bug.
 
586
As well as the reporter, Mark Shuttleworth should have been subscribed
 
587
to the bug.
554
588
 
555
589
    >>> for subscriber in filebug_view.added_bug.getDirectSubscribers():
556
590
    ...     print subscriber.displayname
562
596
    >>> filebug_view.added_bug.getIndirectSubscribers()
563
597
    []
564
598
 
565
 
The user will be notified that Mark Shuttleworth has been subscribed to this
566
 
bug and that the bug has been marked as private.
 
599
The user will be notified that Mark Shuttleworth has been subscribed to
 
600
this bug and that the bug has been marked as private.
567
601
 
568
602
    >>> for notification in filebug_view.request.response.notifications:
569
603
    ...     print notification.message
573
607
    This bug report has been marked private...
574
608
 
575
609
 
576
 
== publishTraverse() ==
 
610
publishTraverse()
 
611
-----------------
577
612
 
578
613
As already seen above, it's the FileBugViewBase's publishTraverse that
579
614
finds the right blob to use.
582
617
    >>> filebug_view.publishTraverse(filebug_view.request,
583
618
    ...     token) is filebug_view
584
619
    True
 
620
 
585
621
    >>> filebug_view.extra_data_token == token
586
622
    True
 
623
 
587
624
    >>> filebug_view.extra_data is not None
588
625
    True
589
626
 
597
634
    NotFound:...
598
635
 
599
636
 
600
 
=== Not found tokens ===
 
637
Not found tokens
 
638
................
601
639
 
602
640
If publishTraverse is called with a token that can't be found, a
603
641
NotFound error is raised.
609
647
    NotFound:...
610
648
 
611
649
 
612
 
== Adding tags to filed bugs ==
 
650
Adding tags to filed bugs
 
651
-------------------------
613
652
 
614
653
    >>> bug_data = dict(
615
654
    ...     title=u'Test Title', comment=u'Test description.',
623
662
    >>> filebug_view = create_initialized_view(ubuntu_firefox, '+filebug')
624
663
    >>> filebug_view.validate(bug_data) is None
625
664
    True
 
665
 
626
666
    >>> filebug_view.submit_bug_action.success(bug_data)
627
667
    >>> filebug_view.added_bug.title
628
668
    u'Test Title'
 
669
 
629
670
    >>> filebug_view.added_bug.description
630
671
    u'Test description.'
 
672
 
631
673
    >>> for tag in filebug_view.added_bug.tags:
632
674
    ...     print tag
633
675
    bar
634
676
    foo
635
677
 
636
678
 
637
 
== Filing security bugs ==
 
679
Filing security bugs
 
680
--------------------
638
681
 
639
682
The base class allows security bugs to be filed.
640
683
 
645
688
    >>> filebug_view = create_initialized_view(ubuntu_firefox, '+filebug')
646
689
    >>> filebug_view.validate(bug_data) is None
647
690
    True
 
691
 
648
692
    >>> filebug_view.submit_bug_action.success(bug_data)
649
693
    >>> filebug_view.added_bug.title
650
694
    u'Security bug'
 
695
 
651
696
    >>> filebug_view.added_bug.security_related
652
697
    True
653
698
 
654
699
 
655
 
== Extra fields for bug supervisors ==
 
700
Extra fields for bug supervisors
 
701
--------------------------------
656
702
 
657
703
Bug supervisors are offered several extra options when filing bugs.
658
704
 
692
738
    ...     milestone=milestone, status=BugTaskStatus.TRIAGED)
693
739
    >>> print filebug_view.validate(bug_data)
694
740
    None
 
741
 
695
742
    >>> filebug_view.submit_bug_action.success(bug_data)
696
743
    >>> [added_bugtask] = filebug_view.added_bug.bugtasks
697
744
 
698
745
    >>> print added_bugtask.status.title
699
746
    Triaged
 
747
 
700
748
    >>> print added_bugtask.importance.title
701
749
    High
 
750
 
702
751
    >>> print added_bugtask.assignee.name
703
752
    bug-superdude
 
753
 
704
754
    >>> print added_bugtask.milestone.name
705
755
    bug-superdude-milestone
706
 
 
707
 
 
708
 
== Validation ==
709
 
 
710
 
 
711
 
=== The comment field ===
712
 
 
713
 
When filing a bug, supplying an empty comment causes a validation error:
714
 
 
715
 
    >>> from lp.bugs.browser.bugtarget import FileBugGuidedView
716
 
    >>> request = LaunchpadTestRequest(
717
 
    ...     form={'field.actions.submit_bug': 'Submit Bug Request'})
718
 
    >>> filebug_view = FileBugGuidedView(ubuntu, request)
719
 
    >>> filebug_view.submit_bug_action.submitted()
720
 
    True
721
 
    >>> bug_data = dict(title='Test Title', comment='')
722
 
    >>> filebug_view.setUpFields()
723
 
    >>> filebug_view.setUpWidgets()
724
 
    >>> filebug_view.validate(bug_data)
725
 
    >>> print filebug_view.getFieldError('comment')
726
 
    Required input is missing.
727
 
 
728
 
Comments can be up to 50000 characters in length:
729
 
 
730
 
    >>> comment = 'x' * 50000
731
 
    >>> bug_data = dict(title='Test Title', comment=comment)
732
 
    >>> filebug_view = FileBugGuidedView(ubuntu, request)
733
 
    >>> filebug_view.setUpFields()
734
 
    >>> filebug_view.setUpWidgets()
735
 
    >>> filebug_view.validate(bug_data)
736
 
    >>> print filebug_view.getFieldError('comment')
737
 
    <BLANKLINE>
738
 
 
739
 
Supplying a comment that is too long causes a validation error:
740
 
 
741
 
    >>> comment = 'x' * 50001
742
 
    >>> bug_data = dict(title='Test Title', comment=comment)
743
 
    >>> filebug_view = FileBugGuidedView(ubuntu, request)
744
 
    >>> filebug_view.setUpFields()
745
 
    >>> filebug_view.setUpWidgets()
746
 
    >>> filebug_view.validate(bug_data)
747
 
    >>> print filebug_view.getFieldError('comment')
748
 
    The description is too long...