Merge lp:~leonardr/launchpad/temporary-integration into lp:launchpad/db-devel

Proposed by Leonard Richardson
Status: Merged
Merged at revision: 9918
Proposed branch: lp:~leonardr/launchpad/temporary-integration
Merge into: lp:launchpad/db-devel
Prerequisite: lp:~leonardr/launchpad/oauth-doctest-to-unit-test
Diff against target: 9423 lines (+1894/-1015)
400 files modified
buildout-templates/bin/kill-test-services.in (+1/-3)
lib/canonical/database/ftests/test_multitablecopy.txt (+1/-1)
lib/canonical/launchpad/browser/ftests/logintoken-corner-cases.txt (+3/-3)
lib/canonical/launchpad/browser/oauth.py (+96/-21)
lib/canonical/launchpad/components/tests/decoratedresultset.txt (+1/-1)
lib/canonical/launchpad/doc/account.txt (+5/-3)
lib/canonical/launchpad/doc/announcement-date-widget.txt (+1/-1)
lib/canonical/launchpad/doc/batch_navigation.txt (+1/-1)
lib/canonical/launchpad/doc/canonical_url.txt (+1/-1)
lib/canonical/launchpad/doc/canonical_url_examples.txt (+8/-5)
lib/canonical/launchpad/doc/checkbox-matrix-widget.txt (+5/-2)
lib/canonical/launchpad/doc/emailauthentication.txt (+1/-1)
lib/canonical/launchpad/doc/feeds.txt (+1/-1)
lib/canonical/launchpad/doc/gpg-encryption.txt (+1/-1)
lib/canonical/launchpad/doc/gpghandler.txt (+4/-2)
lib/canonical/launchpad/doc/hasowner-authorization.txt (+2/-2)
lib/canonical/launchpad/doc/hierarchical-menu.txt (+3/-3)
lib/canonical/launchpad/doc/launchpad-container.txt (+2/-2)
lib/canonical/launchpad/doc/launchpad-target-widget.txt (+3/-3)
lib/canonical/launchpad/doc/launchpadform.txt (+2/-2)
lib/canonical/launchpad/doc/lazr-js-widgets.txt (+1/-1)
lib/canonical/launchpad/doc/librarian.txt (+4/-4)
lib/canonical/launchpad/doc/location-widget.txt (+1/-1)
lib/canonical/launchpad/doc/logintoken-pages.txt (+1/-1)
lib/canonical/launchpad/doc/logintoken.txt (+3/-3)
lib/canonical/launchpad/doc/looptuner.txt (+1/-1)
lib/canonical/launchpad/doc/lower-case-text-widget.txt (+2/-2)
lib/canonical/launchpad/doc/menus.txt (+3/-3)
lib/canonical/launchpad/doc/message.txt (+3/-2)
lib/canonical/launchpad/doc/navigation.txt (+1/-1)
lib/canonical/launchpad/doc/new-line-to-spaces-widget.txt (+1/-1)
lib/canonical/launchpad/doc/notification-recipient-set.txt (+1/-1)
lib/canonical/launchpad/doc/notification-text-escape.txt (+1/-1)
lib/canonical/launchpad/doc/oauth-pages.txt (+27/-5)
lib/canonical/launchpad/doc/oauth.txt (+5/-0)
lib/canonical/launchpad/doc/object-privacy.txt (+3/-2)
lib/canonical/launchpad/doc/package-relationship.txt (+1/-1)
lib/canonical/launchpad/doc/presenting-lengths-of-time.txt (+1/-1)
lib/canonical/launchpad/doc/project-scope-widget.txt (+2/-2)
lib/canonical/launchpad/doc/security-proxies.txt (+2/-2)
lib/canonical/launchpad/doc/signedmessage.txt (+2/-2)
lib/canonical/launchpad/doc/sqlobject-security-proxies.txt (+2/-2)
lib/canonical/launchpad/doc/storm.txt (+11/-4)
lib/canonical/launchpad/doc/stripped-text-widget.txt (+1/-1)
lib/canonical/launchpad/doc/textsearching.txt (+2/-2)
lib/canonical/launchpad/doc/timeout.txt (+3/-3)
lib/canonical/launchpad/doc/tokens-text-widget.txt (+1/-1)
lib/canonical/launchpad/doc/validation.txt (+7/-6)
lib/canonical/launchpad/doc/vocabularies.txt (+6/-4)
lib/canonical/launchpad/doc/webapp-authorization.txt (+2/-2)
lib/canonical/launchpad/doc/webapp-publication.txt (+5/-5)
lib/canonical/launchpad/doc/webservice-configuration.txt (+1/-1)
lib/canonical/launchpad/doc/webservice-marshallers.txt (+6/-4)
lib/canonical/launchpad/doc/xmlrpc-authserver.txt (+4/-2)
lib/canonical/launchpad/interfaces/ftests/validation.txt (+5/-4)
lib/canonical/launchpad/pagetests/feeds/xx-links.txt (+5/-2)
lib/canonical/launchpad/pagetests/oauth/access-token.txt (+4/-3)
lib/canonical/launchpad/pagetests/oauth/authorize-token.txt (+168/-29)
lib/canonical/launchpad/pagetests/oauth/managing-tokens.txt (+3/-2)
lib/canonical/launchpad/pagetests/standalone/xx-opstats.txt (+1/-1)
lib/canonical/launchpad/pagetests/standalone/xx-request-expired.txt (+1/-1)
lib/canonical/launchpad/pagetests/standalone/xx-soft-timeout.txt (+1/-1)
lib/canonical/launchpad/pagetests/webservice/xx-service.txt (+1/-1)
lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt (+1/-1)
lib/canonical/launchpad/templates/oauth-authorize.pt (+49/-29)
lib/canonical/launchpad/templates/token-authorized.pt (+60/-14)
lib/canonical/launchpad/webapp/ftests/test_adapter_timeout.txt.disabled (+2/-2)
lib/canonical/launchpad/webapp/tests/test_preferredcharsets.txt (+1/-1)
lib/canonical/launchpad/webapp/tests/test_request_expire_render.txt (+1/-1)
lib/canonical/lazr/doc/menus.txt (+2/-2)
lib/canonical/lazr/doc/timeout.txt (+1/-1)
lib/lp/answers/browser/tests/views.txt (+2/-2)
lib/lp/answers/doc/emailinterface.txt.disabled (+2/-2)
lib/lp/answers/doc/expiration.txt (+2/-2)
lib/lp/answers/doc/faq-vocabulary.txt (+2/-2)
lib/lp/answers/doc/faq.txt (+2/-2)
lib/lp/answers/doc/faqtarget.txt (+1/-1)
lib/lp/answers/doc/notifications.txt (+2/-2)
lib/lp/answers/doc/person.txt (+1/-1)
lib/lp/answers/doc/projectgroup.txt (+1/-1)
lib/lp/answers/doc/question.txt (+3/-3)
lib/lp/answers/doc/questionsets.txt (+1/-1)
lib/lp/answers/doc/questiontarget.txt (+1/-1)
lib/lp/answers/doc/workflow.txt (+1/-1)
lib/lp/answers/stories/distribution-package-answer-contact.txt (+2/-2)
lib/lp/answers/tests/questiontarget-sourcepackage.txt (+1/-1)
lib/lp/app/browser/tests/base-layout.txt (+1/-1)
lib/lp/app/browser/tests/launchpadform-view.txt (+2/-2)
lib/lp/app/doc/tales.txt (+3/-3)
lib/lp/app/stories/basics/xx-beta-testers-redirection.txt (+2/-2)
lib/lp/archivepublisher/tests/archive-signing.txt (+1/-1)
lib/lp/archivepublisher/tests/publishing-meta-data-files.txt (+2/-2)
lib/lp/archiveuploader/tests/nascentupload-announcements.txt (+5/-4)
lib/lp/archiveuploader/tests/nascentupload-closing-bugs.txt (+3/-2)
lib/lp/archiveuploader/tests/nascentupload-packageset.txt (+5/-4)
lib/lp/archiveuploader/tests/nascentupload.txt (+5/-5)
lib/lp/archiveuploader/tests/upload-karma.txt (+2/-2)
lib/lp/archiveuploader/tests/uploadpolicy.txt (+2/-2)
lib/lp/blueprints/doc/spec-mail-exploder.txt (+1/-1)
lib/lp/blueprints/doc/specgraph.txt (+1/-1)
lib/lp/blueprints/doc/specification-branch.txt (+1/-1)
lib/lp/blueprints/doc/specification-notifications.txt (+1/-1)
lib/lp/blueprints/doc/specification.txt (+2/-2)
lib/lp/blueprints/doc/sprint-agenda.txt (+1/-1)
lib/lp/blueprints/doc/sprint-meeting-export.txt (+2/-2)
lib/lp/blueprints/doc/sprint.txt (+3/-3)
lib/lp/blueprints/stories/sprints/20-sprint-registration.txt (+1/-1)
lib/lp/bugs/browser/tests/bug-nomination-views.txt (+1/-1)
lib/lp/bugs/browser/tests/bug-views.txt (+13/-4)
lib/lp/bugs/browser/tests/buglinktarget-views.txt (+3/-2)
lib/lp/bugs/browser/tests/bugs-views.txt (+2/-2)
lib/lp/bugs/browser/tests/bugtask-adding-views.txt (+3/-3)
lib/lp/bugs/browser/tests/bugtask-edit-views.txt (+3/-3)
lib/lp/bugs/browser/tests/bugtask-search-views.txt (+3/-3)
lib/lp/bugs/browser/tests/distrosourcepackage-bug-views.txt (+2/-2)
lib/lp/bugs/browser/tests/person-bug-views.txt (+1/-1)
lib/lp/bugs/doc/bug-change.txt (+1/-1)
lib/lp/bugs/doc/bug-export.txt (+4/-3)
lib/lp/bugs/doc/bug-nomination.txt (+1/-1)
lib/lp/bugs/doc/bug-private-by-default.txt (+3/-2)
lib/lp/bugs/doc/bug-reported-acknowledgement.txt (+3/-2)
lib/lp/bugs/doc/bug-reporting-guidelines.txt (+3/-2)
lib/lp/bugs/doc/bug-set-status.txt (+2/-2)
lib/lp/bugs/doc/bug-tags.txt (+3/-3)
lib/lp/bugs/doc/bug.txt (+1/-1)
lib/lp/bugs/doc/bugactivity.txt (+8/-4)
lib/lp/bugs/doc/bugattachments.txt (+9/-4)
lib/lp/bugs/doc/bugcomment.txt (+1/-1)
lib/lp/bugs/doc/bugmessage-visibility.txt (+1/-1)
lib/lp/bugs/doc/bugnotification-email.txt (+12/-5)
lib/lp/bugs/doc/bugnotification-sending.txt (+3/-3)
lib/lp/bugs/doc/bugnotification-threading.txt (+1/-1)
lib/lp/bugs/doc/bugnotificationrecipients.txt (+2/-2)
lib/lp/bugs/doc/bugnotifications.txt (+11/-6)
lib/lp/bugs/doc/bugsubscription.txt (+5/-3)
lib/lp/bugs/doc/bugtarget.txt (+3/-2)
lib/lp/bugs/doc/bugtask-bugwatch-widget.txt (+1/-1)
lib/lp/bugs/doc/bugtask-expiration.txt (+7/-4)
lib/lp/bugs/doc/bugtask-find-similar.txt (+4/-3)
lib/lp/bugs/doc/bugtask-package-widget.txt (+1/-1)
lib/lp/bugs/doc/bugtask-retrieval.txt (+4/-2)
lib/lp/bugs/doc/bugtask-search.txt (+14/-7)
lib/lp/bugs/doc/bugtask-status-workflow.txt (+3/-2)
lib/lp/bugs/doc/bugtask.txt (+7/-5)
lib/lp/bugs/doc/bugtracker.txt (+3/-3)
lib/lp/bugs/doc/bugwatch.txt (+13/-8)
lib/lp/bugs/doc/bugwidget.txt (+1/-1)
lib/lp/bugs/doc/bugzilla-import.txt (+3/-2)
lib/lp/bugs/doc/checkwatches-batching.txt (+1/-1)
lib/lp/bugs/doc/checkwatches-cli-switches.txt (+1/-1)
lib/lp/bugs/doc/checkwatches.txt (+6/-7)
lib/lp/bugs/doc/displaying-bugs-and-tasks.txt (+6/-4)
lib/lp/bugs/doc/externalbugtracker-bug-imports.txt (+3/-3)
lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt (+1/-1)
lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt (+1/-1)
lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt (+2/-2)
lib/lp/bugs/doc/externalbugtracker-bugzilla.txt (+4/-3)
lib/lp/bugs/doc/externalbugtracker-comment-imports.txt (+8/-5)
lib/lp/bugs/doc/externalbugtracker-comment-pushing.txt (+9/-7)
lib/lp/bugs/doc/externalbugtracker-debbugs.txt (+7/-5)
lib/lp/bugs/doc/externalbugtracker-emailaddress.txt (+5/-2)
lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt (+1/-1)
lib/lp/bugs/doc/externalbugtracker-mantis.txt (+3/-3)
lib/lp/bugs/doc/externalbugtracker-roundup.txt (+3/-3)
lib/lp/bugs/doc/externalbugtracker-rt.txt (+6/-5)
lib/lp/bugs/doc/externalbugtracker-sourceforge.txt (+3/-3)
lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt (+5/-3)
lib/lp/bugs/doc/externalbugtracker-trac.txt (+4/-4)
lib/lp/bugs/doc/externalbugtracker.txt (+1/-1)
lib/lp/bugs/doc/hasbugs.txt (+6/-3)
lib/lp/bugs/doc/initial-bug-contacts.txt (+1/-1)
lib/lp/bugs/doc/malone-karma.txt (+8/-4)
lib/lp/bugs/doc/malone-xmlrpc.txt (+7/-5)
lib/lp/bugs/doc/official-bug-tags.txt (+3/-3)
lib/lp/bugs/doc/security-teams.txt (+4/-4)
lib/lp/bugs/doc/sourceforge-remote-products.txt (+1/-1)
lib/lp/bugs/stories/bug-privacy/40-unsubscribe-from-private-bug.txt (+4/-3)
lib/lp/bugs/stories/bug-tags/xx-official-bug-tags.txt (+12/-1)
lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt (+1/-1)
lib/lp/bugs/stories/bugs/xx-bug-nomination-table-row.txt (+1/-1)
lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt (+3/-2)
lib/lp/bugs/stories/bugs/xx-front-page-bug-lists.txt (+5/-2)
lib/lp/bugs/stories/bugs/xx-incomplete-bugs.txt (+1/-1)
lib/lp/bugs/stories/bugs/xx-portlets-bug-milestones.txt (+1/-1)
lib/lp/bugs/stories/bugs/xx-remote-bug-comments.txt (+1/-1)
lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt (+3/-2)
lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt (+3/-2)
lib/lp/bugs/stories/bugtask-searches/xx-searching-by-tags.txt (+3/-2)
lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt (+1/-1)
lib/lp/bugs/stories/cve/cve-linking.txt (+1/-1)
lib/lp/bugs/stories/feeds/xx-bug-atom.txt (+1/-1)
lib/lp/bugs/stories/feeds/xx-bug-html.txt (+4/-2)
lib/lp/bugs/stories/structural-subscriptions/xx-bug-subscriptions.txt (+2/-2)
lib/lp/bugs/stories/webservice/xx-bug.txt (+1/-1)
lib/lp/bugs/tests/buglinktarget.txt (+5/-2)
lib/lp/bugs/tests/bugs-emailinterface.txt (+6/-7)
lib/lp/bugs/tests/bugtarget-questiontarget.txt (+5/-4)
lib/lp/code/browser/tests/test_branchlisting.py (+33/-0)
lib/lp/code/doc/branch-merge-proposal-notifications.txt (+4/-3)
lib/lp/code/doc/branch-visibility.txt (+1/-1)
lib/lp/code/doc/codeimport-event.txt (+1/-1)
lib/lp/code/doc/codeimport-job.txt (+1/-1)
lib/lp/code/doc/codeimport.txt (+2/-2)
lib/lp/code/model/branch.py (+2/-1)
lib/lp/code/model/branchmergeproposal.py (+6/-0)
lib/lp/code/model/tests/test_branchmergeproposal.py (+48/-4)
lib/lp/code/model/tests/test_branchmergeproposaljobs.py (+5/-3)
lib/lp/code/stories/branches/xx-branch-deletion.txt (+1/-1)
lib/lp/code/stories/branches/xx-branch-index.txt (+2/-2)
lib/lp/code/stories/branches/xx-branchmergeproposal-listings.txt (+1/-1)
lib/lp/code/stories/branches/xx-branchmergeproposals.txt (+2/-2)
lib/lp/code/stories/branches/xx-creating-branches.txt (+2/-2)
lib/lp/code/stories/branches/xx-private-branch-listings.txt (+1/-1)
lib/lp/code/stories/branches/xx-project-branches.txt (+4/-2)
lib/lp/code/stories/codeimport/xx-failing-codeimport.txt (+1/-1)
lib/lp/code/stories/feeds/xx-revision-atom.txt (+1/-1)
lib/lp/code/stories/webservice/xx-branch.txt (+1/-1)
lib/lp/code/templates/branch-index.pt (+11/-8)
lib/lp/code/templates/branch-information.pt (+1/-1)
lib/lp/code/templates/branch-related-bugs-specs.pt (+5/-1)
lib/lp/code/templates/project-branches.pt (+27/-2)
lib/lp/code/tests/test_project.py (+36/-0)
lib/lp/coop/answersbugs/stories/question-buglink.txt (+1/-1)
lib/lp/coop/answersbugs/tests/notifications-linked-bug.txt (+2/-2)
lib/lp/hardwaredb/doc/hwdb-device-tables.txt (+4/-2)
lib/lp/hardwaredb/doc/hwdb-submission.txt (+1/-1)
lib/lp/hardwaredb/doc/hwdb.txt (+8/-6)
lib/lp/registry/browser/tests/coc-views.txt (+1/-1)
lib/lp/registry/browser/tests/milestone-views.txt (+2/-2)
lib/lp/registry/browser/tests/peoplemerge-views.txt (+1/-1)
lib/lp/registry/browser/tests/person-admin-views.txt (+1/-1)
lib/lp/registry/browser/tests/person-views.txt (+2/-4)
lib/lp/registry/browser/tests/pillar-views.txt (+2/-2)
lib/lp/registry/browser/tests/poll-views_0.txt (+2/-2)
lib/lp/registry/browser/tests/private-team-creation-views.txt (+4/-2)
lib/lp/registry/browser/tests/product-portlet-packages-view.txt (+5/-3)
lib/lp/registry/browser/tests/product-views.txt (+2/-2)
lib/lp/registry/browser/tests/team-views.txt (+20/-12)
lib/lp/registry/configure.zcml (+4/-1)
lib/lp/registry/doc/announcement.txt (+4/-2)
lib/lp/registry/doc/commercialsubscription.txt (+2/-2)
lib/lp/registry/doc/distribution-mirror.txt (+13/-5)
lib/lp/registry/doc/distribution-sourcepackage.txt (+3/-3)
lib/lp/registry/doc/distribution.txt (+3/-6)
lib/lp/registry/doc/distroseries.txt (+11/-10)
lib/lp/registry/doc/entitlement.txt (+10/-5)
lib/lp/registry/doc/featuredproject.txt (+4/-3)
lib/lp/registry/doc/gpg-signatures.txt (+1/-1)
lib/lp/registry/doc/gpgkey.txt (+5/-2)
lib/lp/registry/doc/irc.txt (+1/-1)
lib/lp/registry/doc/jabber.txt (+1/-1)
lib/lp/registry/doc/karmacache.txt (+3/-3)
lib/lp/registry/doc/karmacontext.txt (+4/-2)
lib/lp/registry/doc/mailinglist-subscriptions-xmlrpc.txt (+2/-2)
lib/lp/registry/doc/mailinglists.txt (+5/-3)
lib/lp/registry/doc/mentoringoffer.txt (+8/-5)
lib/lp/registry/doc/message-holds.txt (+1/-1)
lib/lp/registry/doc/milestone.txt (+6/-5)
lib/lp/registry/doc/person-account.txt (+3/-3)
lib/lp/registry/doc/person-karma.txt (+5/-3)
lib/lp/registry/doc/person-notification.txt (+1/-1)
lib/lp/registry/doc/person.txt (+15/-10)
lib/lp/registry/doc/personlocation.txt (+2/-2)
lib/lp/registry/doc/pillar-aliases-field.txt (+1/-1)
lib/lp/registry/doc/pillar.txt (+6/-5)
lib/lp/registry/doc/poll-preconditions.txt (+1/-1)
lib/lp/registry/doc/poll.txt (+6/-2)
lib/lp/registry/doc/product-widgets.txt (+2/-2)
lib/lp/registry/doc/product.txt (+5/-2)
lib/lp/registry/doc/productrelease-file-download.txt (+3/-3)
lib/lp/registry/doc/productseries.txt (+7/-4)
lib/lp/registry/doc/projectgroup.txt (+4/-2)
lib/lp/registry/doc/sshkey.txt (+5/-2)
lib/lp/registry/doc/standing.txt (+6/-4)
lib/lp/registry/doc/structural-subscriptions.txt (+5/-5)
lib/lp/registry/doc/team-nav-menus.txt (+3/-3)
lib/lp/registry/doc/teammembership-email-notification.txt (+8/-4)
lib/lp/registry/doc/teammembership.txt (+5/-3)
lib/lp/registry/doc/user-to-user.txt (+1/-1)
lib/lp/registry/doc/wikiname.txt (+1/-1)
lib/lp/registry/interfaces/projectgroup.py (+7/-0)
lib/lp/registry/model/projectgroup.py (+9/-0)
lib/lp/registry/stories/announcements/xx-announcements.txt (+4/-2)
lib/lp/registry/stories/distributionmirror/xx-distribution-countrymirrors.txt (+2/-2)
lib/lp/registry/stories/gpg-coc/01-claimgpg.txt (+2/-2)
lib/lp/registry/stories/gpg-coc/04-reactivategpg.txt (+1/-1)
lib/lp/registry/stories/gpg-coc/11-handle-special-keys.txt (+1/-1)
lib/lp/registry/stories/mailinglists/lifecycle.txt (+1/-1)
lib/lp/registry/stories/mailinglists/subscriptions.txt (+2/-2)
lib/lp/registry/stories/person/xx-person-editgpgkeys-invalid-key.txt (+3/-3)
lib/lp/registry/stories/pillar/xx-pillar-deactivation.txt (+2/-2)
lib/lp/registry/stories/productrelease/xx-productrelease-basics.txt (+1/-1)
lib/lp/registry/stories/team/xx-adminteammerge.txt (+1/-1)
lib/lp/registry/stories/team/xx-team-membership.txt (+2/-2)
lib/lp/registry/stories/teammembership/10-join-team.txt (+1/-1)
lib/lp/registry/stories/teammembership/xx-expire-subscription.txt (+1/-1)
lib/lp/registry/stories/teammembership/xx-member-renewed-membership.txt (+5/-2)
lib/lp/registry/stories/vouchers/xx-voucher-redemption.txt (+1/-1)
lib/lp/registry/stories/webservice/xx-distribution-mirror.txt (+1/-1)
lib/lp/registry/stories/webservice/xx-distribution.txt (+1/-1)
lib/lp/registry/stories/webservice/xx-person.txt (+1/-1)
lib/lp/registry/stories/webservice/xx-private-team.txt (+1/-1)
lib/lp/registry/templates/team-members.pt (+5/-0)
lib/lp/registry/tests/structural-subscription-target.txt (+1/-2)
lib/lp/services/fields/doc/uri-field.txt (+2/-2)
lib/lp/services/inlinehelp/README.txt (+3/-3)
lib/lp/services/mail/tests/incomingmail.txt (+2/-2)
lib/lp/services/mailman/doc/batching.txt (+1/-1)
lib/lp/services/mailman/doc/bounces.txt (+1/-1)
lib/lp/services/mailman/doc/postings.txt (+2/-2)
lib/lp/services/mailman/doc/recovery.txt (+4/-2)
lib/lp/services/mailman/doc/staging.txt (+1/-1)
lib/lp/services/mailman/doc/subscriptions.txt (+2/-2)
lib/lp/services/memcache/doc/tales-cache.txt (+2/-2)
lib/lp/soyuz/browser/tests/binarypackagerelease-views.txt (+2/-2)
lib/lp/soyuz/browser/tests/build-views.txt (+1/-1)
lib/lp/soyuz/browser/tests/builder-views.txt (+2/-2)
lib/lp/soyuz/browser/tests/distroseriesqueue-views.txt (+2/-2)
lib/lp/soyuz/browser/tests/sourcepackage-views.txt (+1/-1)
lib/lp/soyuz/doc/archive-files.txt (+1/-1)
lib/lp/soyuz/doc/archivepermission.txt (+3/-2)
lib/lp/soyuz/doc/binarypackagebuild.txt (+3/-3)
lib/lp/soyuz/doc/binarypackagerelease.txt (+7/-6)
lib/lp/soyuz/doc/buildd-dispatching.txt (+1/-1)
lib/lp/soyuz/doc/buildd-scoring.txt (+2/-3)
lib/lp/soyuz/doc/buildd-slavescanner.txt (+2/-2)
lib/lp/soyuz/doc/closing-bugs-from-changelogs.txt (+2/-2)
lib/lp/soyuz/doc/components-and-sections.txt (+3/-3)
lib/lp/soyuz/doc/distribution.txt (+2/-2)
lib/lp/soyuz/doc/distroarchseries.txt (+5/-6)
lib/lp/soyuz/doc/distroarchseriesbinarypackage.txt (+5/-6)
lib/lp/soyuz/doc/distroseries-publishing-lookups.txt (+2/-2)
lib/lp/soyuz/doc/distroseriesqueue-dist-upgrader.txt (+1/-1)
lib/lp/soyuz/doc/distroseriesqueue-notify.txt (+1/-1)
lib/lp/soyuz/doc/distroseriesqueue-translations.txt (+2/-2)
lib/lp/soyuz/doc/distroseriesqueue.txt (+8/-9)
lib/lp/soyuz/doc/fakepackager.txt (+2/-2)
lib/lp/soyuz/doc/gina-multiple-arch.txt (+1/-1)
lib/lp/soyuz/doc/manage-chroot.txt (+1/-1)
lib/lp/soyuz/doc/package-diff.txt (+5/-5)
lib/lp/soyuz/doc/package-meta-classes.txt (+2/-3)
lib/lp/soyuz/doc/packagecopyrequest.txt (+3/-3)
lib/lp/soyuz/doc/pocketchroot.txt (+1/-1)
lib/lp/soyuz/doc/publishing.txt (+16/-12)
lib/lp/soyuz/doc/queuebuilder.txt (+1/-1)
lib/lp/soyuz/doc/sourcepackagerelease-build-lookup.txt (+2/-2)
lib/lp/soyuz/doc/sourcepackagerelease.txt (+6/-5)
lib/lp/soyuz/doc/soyuz-files.txt (+7/-4)
lib/lp/soyuz/doc/soyuz-set-of-uploads.txt (+6/-4)
lib/lp/soyuz/doc/soyuz-upload.txt (+11/-5)
lib/lp/soyuz/stories/ppa/xx-copy-packages.txt (+2/-2)
lib/lp/soyuz/stories/ppa/xx-delete-packages.txt (+3/-2)
lib/lp/soyuz/stories/ppa/xx-ppa-files.txt (+1/-1)
lib/lp/soyuz/stories/ppa/xx-ppa-packages.txt (+1/-2)
lib/lp/soyuz/stories/ppa/xx-private-ppa-subscriptions.txt (+1/-1)
lib/lp/soyuz/stories/soyuz/xx-builds-pages.txt (+2/-2)
lib/lp/soyuz/stories/soyuz/xx-distribution-archives.txt (+1/-2)
lib/lp/soyuz/stories/soyuz/xx-package-diff.txt (+4/-4)
lib/lp/soyuz/stories/soyuz/xx-person-packages.txt (+2/-2)
lib/lp/soyuz/stories/soyuz/xx-private-builds.txt (+2/-2)
lib/lp/soyuz/stories/soyuz/xx-queue-pages-delayed-copies.txt (+1/-1)
lib/lp/soyuz/stories/soyuz/xx-queue-pages-motu.txt (+3/-2)
lib/lp/soyuz/stories/soyuz/xx-queue-pages.txt (+4/-4)
lib/lp/soyuz/stories/webservice/xx-archive.txt (+1/-1)
lib/lp/soyuz/stories/webservice/xx-archivedependency.txt (+1/-1)
lib/lp/soyuz/stories/webservice/xx-binary-package-publishing.txt (+1/-1)
lib/lp/soyuz/stories/webservice/xx-builds.txt (+3/-3)
lib/lp/soyuz/stories/webservice/xx-packageupload.txt (+2/-2)
lib/lp/soyuz/stories/webservice/xx-source-package-publishing.txt (+5/-5)
lib/lp/translations/browser/tests/pofile-base-views.txt (+1/-1)
lib/lp/translations/browser/tests/pofile-views.txt (+3/-3)
lib/lp/translations/browser/tests/potemplate-views.txt (+2/-2)
lib/lp/translations/browser/tests/translationimportqueue-views.txt (+1/-1)
lib/lp/translations/browser/tests/translationmessage-views.txt (+3/-3)
lib/lp/translations/doc/language-pack.txt (+1/-1)
lib/lp/translations/doc/poexport-language-pack.txt (+3/-3)
lib/lp/translations/doc/poexport-request-productseries.txt (+1/-1)
lib/lp/translations/doc/pofile.txt (+3/-3)
lib/lp/translations/doc/poimport.txt (+1/-1)
lib/lp/translations/doc/potemplate.txt (+1/-1)
lib/lp/translations/doc/potmsgset.txt (+3/-3)
lib/lp/translations/doc/rosetta-karma.txt (+1/-1)
lib/lp/translations/doc/translationimportqueue.txt (+1/-1)
lib/lp/translations/doc/translationmessage-destroy.txt (+1/-1)
lib/lp/translations/doc/translationmessage.txt (+1/-1)
lib/lp/translations/doc/translations-export-to-branch.txt (+1/-1)
lib/lp/translations/doc/translationsoverview.txt (+2/-2)
lib/lp/translations/doc/translationtemplatesbuildbehavior.txt (+1/-1)
lib/lp/translations/stories/buildfarm/xx-build-summary.txt (+1/-1)
lib/lp/translations/stories/productseries/xx-productseries-translations.txt (+1/-1)
lib/lp/translations/stories/standalone/xx-pofile-translate-message-filtering.txt (+1/-1)
lib/lp/translations/stories/standalone/xx-potemplate-edit.txt (+1/-1)
lib/lp/translations/stories/standalone/xx-sourcepackage-export.txt (+2/-2)
lib/lp/translations/stories/standalone/xx-translation-access-display.txt (+1/-1)
lib/lp/translations/stories/standalone/xx-translationmessage-translate.txt (+1/-1)
lib/lp/translations/stories/translationgroups/30-show-group-translation-targets.txt (+2/-2)
lib/lp/translations/stories/translationgroups/60-translation-suggestions.txt (+2/-2)
lib/lp/translations/tests/potmsgset-update-translation.txt (+1/-1)
utilities/migrater/deglob.py (+161/-2)
utilities/migrater/find.py (+30/-28)
To merge this branch: bzr merge lp:~leonardr/launchpad/temporary-integration
Reviewer Review Type Date Requested Status
Curtis Hovey (community) ui Approve
Guilherme Salgado (community) ui* Approve
Māris Fogels (community) Approve
Review via email: mp+38836@code.launchpad.net

Description of the change

For the first time, this branch makes it possible to create an OAuth access token with an expiration date. The feature is only available for a "desktop integration" type token, and it's intended to allow the end-user to try out desktop integration or temporarily enable access to their Launchpad account on someone else's computer.

When you go to authorize a "desktop integration" OAuth request token, you'll be presented with the normal "allow" and "deny" actions, but you'll also have "one hour", "one day" and "one week" actions. These actions are the same as the "allow" action, but they have a "duration" set, which is transformed into an expiration date when that action is processed.

The expiration date is stored in IOAuthRequestToken.date_expires, and copied over when the token is approved.

Note that it's possible to have more than one "desktop integration" token for a given computer name. In real life, this will only happen if you gave more than one computer the same name. (This does happen, though; someone might have two computers both called "ubuntu" or "localhost".)

To post a comment you must log in.
Revision history for this message
Māris Fogels (mars) wrote :

Hi Leonard,

This code looks good. r=mars.

I have some comments about the language in the OAuth UI: I prefer the wording of "Give all programs on this computer access..." over the phrase "Permanently integrate". Similarly, I prefer the wording of "I'd like to allow access for a day" over "I'd like to try the integration for a day". "Integration" is a very technical term. In contrast, the statement "I would like to do X for a day" sounds very concrete.

I suggest getting a review of the UI text for this. I ask because I have found that OAuth screens are a particularly important place to have good usability as they deal with security and the user's fragile confidence. Also, a screenshot with the UI text would help whomever does the usability review.

Maris

review: Approve
Revision history for this message
Leonard Richardson (leonardr) wrote :

Asking for a UI review. Specific questions for the UI reviewer:

* Wording of the buttons, as flagged by Maris.
* Is the expiration text okay? If you choose a one-week trial it prints a date, eg. "The integration you just authorized will expire 2010-10-26." A little awkward, but not ungrammatical.

Revision history for this message
Curtis Hovey (sinzui) wrote :

I would like Salgado to review the UI. The screencap URL is at https://pastebin.canonical.com/38817/

review: Abstain (ui)
Revision history for this message
Guilherme Salgado (salgado) wrote :

Hi Leonard,

Here are a few suggestions that could help improve things a bit. Given that most of them are wording-related, I'd like Matt Revell to review them as he might have other suggestions.

- Where does the "Ubuntu desktop" part come from? I don't think there's
  anything restricting that page only to Ubuntu desktops, so users of other
  distros might feel either left out or compelled to click "No, thanks".

- I think the heading and the first sentence should make it clear that this
  will give any application on that computer full access to their Launchpad
  account. I say that because the heading just talks about integration, which
  might lead people to think it's something else.

  Maybe we could use something similar to what U1 uses: "Confirm Computer
  Access" as the heading and "Would you like to give all applications running
  on <mycomputer> full access (including making changes) to your Launchpad
  account?"

- I agree with Maris that the word of the buttons should be changed to make
  it clear the user is granting the computer full access to their LP
  account. Also, we can probably avoid the repetition in the buttons by doing
  something like this:

    Allow "mycomputer" to Access my Launchpad Account
        [ Permanently ]
        [ For One Hour ]
        [ For One Day ]
        [ For One Week ]

    Do Not Allow "mycomputer" to Access my Launchpad Account

- Buttons should be Headling Case
  (https://dev.launchpad.net/UserInterfaceWording)

review: Needs Fixing (ui*)
Revision history for this message
Leonard Richardson (leonardr) wrote :

"Ubuntu desktop" comes from a string provided by the client. Users of other distros will see different strings.

Revision history for this message
Leonard Richardson (leonardr) wrote :

I'd also appreciate some advice on how to group the action buttons into two sets. Should I just put two Actions objects into the context, "allow_actions" and "deny_action"?

Revision history for this message
Curtis Hovey (sinzui) wrote :

Why does the page look unstyled? I expect to see the text to use the Ubuntu font. The text lines are difficult to read because of their length. Launchpad's CSS sets the max-width: 45em.

Revision history for this message
Guilherme Salgado (salgado) wrote :

On Wed, 2010-10-20 at 13:04 +0000, Leonard Richardson wrote:
> I'd also appreciate some advice on how to group the action buttons
> into two sets. Should I just put two Actions objects into the context,
> "allow_actions" and "deny_action"?

Why do you want them in two sets?

I think that to render the buttons like I proposed you'll need to do so
manually. You'd still define all your @action methods normally but then
in your template you fill the "buttons" slot and layout the buttons as
you want.

Revision history for this message
Leonard Richardson (leonardr) wrote :

The *screenshot* looks unstyled because the easiest way for me to take a screenshot was to write the HTML file to disk during a test run and view it locally. The page is a normal Launchpad page and when viewed as part of a running Launchpad instance it will be styled.

I don't understand "in your template you fill the "buttons" slot and layout the buttons as you want". Currently I have this code:

<div metal:fill-slot="buttons" />

As I understand it, this invokes some kind of macro that takes my Actions object and automagically lays out the buttons, one per column.

Are you suggesting something like this?

<div metal fill-slot="buttons">

  Allow "mycomputer" to Access my Launchpad Account

 <div class="indented" id="do-integrate">
  <input type="button" name="Permanently" />
  <input type="button" name="One hour" />
  <input type="button" name="One day" />
  <input type="button" name="One week" />
 </div>

 <!--Note: no "indented" div here-->
  <input type="button" name="Don't integrate" />
</div>

That is, I'm trying to get this effect:

  Allow "mycomputer" to Access my Launchpad Account
        [ Permanently ]
        [ For One Hour ]
        [ For One Day ]
        [ For One Week ]

    Do Not Allow "mycomputer" to Access my Launchpad Account

But I have no idea how to do this, either on the level of the CSS styling or the level of the PT templates. I would prefer not to lay out all four of the "yes, i want to integrate" buttons manually--that's why I suggested having two Actions objects.

Can you help me?

Revision history for this message
Curtis Hovey (sinzui) wrote :

On Wed, 2010-10-20 at 15:13 +0000, Leonard Richardson wrote:
> <div metal fill-slot="buttons">
>
> Allow "mycomputer" to Access my Launchpad Account
>
> <div class="indented" id="do-integrate">
> <input type="button" name="Permanently" />
> <input type="button" name="One hour" />
> <input type="button" name="One day" />
> <input type="button" name="One week" />
> </div>
>
> <!--Note: no "indented" div here-->
> <input type="button" name="Don't integrate" />
> </div>

The question-index.pt template renders its button manually:

            <div class="actions" metal:fill-slot="buttons">
              <div>
                <input tal:replace="structure view/answer_action/render" />
                <input tal:replace="structure view/selfanswer_action/render" />
                <input tal:replace="structure view/requestinfo_action/render" />
                <input tal:replace="structure view/giveinfo_action/render" />
                <input tal:replace="structure view/reopen_action/render" />
                <input tal:replace="structure view/comment_action/render" />
              </div>

I think you want to add some structure around the buttons to group them.
You will need <br/> or wrap each is a <div> to create the vertical list.

Revision history for this message
Guilherme Salgado (salgado) wrote :
review: Approve (ui*)
Revision history for this message
Curtis Hovey (sinzui) wrote :

On IRC we tried a 6th layout and discussed capitalisation. We agreed 6 was a little better than 5.

review: Approve (ui)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'buildout-templates/bin/kill-test-services.in'
2--- buildout-templates/bin/kill-test-services.in 2010-04-20 19:10:35 +0000
3+++ buildout-templates/bin/kill-test-services.in 2010-10-21 19:08:55 +0000
4@@ -19,8 +19,7 @@
5 import sys
6
7 from canonical.testing.layers import MemcachedLayer
8-from canonical.librarian.ftests.harness import (
9- LibrarianTestSetup, TacLibrarianTestSetup)
10+from canonical.librarian.testing.server import LibrarianTestSetup
11 from lp.services.osutils import kill_by_pidfile
12
13
14@@ -32,7 +31,6 @@
15 kill_by_pidfile(MemcachedLayer.getPidFile())
16 print "done."
17 print "Killing Librarian....",
18- TacLibrarianTestSetup().tearDown()
19 LibrarianTestSetup().tearDownRoot()
20 print "done."
21 return 0
22
23=== modified file 'lib/canonical/database/ftests/test_multitablecopy.txt'
24--- lib/canonical/database/ftests/test_multitablecopy.txt 2008-05-19 15:24:34 +0000
25+++ lib/canonical/database/ftests/test_multitablecopy.txt 2010-10-21 19:08:55 +0000
26@@ -5,8 +5,8 @@
27
28 >>> import transaction
29 >>> from canonical.database import postgresql
30+ >>> from canonical.database.multitablecopy import MultiTableCopy
31 >>> from canonical.database.sqlbase import cursor
32- >>> from canonical.database.multitablecopy import MultiTableCopy
33
34 >>> # Keep track of tables we'll want to clean up later
35 >>> tables_to_clean_up = []
36
37=== modified file 'lib/canonical/launchpad/browser/ftests/logintoken-corner-cases.txt'
38--- lib/canonical/launchpad/browser/ftests/logintoken-corner-cases.txt 2010-10-03 15:30:06 +0000
39+++ lib/canonical/launchpad/browser/ftests/logintoken-corner-cases.txt 2010-10-21 19:08:55 +0000
40@@ -11,11 +11,11 @@
41 redirect to the default token view. This would happen if for example the
42 user tried to re-post the form after validating one of their email addresses.
43
44- >>> from lp.registry.interfaces.person import IPersonSet
45- >>> from canonical.launchpad.interfaces import (
46- ... ILoginTokenSet, LoginTokenType)
47 >>> from canonical.launchpad.browser import ValidateEmailView
48+ >>> from canonical.launchpad.interfaces.authtoken import LoginTokenType
49+ >>> from canonical.launchpad.interfaces.logintoken import ILoginTokenSet
50 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
51+ >>> from lp.registry.interfaces.person import IPersonSet
52
53 >>> foo_bar = getUtility(IPersonSet).getByName('name16')
54 >>> token = getUtility(ILoginTokenSet).new(
55
56=== modified file 'lib/canonical/launchpad/browser/oauth.py'
57--- lib/canonical/launchpad/browser/oauth.py 2010-10-04 20:33:07 +0000
58+++ lib/canonical/launchpad/browser/oauth.py 2010-10-21 19:08:55 +0000
59@@ -9,12 +9,19 @@
60 'OAuthTokenAuthorizedView',
61 'lookup_oauth_context']
62
63+from datetime import (
64+ datetime,
65+ timedelta,
66+ )
67+
68 from lazr.restful import HTTPResource
69+import pytz
70 import simplejson
71 from zope.component import getUtility
72 from zope.formlib.form import (
73 Action,
74 Actions,
75+ expandPrefix,
76 )
77 from zope.security.interfaces import Unauthorized
78
79@@ -63,7 +70,7 @@
80 return simplejson.dumps(structure)
81
82
83-class OAuthRequestTokenView(LaunchpadView, JSONTokenMixin):
84+class OAuthRequestTokenView(LaunchpadFormView, JSONTokenMixin):
85 """Where consumers can ask for a request token."""
86
87 def __call__(self):
88@@ -107,7 +114,21 @@
89
90 def token_review_success(form, action, data):
91 """The success callback for a button to approve a token."""
92- form.reviewToken(action.permission)
93+ form.reviewToken(action.permission, action.duration)
94+
95+
96+class TemporaryIntegrations:
97+ """Contains duration constants for temporary integrations."""
98+
99+ HOUR = "Hour"
100+ DAY = "Day"
101+ WEEK = "Week"
102+
103+ DURATION = {
104+ HOUR : 60 * 60,
105+ DAY : 60 * 60 * 24,
106+ WEEK : 60 * 60 * 24 * 7
107+ }
108
109
110 def create_oauth_permission_actions():
111@@ -115,19 +136,37 @@
112
113 The first `Actions` object contains every action supported by the
114 OAuthAuthorizeTokenView. The second list contains a good default
115- set of actions, omitting special permissions like DESKTOP_INTEGRATION.
116+ set of actions, omitting special actions like the
117+ DESKTOP_INTEGRATION ones.
118 """
119 all_actions = Actions()
120 ordinary_actions = Actions()
121+ desktop_permission = OAuthPermission.DESKTOP_INTEGRATION
122 for permission in OAuthPermission.items:
123 action = Action(
124 permission.title, name=permission.name,
125 success=token_review_success,
126 condition=token_exists_and_is_not_reviewed)
127 action.permission = permission
128+ action.duration = None
129 all_actions.append(action)
130- if permission != OAuthPermission.DESKTOP_INTEGRATION:
131+ if permission != desktop_permission:
132 ordinary_actions.append(action)
133+
134+ # Add special actions for the time-limited DESKTOP_INTEGRATION
135+ # tokens.
136+ for duration in (
137+ TemporaryIntegrations.HOUR, TemporaryIntegrations.DAY,
138+ TemporaryIntegrations.WEEK):
139+ action = Action(
140+ ("For One %s" % duration),
141+ name=expandPrefix(desktop_permission.name) + duration,
142+ success=token_review_success,
143+ condition=token_exists_and_is_not_reviewed)
144+ action.permission = desktop_permission
145+ action.duration = duration
146+ all_actions.append(action)
147+
148 return all_actions, ordinary_actions
149
150
151@@ -161,7 +200,8 @@
152 used by normal applications.
153 """
154
155- allowed_permissions = self.request.form_ng.getAll('allow_permission')
156+ allowed_permissions = set(
157+ self.request.form_ng.getAll('allow_permission'))
158 if len(allowed_permissions) == 0:
159 return self.actions_excluding_special_permissions
160 actions = Actions()
161@@ -174,9 +214,10 @@
162
163 # DESKTOP_INTEGRATION cannot be requested as one of several
164 # options--it must be the only option (other than
165- # UNAUTHORIZED). If DESKTOP_INTEGRATION is one of several
166- # options, remove it from the list.
167+ # UNAUTHORIZED). If there is any item in the list that doesn't
168+ # use DESKTOP_INTEGRATION, remove it from the list.
169 desktop_permission = OAuthPermission.DESKTOP_INTEGRATION
170+
171 if (desktop_permission.name in allowed_permissions
172 and len(allowed_permissions) > 1):
173 allowed_permissions.remove(desktop_permission.name)
174@@ -192,33 +233,40 @@
175 "the computer being integrated."
176 % self.token.consumer.key))
177
178- # We're going for desktop integration. The only two
179- # possibilities are "allow" and "deny". We'll customize
180- # the "allow" message using the hostname provided by the
181- # desktop.
182+ # We're going for desktop integration. There are four
183+ # possibilities: "allow permanently", "allow for one
184+ # hour", "allow for one day", "allow for one week", and
185+ # "deny". We'll customize the "allow permanently" and
186+ # "deny" message using the hostname provided by the
187+ # desktop. We'll use the existing Action objects for the
188+ # "temporary integration" actions, without customizing
189+ # their messages.
190 #
191 # Since self.actions is a descriptor that returns copies
192 # of Action objects, we can modify the actions we get
193 # in-place without ruining the Action objects for everyone
194 # else.
195 desktop_name = self.token.consumer.integrated_desktop_name
196- label = (
197- 'Give all programs running on &quot;%s&quot; access '
198- 'to my Launchpad account.')
199 allow_action = [
200 action for action in self.actions
201 if action.name == desktop_permission.name][0]
202- allow_action.label = label % desktop_name
203+ allow_action.label = "Until I Disable It"
204 actions.append(allow_action)
205
206- # We'll customize the "deny" message as well.
207- label = "No, thanks, I don't trust &quot;%s&quot;."
208+ # Bring in all of the temporary integration actions.
209+ for action in self.actions:
210+ if (action.permission == desktop_permission
211+ and action.name != desktop_permission.name):
212+ actions.append(action)
213+
214+ # Fionally, customize the "deny" message.
215+ label = (
216+ "Do Not Allow &quot;%s&quot; to Access my Launchpad Account.")
217 deny_action = [
218 action for action in self.actions
219 if action.name == OAuthPermission.UNAUTHORIZED.name][0]
220 deny_action.label = label % desktop_name
221 actions.append(deny_action)
222-
223 else:
224 # We're going for web-based integration.
225 for action in self.actions_excluding_special_permissions:
226@@ -237,6 +285,25 @@
227 return self.actions_excluding_special_permissions
228 return actions
229
230+ @property
231+ def visible_desktop_integration_actions(self):
232+ """Return all visible actions for DESKTOP_INTEGRATION."""
233+ actions = Actions()
234+ for action in self.visible_actions:
235+ if action.permission is OAuthPermission.DESKTOP_INTEGRATION:
236+ actions.append(action)
237+ return actions
238+
239+ @property
240+ def unauthorized_action(self):
241+ """Returns just the action for the UNAUTHORIZED permission level."""
242+ for action in self.visible_actions:
243+ if action.permission is OAuthPermission.UNAUTHORIZED:
244+ return action
245+ raise AssertionError(
246+ "UNAUTHORIZED permission level should always be visible, "
247+ "but wasn't.")
248+
249 def initialize(self):
250 self.storeTokenContext()
251 form = get_oauth_authorization(self.request)
252@@ -244,7 +311,6 @@
253 if key:
254 self.token = getUtility(IOAuthRequestTokenSet).getByKey(key)
255
256-
257 callback = self.request.form.get('oauth_callback')
258 if (self.token is not None
259 and self.token.consumer.is_integrated_desktop):
260@@ -295,8 +361,16 @@
261 raise UnexpectedFormData("Unknown context.")
262 self.token_context = context
263
264- def reviewToken(self, permission):
265- self.token.review(self.user, permission, self.token_context)
266+ def reviewToken(self, permission, duration):
267+ duration_seconds = TemporaryIntegrations.DURATION.get(duration)
268+ if duration_seconds is not None:
269+ duration_delta = timedelta(seconds=duration_seconds)
270+ expiration_date = (
271+ datetime.now(pytz.timezone('UTC')) + duration_delta)
272+ else:
273+ expiration_date = None
274+ self.token.review(self.user, permission, self.token_context,
275+ date_expires=expiration_date)
276 callback = self.request.form.get('oauth_callback')
277 if callback:
278 self.next_url = callback
279@@ -304,6 +378,7 @@
280 self.next_url = (
281 '+token-authorized?oauth_token=%s' % self.token.key)
282
283+
284 def lookup_oauth_context(context):
285 """Transform an OAuth context string into a context object.
286
287
288=== modified file 'lib/canonical/launchpad/components/tests/decoratedresultset.txt'
289--- lib/canonical/launchpad/components/tests/decoratedresultset.txt 2010-10-09 16:36:22 +0000
290+++ lib/canonical/launchpad/components/tests/decoratedresultset.txt 2010-10-21 19:08:55 +0000
291@@ -10,8 +10,8 @@
292 ResultSet:
293
294 >>> from zope.component import getUtility
295+ >>> from lp.registry.interfaces.distribution import IDistributionSet
296 >>> from storm.store import Store
297- >>> from lp.registry.interfaces.distribution import IDistributionSet
298 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
299 >>> store = Store.of(ubuntu)
300 >>> from lp.registry.model.distribution import Distribution
301
302=== modified file 'lib/canonical/launchpad/doc/account.txt'
303--- lib/canonical/launchpad/doc/account.txt 2010-10-10 15:39:28 +0000
304+++ lib/canonical/launchpad/doc/account.txt 2010-10-21 19:08:55 +0000
305@@ -126,8 +126,10 @@
306 If we add a new guessed email address, it will be included in the
307 guessed list.
308
309- >>> from canonical.launchpad.interfaces import (
310- ... EmailAddressStatus, IEmailAddressSet)
311+ >>> from canonical.launchpad.interfaces.emailaddress import (
312+ ... EmailAddressStatus,
313+ ... IEmailAddressSet,
314+ ... )
315 >>> email = getUtility(IEmailAddressSet).new(
316 ... "guessed-email@example.com", account=account,
317 ... status=EmailAddressStatus.NEW)
318@@ -294,8 +296,8 @@
319
320 # We need to change database policy here again, as the SSO Server cannot
321 # modify tables in the lpmain replication set.
322+ >>> from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy
323 >>> from canonical.launchpad.webapp.interfaces import IStoreSelector
324- >>> from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy
325 >>> getUtility(IStoreSelector).push(MasterDatabasePolicy())
326
327 >>> from lp.registry.interfaces.person import PersonCreationRationale
328
329=== modified file 'lib/canonical/launchpad/doc/announcement-date-widget.txt'
330--- lib/canonical/launchpad/doc/announcement-date-widget.txt 2009-08-13 19:36:01 +0000
331+++ lib/canonical/launchpad/doc/announcement-date-widget.txt 2010-10-21 19:08:55 +0000
332@@ -4,10 +4,10 @@
333 choose to publish an announcement immediately, at a predetermined date in the
334 future, or to manually publish it later.
335
336+ >>> from zope.schema import Field
337 >>> from canonical.launchpad.testing.pages import extract_text
338 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
339 >>> from canonical.widgets.announcementdate import AnnouncementDateWidget
340- >>> from zope.schema import Field
341 >>> field = Field(__name__='foo', title=u'Foo')
342 >>> widget = AnnouncementDateWidget(field, LaunchpadTestRequest())
343 >>> print extract_text(widget())
344
345=== modified file 'lib/canonical/launchpad/doc/batch_navigation.txt'
346--- lib/canonical/launchpad/doc/batch_navigation.txt 2010-10-09 16:36:22 +0000
347+++ lib/canonical/launchpad/doc/batch_navigation.txt 2010-10-21 19:08:55 +0000
348@@ -55,8 +55,8 @@
349
350 Imports and initialization:
351
352+ >>> from canonical.ftests.pgsql import CursorWrapper
353 >>> from canonical.launchpad.database import EmailAddress
354- >>> from canonical.ftests.pgsql import CursorWrapper
355 >>> from canonical.launchpad.interfaces.lpstorm import IStore
356 >>> ignore = IStore(EmailAddress) # Prime the database connection.
357 ... # (Priming is important if this test is run in isolation).
358
359=== modified file 'lib/canonical/launchpad/doc/canonical_url.txt'
360--- lib/canonical/launchpad/doc/canonical_url.txt 2010-10-09 16:36:22 +0000
361+++ lib/canonical/launchpad/doc/canonical_url.txt 2010-10-21 19:08:55 +0000
362@@ -502,8 +502,8 @@
363
364 >>> from zope.app.security.principalregistry import (
365 ... UnauthenticatedPrincipal)
366+ >>> from canonical.launchpad.webapp.interaction import setupInteraction
367 >>> from canonical.launchpad.webapp.servers import WebServiceTestRequest
368- >>> from canonical.launchpad.webapp.interaction import setupInteraction
369 >>> from lazr.restful.utils import get_current_browser_request
370 >>> anonymous = UnauthenticatedPrincipal(None, None, None)
371 >>> api_request = WebServiceTestRequest()
372
373=== modified file 'lib/canonical/launchpad/doc/canonical_url_examples.txt'
374--- lib/canonical/launchpad/doc/canonical_url_examples.txt 2010-10-11 16:17:45 +0000
375+++ lib/canonical/launchpad/doc/canonical_url_examples.txt 2010-10-21 19:08:55 +0000
376@@ -52,8 +52,11 @@
377
378 == Persons and Teams ==
379
380- >>> from canonical.launchpad.interfaces import (
381- ... IPersonSet, ICodeOfConductSet, ISignedCodeOfConductSet)
382+ >>> from lp.registry.interfaces.codeofconduct import (
383+ ... ICodeOfConductSet,
384+ ... ISignedCodeOfConductSet,
385+ ... )
386+ >>> from lp.registry.interfaces.person import IPersonSet
387
388 The IPersonSet.
389
390@@ -133,8 +136,8 @@
391
392 == Projects groups and products ==
393
394- >>> from canonical.launchpad.interfaces import (
395- ... IProjectGroupSet, IProductSet)
396+ >>> from lp.registry.interfaces.product import IProductSet
397+ >>> from lp.registry.interfaces.projectgroup import IProjectGroupSet
398
399 The IProjectGroupSet.
400
401@@ -289,8 +292,8 @@
402
403 == Remote Bug Trackers and Remote Bugs ==
404
405+ >>> from lp.bugs.browser.bugtracker import RemoteBug
406 >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
407- >>> from lp.bugs.browser.bugtracker import RemoteBug
408
409 An IBugTrackerSet.
410
411
412=== modified file 'lib/canonical/launchpad/doc/checkbox-matrix-widget.txt'
413--- lib/canonical/launchpad/doc/checkbox-matrix-widget.txt 2010-10-03 15:30:06 +0000
414+++ lib/canonical/launchpad/doc/checkbox-matrix-widget.txt 2010-10-21 19:08:55 +0000
415@@ -10,8 +10,11 @@
416
417 >>> from BeautifulSoup import BeautifulSoup
418 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
419- >>> from canonical.launchpad.interfaces import (
420- ... IProduct, IProductSet, License)
421+ >>> from lp.registry.interfaces.product import (
422+ ... IProduct,
423+ ... IProductSet,
424+ ... License,
425+ ... )
426 >>> product = getUtility(IProductSet).get(1)
427 >>> licenses_field = IProduct['licenses'].bind(product)
428 >>> vtype = licenses_field.value_type
429
430=== modified file 'lib/canonical/launchpad/doc/emailauthentication.txt'
431--- lib/canonical/launchpad/doc/emailauthentication.txt 2010-10-15 15:20:39 +0000
432+++ lib/canonical/launchpad/doc/emailauthentication.txt 2010-10-21 19:08:55 +0000
433@@ -37,9 +37,9 @@
434 user in the launch bag:
435
436 >>> import email
437+ >>> from zope.component import getUtility
438 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
439 >>> from lp.registry.interfaces.person import IPersonSet
440- >>> from zope.component import getUtility
441 >>> launchbag = getUtility(ILaunchBag)
442 >>> name, addr = email.Utils.parseaddr(msg['From'])
443 >>> from_user = getUtility(IPersonSet).getByEmail(addr)
444
445=== modified file 'lib/canonical/launchpad/doc/feeds.txt'
446--- lib/canonical/launchpad/doc/feeds.txt 2009-08-05 18:52:52 +0000
447+++ lib/canonical/launchpad/doc/feeds.txt 2010-10-21 19:08:55 +0000
448@@ -108,8 +108,8 @@
449 by browsers and the reverse-proxy in front of the feeds servers.
450
451 >>> from canonical.config import config
452+ >>> from canonical.lazr.feed.feed import FeedBase
453 >>> from lp.bugs.feed.bug import BugsFeedBase
454- >>> from canonical.lazr.feed.feed import FeedBase
455 >>> config.launchpad.max_feed_cache_minutes
456 60
457 >>> config.launchpad.max_bug_feed_cache_minutes
458
459=== modified file 'lib/canonical/launchpad/doc/gpg-encryption.txt'
460--- lib/canonical/launchpad/doc/gpg-encryption.txt 2010-10-09 16:36:22 +0000
461+++ lib/canonical/launchpad/doc/gpg-encryption.txt 2010-10-21 19:08:55 +0000
462@@ -15,8 +15,8 @@
463
464 Sample Person has public and secret keys set.
465
466+ >>> from zope.component import getUtility
467 >>> from canonical.launchpad.ftests import login
468- >>> from zope.component import getUtility
469 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
470
471 >>> bag = getUtility(ILaunchBag)
472
473=== modified file 'lib/canonical/launchpad/doc/gpghandler.txt'
474--- lib/canonical/launchpad/doc/gpghandler.txt 2010-10-03 15:30:06 +0000
475+++ lib/canonical/launchpad/doc/gpghandler.txt 2010-10-21 19:08:55 +0000
476@@ -25,8 +25,10 @@
477 >>> from zope.component import getUtility
478 >>> from canonical.launchpad.webapp.testing import verifyObject
479
480- >>> from canonical.launchpad.interfaces import (
481- ... IGPGHandler, IPymeKey)
482+ >>> from canonical.launchpad.interfaces.gpghandler import (
483+ ... IGPGHandler,
484+ ... IPymeKey,
485+ ... )
486 >>> gpghandler = getUtility(IGPGHandler)
487
488 -------------------------------------------------------------------------
489
490=== modified file 'lib/canonical/launchpad/doc/hasowner-authorization.txt'
491--- lib/canonical/launchpad/doc/hasowner-authorization.txt 2010-01-12 14:52:41 +0000
492+++ lib/canonical/launchpad/doc/hasowner-authorization.txt 2010-10-21 19:08:55 +0000
493@@ -5,8 +5,8 @@
494
495 # First we define a class which only provides IHasOwner.
496 >>> from zope.interface import implements
497+ >>> from lp.registry.interfaces.person import IPersonSet
498 >>> from lp.registry.interfaces.role import IHasOwner
499- >>> from lp.registry.interfaces.person import IPersonSet
500 >>> salgado = getUtility(IPersonSet).getByName('salgado')
501 >>> class FooObject:
502 ... implements(IHasOwner)
503@@ -15,8 +15,8 @@
504 Salgado is the owner of any FooObject we create, so he can edit it.
505
506 >>> foo = FooObject()
507+ >>> from zope.component import queryAdapter
508 >>> from canonical.launchpad.webapp.interfaces import IAuthorization
509- >>> from zope.component import queryAdapter
510 >>> authorization = queryAdapter(foo, IAuthorization, 'launchpad.Edit')
511 >>> print authorization.checkAccountAuthenticated(salgado.account)
512 True
513
514=== modified file 'lib/canonical/launchpad/doc/hierarchical-menu.txt'
515--- lib/canonical/launchpad/doc/hierarchical-menu.txt 2010-07-27 12:42:00 +0000
516+++ lib/canonical/launchpad/doc/hierarchical-menu.txt 2010-10-21 19:08:55 +0000
517@@ -22,8 +22,8 @@
518 >>> class ICooker(Interface):
519 ... """A cooker."""
520
521+ >>> from canonical.launchpad.webapp.interfaces import ICanonicalUrlData
522 >>> from canonical.launchpad.webapp.url import urlappend
523- >>> from canonical.launchpad.webapp.interfaces import ICanonicalUrlData
524
525 >>> class BaseContent:
526 ... implements(ICanonicalUrlData)
527@@ -83,8 +83,8 @@
528 IBreadcrumb adapters are registered for them. The hierarchy builds a list of
529 breadcrumbs starting with the breadcrumb closest to the hierarchy root.
530
531+ >>> from canonical.launchpad.browser.launchpad import Hierarchy
532 >>> from canonical.launchpad.webapp.breadcrumb import Breadcrumb
533- >>> from canonical.launchpad.browser.launchpad import Hierarchy
534
535 # Monkey patch Hierarchy.makeBreadcrumbForRequestedPage so that we don't
536 # have to create fake views and other stuff to test breadcrumbs here. The
537@@ -174,8 +174,8 @@
538 context. The default adapter provides the url attribute, but the breadcrumb's
539 text must be overriden in subclasses.
540
541- >>> from canonical.launchpad.webapp.interfaces import IBreadcrumb
542 >>> from zope.interface.verify import verifyObject
543+ >>> from canonical.launchpad.webapp.interfaces import IBreadcrumb
544 >>> breadcrumb = Breadcrumb(cookbook)
545 >>> verifyObject(IBreadcrumb, breadcrumb)
546 True
547
548=== modified file 'lib/canonical/launchpad/doc/launchpad-container.txt'
549--- lib/canonical/launchpad/doc/launchpad-container.txt 2009-06-12 16:36:02 +0000
550+++ lib/canonical/launchpad/doc/launchpad-container.txt 2010-10-21 19:08:55 +0000
551@@ -7,8 +7,8 @@
552 that we have an easy way of finding whether or not any given object is
553 within the scope of a token's context and grant or deny access to it.
554
555+ >>> from canonical.launchpad.webapp.interfaces import ILaunchpadContainer
556 >>> from canonical.launchpad.webapp.testing import verifyObject
557- >>> from canonical.launchpad.webapp.interfaces import ILaunchpadContainer
558 >>> from lp.registry.interfaces.product import IProductSet
559 >>> from lp.registry.interfaces.distribution import (
560 ... IDistributionSet)
561@@ -80,8 +80,8 @@
562 Bugs are associated to our pillars through their bug tasks, so a bug is
563 said to be within any of its bugtasks' targets.
564
565+ >>> from lp.bugs.interfaces.bug import IBugSet
566 >>> from operator import attrgetter
567- >>> from lp.bugs.interfaces.bug import IBugSet
568 >>> bug_1 = getUtility(IBugSet).get(1)
569 >>> bugtasks = bug_1.bugtasks
570 >>> targets = [task.target for task in bug_1.bugtasks]
571
572=== modified file 'lib/canonical/launchpad/doc/launchpad-target-widget.txt'
573--- lib/canonical/launchpad/doc/launchpad-target-widget.txt 2010-10-09 16:36:22 +0000
574+++ lib/canonical/launchpad/doc/launchpad-target-widget.txt 2010-10-21 19:08:55 +0000
575@@ -3,10 +3,10 @@
576 The general +filebug allows bugs to be filed on any product or package,
577 and to help with this, the LaunchpadTargetWidget is used.
578
579+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
580 >>> from canonical.launchpad.webapp.testing import verifyObject
581+ >>> from canonical.widgets.launchpadtarget import LaunchpadTargetWidget
582 >>> from lp.bugs.interfaces.bug import IFrontPageBugAddForm
583- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
584- >>> from canonical.widgets.launchpadtarget import LaunchpadTargetWidget
585
586 >>> empty_request = LaunchpadTestRequest()
587 >>> widget = LaunchpadTargetWidget(
588@@ -14,8 +14,8 @@
589
590 The widget complies to both IInputWidget and IBrowserWidget.
591
592+ >>> from zope.app.form.browser.interfaces import IBrowserWidget
593 >>> from zope.app.form.interfaces import IInputWidget
594- >>> from zope.app.form.browser.interfaces import IBrowserWidget
595 >>> verifyObject(IInputWidget, widget)
596 True
597 >>> verifyObject(IBrowserWidget, widget)
598
599=== modified file 'lib/canonical/launchpad/doc/launchpadform.txt'
600--- lib/canonical/launchpad/doc/launchpadform.txt 2009-06-12 16:36:02 +0000
601+++ lib/canonical/launchpad/doc/launchpadform.txt 2010-10-21 19:08:55 +0000
602@@ -131,8 +131,8 @@
603 attribute:
604
605 >>> from zope.app.form.browser import TextWidget
606+ >>> from canonical.launchpad.webapp import custom_widget
607 >>> from canonical.widgets import PasswordChangeWidget
608- >>> from canonical.launchpad.webapp import custom_widget
609
610 >>> class FormTestView3(LaunchpadFormView):
611 ... schema = IFormTest
612@@ -469,9 +469,9 @@
613 First we'll create a fake pagetemplate which doesn't use Launchpad's main
614 template and thus is way simpler.
615
616- >>> from z3c.ptcompat import ViewPageTemplateFile
617 >>> from StringIO import StringIO
618 >>> from tempfile import mkstemp
619+ >>> from z3c.ptcompat import ViewPageTemplateFile
620 >>> file, filename = mkstemp()
621 >>> f = open(filename, 'w')
622 >>> f.write(u'<div metal:use-macro="context/@@launchpad_form/form" />')
623
624=== modified file 'lib/canonical/launchpad/doc/lazr-js-widgets.txt'
625--- lib/canonical/launchpad/doc/lazr-js-widgets.txt 2010-10-09 16:36:22 +0000
626+++ lib/canonical/launchpad/doc/lazr-js-widgets.txt 2010-10-21 19:08:55 +0000
627@@ -82,8 +82,8 @@
628 The InlineEditPickerWidget can be used for any interface attribute that
629 has a vocabulary defined for it.
630
631+ >>> from zope.component import getUtility
632 >>> from canonical.widgets.lazrjs import InlineEditPickerWidget
633- >>> from zope.component import getUtility
634 >>> from lp.bugs.interfaces.bugtask import IBugTask, IBugTaskSet
635 >>> bugtask = getUtility(IBugTaskSet).get(2)
636 >>> def create_inline_edit_picker_widget():
637
638=== modified file 'lib/canonical/launchpad/doc/librarian.txt'
639--- lib/canonical/launchpad/doc/librarian.txt 2010-10-10 15:39:28 +0000
640+++ lib/canonical/launchpad/doc/librarian.txt 2010-10-21 19:08:55 +0000
641@@ -28,8 +28,8 @@
642
643 == High Level ==
644
645+ >>> from StringIO import StringIO
646 >>> from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
647- >>> from StringIO import StringIO
648 >>> data = 'This is some data'
649
650 We can create LibraryFileAliases using the ILibraryFileAliasSet utility.
651@@ -118,8 +118,8 @@
652 However, we can force the use of HTTP by setting the 'HTTP_X_SCHEME'
653 header in the request to 'http', even when 'use_https' is True.
654
655+ >>> from zope.component import getMultiAdapter
656 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
657- >>> from zope.component import getMultiAdapter
658 >>> from urlparse import urlparse
659 >>> request = LaunchpadTestRequest(
660 ... environ={'REQUEST_METHOD': 'GET',
661@@ -573,9 +573,9 @@
662
663 XXX bug=631884 we have to establish the flags object manually for testing.
664
665+ >>> from lp.services.features import per_thread
666+ >>> from lp.services.features.flags import FeatureController
667 >>> from lp.services.features.webapp import ScopesFromRequest
668- >>> from lp.services.features.flags import FeatureController
669- >>> from lp.services.features import per_thread
670 >>> per_thread.features = FeatureController(
671 ... ScopesFromRequest(empty_request).lookup)
672
673
674=== modified file 'lib/canonical/launchpad/doc/location-widget.txt'
675--- lib/canonical/launchpad/doc/location-widget.txt 2010-09-21 04:21:16 +0000
676+++ lib/canonical/launchpad/doc/location-widget.txt 2010-10-21 19:08:55 +0000
677@@ -3,9 +3,9 @@
678 A widget used when setting the geographic location of a given person.
679
680 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
681+ >>> from canonical.widgets.location import LocationWidget
682 >>> from lp.registry.interfaces.person import IPersonSet
683 >>> from lp.services.fields import LocationField
684- >>> from canonical.widgets.location import LocationWidget
685 >>> salgado = getUtility(IPersonSet).getByName('salgado')
686 >>> field = LocationField(__name__='location', title=u'Location')
687
688
689=== modified file 'lib/canonical/launchpad/doc/logintoken-pages.txt'
690--- lib/canonical/launchpad/doc/logintoken-pages.txt 2010-10-03 15:30:06 +0000
691+++ lib/canonical/launchpad/doc/logintoken-pages.txt 2010-10-21 19:08:55 +0000
692@@ -21,8 +21,8 @@
693 >>> from canonical.launchpad.interfaces.authtoken import LoginTokenType
694 >>> from canonical.launchpad.interfaces.logintoken import (
695 ... ILoginTokenSet)
696+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
697 >>> from lp.registry.model.person import PersonSet
698- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
699
700 # To simplify our tests we'll use the PersonSet() class directly instead
701 # of gettint it as a zope secured utility. If we don't do that we'd have
702
703=== modified file 'lib/canonical/launchpad/doc/logintoken.txt'
704--- lib/canonical/launchpad/doc/logintoken.txt 2009-05-12 01:39:29 +0000
705+++ lib/canonical/launchpad/doc/logintoken.txt 2010-10-21 19:08:55 +0000
706@@ -18,12 +18,12 @@
707 4) The token is now marked as consumed, together with any other
708 tokens of the same type and for the same email address.
709
710+ >>> from canonical.launchpad.interfaces.authtoken import LoginTokenType
711 >>> from lp.registry.model.person import Person
712- >>> from canonical.launchpad.interfaces.authtoken import LoginTokenType
713 >>> from canonical.launchpad.interfaces.logintoken import (
714 ... ILoginTokenSet)
715+ >>> from canonical.database.sqlbase import flush_database_updates
716 >>> from lp.services.mail import stub
717- >>> from canonical.database.sqlbase import flush_database_updates
718 >>> import transaction
719 >>> foobar = Person.byName('name16')
720
721@@ -96,8 +96,8 @@
722 our own making.
723
724 >>> import pytz
725+ >>> from zope.security.proxy import removeSecurityProxy
726 >>> from datetime import datetime
727- >>> from zope.security.proxy import removeSecurityProxy
728
729 >>> token = removeSecurityProxy(token)
730 >>> token.date_consumed = datetime(
731
732=== modified file 'lib/canonical/launchpad/doc/looptuner.txt'
733--- lib/canonical/launchpad/doc/looptuner.txt 2010-04-07 15:57:55 +0000
734+++ lib/canonical/launchpad/doc/looptuner.txt 2010-10-21 19:08:55 +0000
735@@ -20,8 +20,8 @@
736
737 >>> import math
738 >>> from zope.interface import implements
739+ >>> from canonical.launchpad.interfaces.looptuner import ITunableLoop
740 >>> from canonical.launchpad.utilities.looptuner import LoopTuner
741- >>> from canonical.launchpad.interfaces.looptuner import ITunableLoop
742
743 The LoopTuner requires the operation you define for it to implement the
744 ITunableLoop interface.
745
746=== modified file 'lib/canonical/launchpad/doc/lower-case-text-widget.txt'
747--- lib/canonical/launchpad/doc/lower-case-text-widget.txt 2010-10-09 16:36:22 +0000
748+++ lib/canonical/launchpad/doc/lower-case-text-widget.txt 2010-10-21 19:08:55 +0000
749@@ -7,9 +7,9 @@
750 LowerCaseTextWidget can be used to automatically convert the input to
751 lower case:
752
753+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
754+ >>> from canonical.widgets.textwidgets import LowerCaseTextWidget
755 >>> from lp.bugs.interfaces.bug import IBug
756- >>> from canonical.widgets.textwidgets import LowerCaseTextWidget
757- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
758 >>> field = IBug['description']
759 >>> request = LaunchpadTestRequest(form={'field.description':'Foo'})
760 >>> widget = LowerCaseTextWidget(field, request)
761
762=== modified file 'lib/canonical/launchpad/doc/menus.txt'
763--- lib/canonical/launchpad/doc/menus.txt 2009-10-21 17:41:20 +0000
764+++ lib/canonical/launchpad/doc/menus.txt 2010-10-21 19:08:55 +0000
765@@ -341,8 +341,8 @@
766 # We need to use a real launchpad test request so the view adapter
767 # lookups will work. That request also needs to implement
768 # IParticipation so that the login machinery will work.
769+ >>> from zope.security.interfaces import IParticipation
770 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
771- >>> from zope.security.interfaces import IParticipation
772 >>> class InteractiveTestRequest(LaunchpadTestRequest):
773 ... implements(IParticipation)
774 ... principal = None
775@@ -687,10 +687,10 @@
776 link should appear linked. The request is also set as the menu's
777 'request' attribute.
778
779+ >>> from zope.publisher.interfaces.browser import IBrowserRequest
780+ >>> from zope.publisher.interfaces.http import IHTTPApplicationRequest
781 >>> from canonical.launchpad.ftests import test_tales
782 >>> from canonical.launchpad.webapp import LaunchpadView
783- >>> from zope.publisher.interfaces.http import IHTTPApplicationRequest
784- >>> from zope.publisher.interfaces.browser import IBrowserRequest
785 >>> from canonical.launchpad.webapp.vhosts import allvhosts
786 >>> class FakeRequest:
787 ... implements(IHTTPApplicationRequest, IBrowserRequest)
788
789=== modified file 'lib/canonical/launchpad/doc/message.txt'
790--- lib/canonical/launchpad/doc/message.txt 2010-10-09 16:36:22 +0000
791+++ lib/canonical/launchpad/doc/message.txt 2010-10-21 19:08:55 +0000
792@@ -4,8 +4,9 @@
793 various parts of launchpad. Currently, it is used by Malone for comments
794 on bugs. Bugs are linked to Messages via the BugMessage table.
795
796- >>> from canonical.launchpad.interfaces import (
797- ... IBugMessageSet, IBugSet, IOpenLaunchBag)
798+ >>> from canonical.launchpad.webapp.interfaces import IOpenLaunchBag
799+ >>> from lp.bugs.interfaces.bug import IBugSet
800+ >>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
801 >>> login('foo.bar@canonical.com')
802 >>> bugmessageset = getUtility(IBugMessageSet)
803 >>> bug_one = getUtility(IBugSet).get(1)
804
805=== modified file 'lib/canonical/launchpad/doc/navigation.txt'
806--- lib/canonical/launchpad/doc/navigation.txt 2010-10-03 15:30:06 +0000
807+++ lib/canonical/launchpad/doc/navigation.txt 2010-10-21 19:08:55 +0000
808@@ -269,8 +269,8 @@
809 Once registered, we can look the navigation up using getMultiAdapter().
810
811 >>> from zope.component import getMultiAdapter
812+ >>> from zope.publisher.interfaces.browser import IBrowserPublisher
813 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
814- >>> from zope.publisher.interfaces.browser import IBrowserPublisher
815 >>> navigation = getMultiAdapter(
816 ... (thingset, LaunchpadTestRequest()), IBrowserPublisher, name='')
817
818
819=== modified file 'lib/canonical/launchpad/doc/new-line-to-spaces-widget.txt'
820--- lib/canonical/launchpad/doc/new-line-to-spaces-widget.txt 2010-10-09 16:36:22 +0000
821+++ lib/canonical/launchpad/doc/new-line-to-spaces-widget.txt 2010-10-21 19:08:55 +0000
822@@ -3,8 +3,8 @@
823
824 This custom widget is used to replace new line characters to spaces.
825
826+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
827 >>> from canonical.widgets.bugtask import NewLineToSpacesWidget
828- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
829 >>> from lp.bugs.interfaces.bugtask import IBugTaskSearch
830
831 We pass a string with some new line characters to the widget
832
833=== modified file 'lib/canonical/launchpad/doc/notification-recipient-set.txt'
834--- lib/canonical/launchpad/doc/notification-recipient-set.txt 2010-10-09 16:36:22 +0000
835+++ lib/canonical/launchpad/doc/notification-recipient-set.txt 2010-10-21 19:08:55 +0000
836@@ -15,8 +15,8 @@
837 You can use it as is or derive from it
838 (see bugnotificationrecipients.txt for an example of a derivation).
839
840+ >>> from canonical.launchpad.interfaces.launchpad import INotificationRecipientSet
841 >>> from canonical.launchpad.webapp.testing import verifyObject
842- >>> from canonical.launchpad.interfaces.launchpad import INotificationRecipientSet
843 >>> from canonical.launchpad.mailnotification import (
844 ... NotificationRecipientSet)
845
846
847=== modified file 'lib/canonical/launchpad/doc/notification-text-escape.txt'
848--- lib/canonical/launchpad/doc/notification-text-escape.txt 2008-04-16 16:28:14 +0000
849+++ lib/canonical/launchpad/doc/notification-text-escape.txt 2010-10-21 19:08:55 +0000
850@@ -41,8 +41,8 @@
851 IStructuredString interface, then a string will be returned with the
852 appropriate sections escaped and unescaped.
853
854+ >>> from canonical.launchpad.webapp.interfaces import IStructuredString
855 >>> from canonical.launchpad.webapp.menu import structured
856- >>> from canonical.launchpad.webapp.interfaces import IStructuredString
857 >>> msg = u'<b>%(escaped)s</b>'
858 >>> structured_text = structured(msg, escaped=u'<br/>foo')
859 >>> IStructuredString.providedBy(structured_text)
860
861=== modified file 'lib/canonical/launchpad/doc/oauth-pages.txt'
862--- lib/canonical/launchpad/doc/oauth-pages.txt 2009-06-12 16:36:02 +0000
863+++ lib/canonical/launchpad/doc/oauth-pages.txt 2010-10-21 19:08:55 +0000
864@@ -32,6 +32,28 @@
865 ... if tag.attrMap['value']:
866 ... print tag.attrMap['name'], tag.attrMap['value']
867
868+When the client doesn't specify a duration, the resulting request
869+token will have no expiration date set.
870+
871+ >>> from datetime import datetime
872+ >>> view, token = get_view_with_fresh_token({})
873+ >>> view.reviewToken(OAuthPermission.READ_PRIVATE, None)
874+ >>> print token.date_expires
875+ None
876+
877+When the client specifies a duration, the resulting request
878+token will have an appropriate expiration date set.
879+
880+ >>> from datetime import datetime
881+ >>> import pytz
882+ >>> from canonical.launchpad.browser.oauth import (
883+ ... TemporaryIntegrations)
884+ >>> view, token = get_view_with_fresh_token({})
885+ >>> view.reviewToken(
886+ ... OAuthPermission.READ_PRIVATE, TemporaryIntegrations.HOUR)
887+ >>> token.date_expires > datetime.now(pytz.timezone('UTC'))
888+ True
889+
890 When the consumer doesn't specify a context, the token will not have a
891 context either.
892
893@@ -45,7 +67,7 @@
894 loggingout...
895 oauth_token...
896
897- >>> view.reviewToken(OAuthPermission.READ_PRIVATE)
898+ >>> view.reviewToken(OAuthPermission.READ_PRIVATE, None)
899 >>> token.person.name
900 u'salgado'
901 >>> print token.context
902@@ -69,7 +91,7 @@
903 oauth_token...
904 lp.context firefox
905
906- >>> view.reviewToken(OAuthPermission.READ_PUBLIC)
907+ >>> view.reviewToken(OAuthPermission.READ_PUBLIC, None)
908 >>> token.context.name
909 u'firefox'
910
911@@ -86,7 +108,7 @@
912 oauth_token...
913 lp.context mozilla
914
915- >>> view.reviewToken(OAuthPermission.READ_PUBLIC)
916+ >>> view.reviewToken(OAuthPermission.READ_PUBLIC, None)
917 >>> token.context.name
918 u'mozilla'
919
920@@ -103,7 +125,7 @@
921 oauth_token...
922 lp.context ubuntu
923
924- >>> view.reviewToken(OAuthPermission.READ_PUBLIC)
925+ >>> view.reviewToken(OAuthPermission.READ_PUBLIC, None)
926 >>> token.context.name
927 u'ubuntu'
928
929@@ -122,7 +144,7 @@
930 oauth_token...
931 lp.context ubuntu/evolution
932
933- >>> view.reviewToken(OAuthPermission.READ_PUBLIC)
934+ >>> view.reviewToken(OAuthPermission.READ_PUBLIC, None)
935 >>> token.context.title
936 u'...evolution... package in Ubuntu'
937
938
939=== modified file 'lib/canonical/launchpad/doc/oauth.txt'
940--- lib/canonical/launchpad/doc/oauth.txt 2010-10-21 19:08:53 +0000
941+++ lib/canonical/launchpad/doc/oauth.txt 2010-10-21 19:08:55 +0000
942@@ -17,8 +17,13 @@
943
944 Here's a quick demonstration of the behavior.
945
946+ >>> login('foo.bar@canonical.com')
947+ >>> access_token = factory.makeOAuthAccessToken()
948+ >>> logout()
949+
950 - We can use a nonce.
951
952+ >>> from canonical.launchpad.interfaces.oauth import IOAuthNonce
953 >>> import time
954 >>> now = time.time() - 1
955 >>> nonce1 = access_token.checkNonceAndTimestamp('boo', now)
956
957=== modified file 'lib/canonical/launchpad/doc/object-privacy.txt'
958--- lib/canonical/launchpad/doc/object-privacy.txt 2010-10-03 15:30:06 +0000
959+++ lib/canonical/launchpad/doc/object-privacy.txt 2010-10-21 19:08:55 +0000
960@@ -8,8 +8,9 @@
961 IObjectPrivacy and check its is_private attribute.
962
963 >>> from canonical.lazr.interfaces import IObjectPrivacy
964- >>> from canonical.launchpad.interfaces import (
965- ... IBugSet, IPersonSet, IQuestionSet)
966+ >>> from lp.answers.interfaces.questioncollection import IQuestionSet
967+ >>> from lp.bugs.interfaces.bug import IBugSet
968+ >>> from lp.registry.interfaces.person import IPersonSet
969 >>> bug = getUtility(IBugSet).get(1)
970 >>> bug.private
971 False
972
973=== modified file 'lib/canonical/launchpad/doc/package-relationship.txt'
974--- lib/canonical/launchpad/doc/package-relationship.txt 2010-10-09 16:36:22 +0000
975+++ lib/canonical/launchpad/doc/package-relationship.txt 2010-10-21 19:08:55 +0000
976@@ -54,8 +54,8 @@
977 Now for each parsed element we can build an IPackageRelationship:
978
979 >>> from canonical.launchpad.browser import PackageRelationship
980+ >>> from canonical.launchpad.interfaces.packagerelationship import IPackageRelationship
981 >>> from canonical.launchpad.webapp.testing import verifyObject
982- >>> from canonical.launchpad.interfaces.packagerelationship import IPackageRelationship
983
984 >>> name, version, operator = parsed_relationships[1]
985 >>> fake_url = 'http://host/path'
986
987=== modified file 'lib/canonical/launchpad/doc/presenting-lengths-of-time.txt'
988--- lib/canonical/launchpad/doc/presenting-lengths-of-time.txt 2005-10-31 18:29:12 +0000
989+++ lib/canonical/launchpad/doc/presenting-lengths-of-time.txt 2010-10-21 19:08:55 +0000
990@@ -3,8 +3,8 @@
991
992 First, let's bring in some dependencies:
993
994+ >>> from canonical.launchpad.ftests import test_tales
995 >>> from datetime import timedelta
996- >>> from canonical.launchpad.ftests import test_tales
997
998 Exact Duration
999 --------------
1000
1001=== modified file 'lib/canonical/launchpad/doc/project-scope-widget.txt'
1002--- lib/canonical/launchpad/doc/project-scope-widget.txt 2010-10-09 16:36:22 +0000
1003+++ lib/canonical/launchpad/doc/project-scope-widget.txt 2010-10-21 19:08:55 +0000
1004@@ -7,9 +7,9 @@
1005 we will use the Project vocabulary which allows any project to be
1006 selected.
1007
1008- >>> from canonical.launchpad.webapp.testing import verifyObject
1009 >>> from zope.schema import Choice
1010 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
1011+ >>> from canonical.launchpad.webapp.testing import verifyObject
1012 >>> from canonical.widgets.project import ProjectScopeWidget
1013
1014 >>> empty_request = LaunchpadTestRequest()
1015@@ -21,8 +21,8 @@
1016
1017 The widget complies to both IInputWidget and IBrowserWidget.
1018
1019+ >>> from zope.app.form.browser.interfaces import IBrowserWidget
1020 >>> from zope.app.form.interfaces import IInputWidget
1021- >>> from zope.app.form.browser.interfaces import IBrowserWidget
1022 >>> verifyObject(IInputWidget, widget)
1023 True
1024 >>> verifyObject(IBrowserWidget, widget)
1025
1026=== modified file 'lib/canonical/launchpad/doc/security-proxies.txt'
1027--- lib/canonical/launchpad/doc/security-proxies.txt 2010-10-17 02:00:18 +0000
1028+++ lib/canonical/launchpad/doc/security-proxies.txt 2010-10-21 19:08:55 +0000
1029@@ -45,8 +45,8 @@
1030 XXX: bug 3315
1031 DB schema objects should be comparable correctly when proxied...
1032
1033- >>> from canonical.launchpad.interfaces import (
1034- ... SeriesStatus, IDistroSeriesSet)
1035+ >>> from lp.registry.interfaces.distroseries import IDistroSeriesSet
1036+ >>> from lp.registry.interfaces.series import SeriesStatus
1037 >>> hoary = getUtility(IDistroSeriesSet).get(3)
1038 >>> print hoary.status.name
1039 DEVELOPMENT
1040
1041=== modified file 'lib/canonical/launchpad/doc/signedmessage.txt'
1042--- lib/canonical/launchpad/doc/signedmessage.txt 2007-08-09 14:49:07 +0000
1043+++ lib/canonical/launchpad/doc/signedmessage.txt 2010-10-21 19:08:55 +0000
1044@@ -6,9 +6,9 @@
1045 SignedMessage as the _class parameter, but it also ensures that all
1046 the attributes are correctly set.
1047
1048+ >>> from canonical.launchpad.interfaces.mail import ISignedMessage
1049+ >>> from canonical.launchpad.mail import signed_message_from_string
1050 >>> from canonical.launchpad.webapp.testing import verifyObject
1051- >>> from canonical.launchpad.mail import signed_message_from_string
1052- >>> from canonical.launchpad.interfaces.mail import ISignedMessage
1053 >>> msg = signed_message_from_string('To: someone\n\nHello.')
1054 >>> verifyObject(ISignedMessage, msg)
1055 True
1056
1057=== modified file 'lib/canonical/launchpad/doc/sqlobject-security-proxies.txt'
1058--- lib/canonical/launchpad/doc/sqlobject-security-proxies.txt 2010-10-03 15:30:06 +0000
1059+++ lib/canonical/launchpad/doc/sqlobject-security-proxies.txt 2010-10-21 19:08:55 +0000
1060@@ -3,9 +3,9 @@
1061
1062 Do some imports.
1063
1064+ >>> from zope.component import getUtility
1065+ >>> from lp.bugs.model.bug import BugTask
1066 >>> from lp.registry.interfaces.person import IPersonSet
1067- >>> from lp.bugs.model.bug import BugTask
1068- >>> from zope.component import getUtility
1069
1070 Login as Mark.
1071
1072
1073=== modified file 'lib/canonical/launchpad/doc/storm.txt'
1074--- lib/canonical/launchpad/doc/storm.txt 2010-10-03 15:30:06 +0000
1075+++ lib/canonical/launchpad/doc/storm.txt 2010-10-21 19:08:55 +0000
1076@@ -6,14 +6,21 @@
1077 In addition to what Storm provides, we also have some Launchpad
1078 specific Storm tools to cope with our master and slave store arrangement.
1079
1080- >>> from canonical.launchpad.interfaces import (
1081- ... EmailAddressStatus, IEmailAddressSet,
1082- ... IMasterObject, IMasterStore, ISlaveStore, IStore)
1083+ >>> from canonical.launchpad.interfaces.emailaddress import (
1084+ ... EmailAddressStatus,
1085+ ... IEmailAddressSet,
1086+ ... )
1087+ >>> from canonical.launchpad.interfaces.lpstorm import (
1088+ ... IMasterObject,
1089+ ... IMasterStore,
1090+ ... ISlaveStore,
1091+ ... IStore,
1092+ ... )
1093 >>> from canonical.launchpad.database import (
1094 ... Account, AccountPassword, EmailAddress)
1095+ >>> from zope.security.proxy import ProxyFactory
1096 >>> from lp.registry.interfaces.person import IPersonSet
1097 >>> from lp.registry.model.person import Person
1098- >>> from zope.security.proxy import ProxyFactory
1099
1100
1101 You need to use the correct master Store to make changes to
1102
1103=== modified file 'lib/canonical/launchpad/doc/stripped-text-widget.txt'
1104--- lib/canonical/launchpad/doc/stripped-text-widget.txt 2010-10-09 16:36:22 +0000
1105+++ lib/canonical/launchpad/doc/stripped-text-widget.txt 2010-10-21 19:08:55 +0000
1106@@ -30,8 +30,8 @@
1107
1108 This custom widget is used to strip leading and trailing whitespaces.
1109
1110+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
1111 >>> from canonical.widgets.textwidgets import StrippedTextWidget
1112- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
1113 >>> from lp.bugs.interfaces.bugtracker import IRemoteBug
1114
1115 We pass a string with leading and trailing whitespaces to the widget
1116
1117=== modified file 'lib/canonical/launchpad/doc/textsearching.txt'
1118--- lib/canonical/launchpad/doc/textsearching.txt 2010-10-09 16:36:22 +0000
1119+++ lib/canonical/launchpad/doc/textsearching.txt 2010-10-21 19:08:55 +0000
1120@@ -602,8 +602,8 @@
1121 rows will be excluded from the final search.
1122
1123 >>> from canonical.database.nl_search import nl_phrase_search
1124+ >>> from canonical.database.sqlbase import quote
1125 >>> from lp.answers.model.question import Question
1126- >>> from canonical.database.sqlbase import quote
1127
1128 More than 50% of the questions matches firefox:
1129
1130@@ -689,8 +689,8 @@
1131 For example, there are less than 5 questions filed on the
1132 mozilla-firefox source package.
1133
1134+ >>> from canonical.database.sqlbase import sqlvalues
1135 >>> from lp.registry.interfaces.distribution import IDistributionSet
1136- >>> from canonical.database.sqlbase import sqlvalues
1137 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
1138 >>> firefox_package = ubuntu.getSourcePackage('mozilla-firefox')
1139 >>> firefox_package_questions = Question.select(
1140
1141=== modified file 'lib/canonical/launchpad/doc/timeout.txt'
1142--- lib/canonical/launchpad/doc/timeout.txt 2010-10-02 20:58:22 +0000
1143+++ lib/canonical/launchpad/doc/timeout.txt 2010-10-21 19:08:55 +0000
1144@@ -26,8 +26,8 @@
1145 The timeout to use is the number of seconds remaining before
1146 db_statement_timeout is expired.
1147
1148+ >>> from canonical.config import config
1149 >>> from textwrap import dedent
1150- >>> from canonical.config import config
1151 >>> config.push('timeout', dedent('''\
1152 ... [database]
1153 ... db_statement_timeout = 10000'''))
1154@@ -88,9 +88,9 @@
1155
1156 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
1157 >>> from lp.services.features.model import FeatureFlag, getFeatureStore
1158+ >>> from lp.services.features import per_thread
1159+ >>> from lp.services.features.flags import FeatureController
1160 >>> from lp.services.features.webapp import ScopesFromRequest
1161- >>> from lp.services.features.flags import FeatureController
1162- >>> from lp.services.features import per_thread
1163
1164 Install the feature flag to increase the timeout value.
1165
1166
1167=== modified file 'lib/canonical/launchpad/doc/tokens-text-widget.txt'
1168--- lib/canonical/launchpad/doc/tokens-text-widget.txt 2010-10-09 16:36:22 +0000
1169+++ lib/canonical/launchpad/doc/tokens-text-widget.txt 2010-10-21 19:08:55 +0000
1170@@ -3,8 +3,8 @@
1171 This custom widget is used to normalise the space between words,
1172 strip punctuation, and strip leading and trailing whitespace.
1173
1174+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
1175 >>> from canonical.widgets.textwidgets import TokensTextWidget
1176- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
1177 >>> from lp.answers.interfaces.faq import IFAQ
1178
1179 The IFAQ keywords field requires a space separated list of terms. In the
1180
1181=== modified file 'lib/canonical/launchpad/doc/validation.txt'
1182--- lib/canonical/launchpad/doc/validation.txt 2010-10-10 15:39:28 +0000
1183+++ lib/canonical/launchpad/doc/validation.txt 2010-10-21 19:08:55 +0000
1184@@ -7,9 +7,10 @@
1185 The validate_distrotask() function is used to guarantee that distribution
1186 bugtasks are unique per bug.
1187
1188- >>> from canonical.launchpad.interfaces import (
1189- ... IBugSet, IDistributionSet, ISourcePackageNameSet,
1190- ... validate_distrotask)
1191+ >>> from canonical.launchpad.interfaces import validate_distrotask
1192+ >>> from lp.bugs.interfaces.bug import IBugSet
1193+ >>> from lp.registry.interfaces.distribution import IDistributionSet
1194+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
1195 >>> bug_two = getUtility(IBugSet).get(2)
1196 >>> debian = getUtility(IDistributionSet).getByName('debian')
1197 >>> mozilla_firefox = getUtility(
1198@@ -31,8 +32,8 @@
1199 If the bug already has a distribution task with no source package, it's
1200 not possible to add a another one.
1201
1202- >>> from canonical.launchpad.interfaces import (
1203- ... CreateBugParams, IDistributionSet)
1204+ >>> from lp.bugs.interfaces.bug import CreateBugParams
1205+ >>> from lp.registry.interfaces.distribution import IDistributionSet
1206
1207 >>> login('no-priv@canonical.com')
1208 >>> no_priv = getUtility(ILaunchBag).user
1209@@ -57,8 +58,8 @@
1210 It's not allowed even if the sourcepackage has been published in a
1211 PPA.
1212
1213+ >>> from lp.soyuz.enums import PackagePublishingStatus
1214 >>> from lp.soyuz.tests.ppa import publishToPPA
1215- >>> from lp.soyuz.enums import PackagePublishingStatus
1216 >>> publishToPPA(
1217 ... person_name='cprov',
1218 ... sourcepackage_name='foobar',
1219
1220=== modified file 'lib/canonical/launchpad/doc/vocabularies.txt'
1221--- lib/canonical/launchpad/doc/vocabularies.txt 2010-10-09 16:36:22 +0000
1222+++ lib/canonical/launchpad/doc/vocabularies.txt 2010-10-21 19:08:55 +0000
1223@@ -10,9 +10,11 @@
1224
1225 >>> from zope.component import getUtility
1226 >>> from canonical.launchpad.ftests import ANONYMOUS, login
1227- >>> from canonical.launchpad.interfaces import (
1228- ... IPersonSet, IOpenLaunchBag, IProductSet, IProjectGroupSet)
1229 >>> from canonical.database.sqlbase import flush_database_updates
1230+ >>> from canonical.launchpad.webapp.interfaces import IOpenLaunchBag
1231+ >>> from lp.registry.interfaces.person import IPersonSet
1232+ >>> from lp.registry.interfaces.product import IProductSet
1233+ >>> from lp.registry.interfaces.projectgroup import IProjectGroupSet
1234 >>> person_set = getUtility(IPersonSet)
1235 >>> product_set = getUtility(IProductSet)
1236 >>> login('foo.bar@canonical.com')
1237@@ -395,8 +397,8 @@
1238 Bug watches with an email address URL (i.e. starts with "mailto:") are
1239 treated differently.
1240
1241- >>> from canonical.launchpad.interfaces import (
1242- ... IBugWatchSet, IBugTrackerSet)
1243+ >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
1244+ >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
1245
1246 >>> bug_twelve = getUtility(IBugSet).get(12)
1247 >>> email_bugtracker = getUtility(IBugTrackerSet).getByName('email')
1248
1249=== modified file 'lib/canonical/launchpad/doc/webapp-authorization.txt'
1250--- lib/canonical/launchpad/doc/webapp-authorization.txt 2010-10-18 10:11:04 +0000
1251+++ lib/canonical/launchpad/doc/webapp-authorization.txt 2010-10-21 19:08:55 +0000
1252@@ -5,8 +5,8 @@
1253 given object. This is the same check available in TALES as
1254 something/required:permission.Name.
1255
1256+ >>> from zope.component import getUtility
1257 >>> from canonical.launchpad.webapp.authorization import check_permission
1258- >>> from zope.component import getUtility
1259 >>> from lp.registry.interfaces.person import IPersonSet
1260
1261 >>> personset = getUtility(IPersonSet)
1262@@ -60,8 +60,8 @@
1263 access to private objects. For instance, the above principal has
1264 permission to read private and non-private objects (READ_PRIVATE).
1265
1266+ >>> from canonical.launchpad.ftests import syncUpdate
1267 >>> from lp.bugs.interfaces.bug import IBugSet
1268- >>> from canonical.launchpad.ftests import syncUpdate
1269 >>> login('test@canonical.com')
1270 >>> bug_1 = getUtility(IBugSet).get(1)
1271 >>> bug_1.setPrivate(True, sample_person)
1272
1273=== modified file 'lib/canonical/launchpad/doc/webapp-publication.txt'
1274--- lib/canonical/launchpad/doc/webapp-publication.txt 2010-10-09 16:36:22 +0000
1275+++ lib/canonical/launchpad/doc/webapp-publication.txt 2010-10-21 19:08:55 +0000
1276@@ -144,8 +144,8 @@
1277 ... LaunchpadBrowserPublication)
1278 >>> from canonical.launchpad.webapp.servers import (
1279 ... LaunchpadBrowserRequest, VirtualHostRequestPublicationFactory)
1280+ >>> from zope.app.publication.interfaces import IRequestPublicationFactory
1281 >>> from canonical.launchpad.webapp.testing import verifyObject
1282- >>> from zope.app.publication.interfaces import IRequestPublicationFactory
1283
1284 Those factories provide the IRequestPublicationFactory interface.
1285
1286@@ -909,10 +909,10 @@
1287 In the default implementation, the following database modification will
1288 be automatically reverted in a GET request.
1289
1290+ >>> from canonical.launchpad.database import EmailAddress
1291 >>> from canonical.launchpad.ftests import syncUpdate
1292- >>> from canonical.launchpad.database import EmailAddress
1293+ >>> from canonical.launchpad.interfaces.lpstorm import IMasterStore
1294 >>> from lp.registry.model.person import Person
1295- >>> from canonical.launchpad.interfaces.lpstorm import IMasterStore
1296 >>> login('foo.bar@canonical.com')
1297 >>> txn = transaction.begin()
1298 >>> def get_foo_bar_person():
1299@@ -965,13 +965,13 @@
1300 the OAuthNonce table.
1301
1302 >>> import time
1303+ >>> from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
1304 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission
1305 >>> from lp.registry.interfaces.person import IPersonSet
1306- >>> from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
1307
1308+ >>> from zope.component import getUtility
1309 >>> from canonical.launchpad.webapp.dbpolicy import MasterDatabasePolicy
1310 >>> from canonical.launchpad.webapp.interfaces import IStoreSelector
1311- >>> from zope.component import getUtility
1312 >>> getUtility(IStoreSelector).push(MasterDatabasePolicy())
1313
1314 >>> salgado = getUtility(IPersonSet).getByName('salgado')
1315
1316=== modified file 'lib/canonical/launchpad/doc/webservice-configuration.txt'
1317--- lib/canonical/launchpad/doc/webservice-configuration.txt 2009-04-17 10:32:16 +0000
1318+++ lib/canonical/launchpad/doc/webservice-configuration.txt 2010-10-21 19:08:55 +0000
1319@@ -24,8 +24,8 @@
1320 based on the site configuration and whether the requesting user is a
1321 developer.
1322
1323+ >>> from canonical.config import config
1324 >>> from textwrap import dedent
1325- >>> from canonical.config import config
1326
1327 >>> from zope.interface import implements
1328 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
1329
1330=== modified file 'lib/canonical/launchpad/doc/webservice-marshallers.txt'
1331--- lib/canonical/launchpad/doc/webservice-marshallers.txt 2010-10-09 16:36:22 +0000
1332+++ lib/canonical/launchpad/doc/webservice-marshallers.txt 2010-10-21 19:08:55 +0000
1333@@ -8,8 +8,10 @@
1334 application root.
1335
1336 >>> from canonical.launchpad.webapp.adapter import set_request_started
1337- >>> from canonical.launchpad.webapp.servers import WebServiceTestRequest
1338- >>> from canonical.launchpad.webapp.servers import WebServicePublication
1339+ >>> from canonical.launchpad.webapp.servers import (
1340+ ... WebServicePublication,
1341+ ... WebServiceTestRequest,
1342+ ... )
1343 >>> request = WebServiceTestRequest(method='GET')
1344 >>> set_request_started()
1345 >>> request.setPublication(WebServicePublication(None))
1346@@ -29,12 +31,12 @@
1347 string is a URL corresponding to a vocabulary item, the marshaller
1348 returns that item. Otherwise it raises a ValueError.
1349
1350- >>> from lp.registry.interfaces.person import IPerson
1351 >>> from zope.component import getMultiAdapter
1352 >>> from zope.schema import Choice
1353+ >>> from lazr.restful import EntryResource
1354 >>> from lazr.restful.fields import ReferenceChoice
1355 >>> from lazr.restful.interfaces import IFieldMarshaller
1356- >>> from lazr.restful import EntryResource
1357+ >>> from lp.registry.interfaces.person import IPerson
1358
1359 # Bind the field, to resolve the vocabulary name.
1360 >>> field = ReferenceChoice(
1361
1362=== modified file 'lib/canonical/launchpad/doc/xmlrpc-authserver.txt'
1363--- lib/canonical/launchpad/doc/xmlrpc-authserver.txt 2010-10-03 15:30:06 +0000
1364+++ lib/canonical/launchpad/doc/xmlrpc-authserver.txt 2010-10-21 19:08:55 +0000
1365@@ -3,8 +3,10 @@
1366 The AuthServer interface is available on the authserver attribute
1367 of our private XMLRPC instance.
1368
1369- >>> from canonical.launchpad.interfaces import (
1370- ... IAuthServerApplication, IPrivateApplication)
1371+ >>> from canonical.launchpad.interfaces.launchpad import (
1372+ ... IAuthServerApplication,
1373+ ... IPrivateApplication,
1374+ ... )
1375 >>> from canonical.launchpad.webapp.testing import verifyObject
1376
1377 >>> private_root = getUtility(IPrivateApplication)
1378
1379=== modified file 'lib/canonical/launchpad/interfaces/ftests/validation.txt'
1380--- lib/canonical/launchpad/interfaces/ftests/validation.txt 2010-10-03 15:30:06 +0000
1381+++ lib/canonical/launchpad/interfaces/ftests/validation.txt 2010-10-21 19:08:55 +0000
1382@@ -1,16 +1,17 @@
1383 = Launchpad field validators =
1384
1385 >>> from zope.component import getUtility
1386- >>> from canonical.launchpad.interfaces import (
1387- ... CreateBugParams, IOpenLaunchBag, IPersonSet, IProductSet)
1388+ >>> from canonical.launchpad.webapp.interfaces import IOpenLaunchBag
1389+ >>> from lp.bugs.interfaces.bug import CreateBugParams
1390+ >>> from lp.registry.interfaces.person import IPersonSet
1391+ >>> from lp.registry.interfaces.product import IProductSet
1392
1393 == can_be_nominated_for_series ==
1394
1395 This validator is used to check if the bug in the launchbag can be
1396 nominated for the given series.
1397
1398- >>> from canonical.launchpad.interfaces import (
1399- ... can_be_nominated_for_series)
1400+ >>> from canonical.launchpad.interfaces import can_be_nominated_for_series
1401
1402 If we create a new bug, all the target's series can be nominated.
1403
1404
1405=== modified file 'lib/canonical/launchpad/pagetests/feeds/xx-links.txt'
1406--- lib/canonical/launchpad/pagetests/feeds/xx-links.txt 2010-10-03 15:30:06 +0000
1407+++ lib/canonical/launchpad/pagetests/feeds/xx-links.txt 2010-10-21 19:08:55 +0000
1408@@ -116,8 +116,11 @@
1409 >>> from canonical.database.sqlbase import flush_database_updates
1410 >>> login('foo.bar@canonical.com')
1411 >>> from zope.component import getUtility
1412- >>> from canonical.launchpad.interfaces import (
1413- ... ILaunchBag, IProductSet, License)
1414+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
1415+ >>> from lp.registry.interfaces.product import (
1416+ ... IProductSet,
1417+ ... License,
1418+ ... )
1419 >>> user = getUtility(ILaunchBag).user
1420 >>> getUtility(IProductSet).createProduct(
1421 ... user, 'bad-displayname',
1422
1423=== modified file 'lib/canonical/launchpad/pagetests/oauth/access-token.txt'
1424--- lib/canonical/launchpad/pagetests/oauth/access-token.txt 2010-10-03 15:30:06 +0000
1425+++ lib/canonical/launchpad/pagetests/oauth/access-token.txt 2010-10-21 19:08:55 +0000
1426@@ -5,10 +5,11 @@
1427 access token.
1428
1429 # First we create a new request token and review it.
1430+ >>> from zope.component import getUtility
1431+ >>> from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
1432 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission
1433- >>> from canonical.launchpad.interfaces import (
1434- ... IOAuthConsumerSet, IPersonSet, IProductSet)
1435- >>> from zope.component import getUtility
1436+ >>> from lp.registry.interfaces.person import IPersonSet
1437+ >>> from lp.registry.interfaces.product import IProductSet
1438 >>> from canonical.launchpad.ftests import login, logout
1439 >>> login('salgado@ubuntu.com')
1440 >>> consumer = getUtility(IOAuthConsumerSet).getByKey('foobar123451432')
1441
1442=== modified file 'lib/canonical/launchpad/pagetests/oauth/authorize-token.txt'
1443--- lib/canonical/launchpad/pagetests/oauth/authorize-token.txt 2010-10-18 10:11:04 +0000
1444+++ lib/canonical/launchpad/pagetests/oauth/authorize-token.txt 2010-10-21 19:08:55 +0000
1445@@ -4,14 +4,21 @@
1446 Launchpad's +authorize-token page in order for the user to authenticate
1447 and authorize or not the consumer to act on his behalf.
1448
1449+ >>> def request_token_for(consumer):
1450+ ... """Helper method to create a request token."""
1451+ ... login('salgado@ubuntu.com')
1452+ ... token = consumer.newRequestToken()
1453+ ... logout()
1454+ ... return token
1455+
1456 # Create a new request token.
1457+ >>> from zope.component import getUtility
1458 >>> from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
1459- >>> from zope.component import getUtility
1460 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
1461 >>> login('salgado@ubuntu.com')
1462 >>> consumer = getUtility(IOAuthConsumerSet).getByKey('foobar123451432')
1463- >>> token = consumer.newRequestToken()
1464 >>> logout()
1465+ >>> token = request_token_for(consumer)
1466
1467 According to the OAuth Core 1.0 spec, the request to the service
1468 provider's user authorization URL (+authorize-token in our case) must
1469@@ -71,10 +78,13 @@
1470 that isn't enough for the application. The user always has the option
1471 to deny permission altogether.
1472
1473- >>> def authorize_token_main_content(allow_permission):
1474+ >>> def authorize_token_browser(allow_permission):
1475 ... browser.open(
1476 ... "http://launchpad.dev/+authorize-token?%s&%s"
1477 ... % (urlencode(params), allow_permission))
1478+
1479+ >>> def authorize_token_main_content(allow_permission):
1480+ ... authorize_token_browser(allow_permission)
1481 ... return find_tag_by_id(browser.contents, 'maincontent')
1482
1483 >>> def print_access_levels_for(allow_permission):
1484@@ -196,10 +206,7 @@
1485 +authorized-token.
1486
1487 # Create a new (unreviewed) token.
1488- >>> logout()
1489- >>> login('salgado@ubuntu.com')
1490- >>> token = consumer.newRequestToken()
1491- >>> logout()
1492+ >>> token = request_token_for(consumer)
1493
1494 >>> params = dict(oauth_token=token.key)
1495 >>> browser.open(
1496@@ -268,14 +275,15 @@
1497 The desktop integration option is only available for OAuth consumers
1498 that say what kind of desktop they are (eg. Ubuntu) and give a name
1499 that a user can identify with their computer (eg. the hostname). Here,
1500-we'll create such a token.
1501+we'll create such a consumer, and then a request token for that consumer.
1502
1503- >>> login('salgado@ubuntu.com')
1504- >>> desktop_key = "System-wide: Ubuntu desktop (mycomputer)"
1505- >>> consumer = getUtility(IOAuthConsumerSet).new(desktop_key)
1506- >>> token = consumer.newRequestToken()
1507+ >>> login('foo.bar@canonical.com')
1508+ >>> consumer = factory.makeOAuthConsumer(
1509+ ... "System-wide: Ubuntu desktop (mycomputer)")
1510 >>> logout()
1511
1512+ >>> token = request_token_for(consumer)
1513+
1514 When a desktop tries to integrate with Launchpad, the user gets a
1515 special warning about giving access to every program running on their
1516 desktop.
1517@@ -284,34 +292,42 @@
1518 >>> print extract_text(
1519 ... authorize_token_main_content(
1520 ... 'allow_permission=DESKTOP_INTEGRATION'))
1521- Integrating mycomputer into your Launchpad account
1522+ Confirm Computer Access
1523 The Ubuntu desktop called mycomputer wants access to your
1524- Launchpad account. If you allow the integration, all applications
1525- running on mycomputer will have read-write access to your
1526- Launchpad account, including to your private data.
1527+ Launchpad account. If you allow this, every application running on
1528+ mycomputer will have read-write access to your Launchpad account,
1529+ including to your private data.
1530 If you're using a public computer, if mycomputer is not the
1531 computer you're using right now, or if something just doesn't feel
1532- right about this situation, you should choose "No, thanks, I don't
1533- trust 'mycomputer'", or close this window now. You can always try
1534- again later.
1535- Even if you decide to allow the integration, you can change your
1536- mind later.
1537+ right about this situation, you should choose "Do Not Allow
1538+ 'mycomputer' to Access my Launchpad Account", or close this window
1539+ now. You can always try again later.
1540+ Even if you decide to give mycomputer access to your Launchpad
1541+ account, you can change your mind later.
1542+ Allow mycomputer to access my Launchpad account:
1543+ or
1544 See all applications authorized to access Launchpad on your behalf.
1545
1546-
1547 The only time the 'Desktop Integration' permission shows up in the
1548 list of permissions is if the client specifically requests it, and no
1549 other permission. (Also requesting UNAUTHORIZED is okay--it will show
1550 up anyway.)
1551
1552- >>> print_access_levels_for('allow_permission=DESKTOP_INTEGRATION')
1553- Give all programs running on "mycomputer" access to my Launchpad account.
1554- No, thanks, I don't trust "mycomputer".
1555+ >>> allow_desktop = 'allow_permission=DESKTOP_INTEGRATION'
1556+ >>> print_access_levels_for(allow_desktop)
1557+ Until I Disable It
1558+ For One Hour
1559+ For One Day
1560+ For One Week
1561+ Do Not Allow "mycomputer" to Access my Launchpad Account.
1562
1563 >>> print_access_levels_for(
1564 ... 'allow_permission=DESKTOP_INTEGRATION&allow_permission=UNAUTHORIZED')
1565- Give all programs running on "mycomputer" access to my Launchpad account.
1566- No, thanks, I don't trust "mycomputer".
1567+ Until I Disable It
1568+ For One Hour
1569+ For One Day
1570+ For One Week
1571+ Do Not Allow "mycomputer" to Access my Launchpad Account.
1572
1573 A desktop may not request a level of access other than
1574 DESKTOP_INTEGRATION, since the whole point is to have a permission
1575@@ -324,7 +340,7 @@
1576 ("Change Anything") not supported for desktop-wide use.
1577
1578 >>> print_access_levels_for(
1579- ... 'allow_permission=WRITE_PUBLIC&allow_permission=DESKTOP_INTEGRATION')
1580+ ... 'allow_permission=WRITE_PUBLIC&' + allow_desktop)
1581 Traceback (most recent call last):
1582 ...
1583 Unauthorized: Desktop integration token requested a permission
1584@@ -335,7 +351,7 @@
1585 websites into Launchpad.
1586
1587 >>> params['oauth_callback'] = 'http://launchpad.dev/bzr'
1588- >>> print_access_levels_for('allow_permission=DESKTOP_INTEGRATION')
1589+ >>> print_access_levels_for(allow_desktop)
1590 Traceback (most recent call last):
1591 ...
1592 Unauthorized: A desktop integration may not specify an OAuth
1593@@ -349,3 +365,126 @@
1594 ...
1595 Unauthorized: A desktop integration may not specify an OAuth
1596 callback URL.
1597+
1598+ >>> del params['oauth_callback']
1599+
1600+Accepting full integration
1601+--------------------------
1602+
1603+Now let's create a helper function to go through the entire desktop
1604+integration process, given the name of the desktop and the level of
1605+integration desired.
1606+
1607+ >>> def integrate_desktop(button_to_click):
1608+ ... """Authorize (or don't) a desktop integration request token.
1609+ ... The token is authorized for the computer "mycomputer".
1610+ ...
1611+ ... :return: the IOAuthRequestToken, possibly authorized.
1612+ ... """
1613+ ... token = request_token_for(consumer)
1614+ ... params['oauth_token'] = token.key
1615+ ... authorize_token_browser(allow_desktop)
1616+ ... button = browser.getControl(button_to_click)
1617+ ... button.click()
1618+ ... return token
1619+
1620+If the client chooses a permanent desktop integration, the request
1621+token is approved and has no expiration date.
1622+
1623+ >>> token = integrate_desktop("Until I Disable It")
1624+ >>> print extract_text(find_tag_by_id(browser.contents, 'maincontent'))
1625+ Almost finished ...
1626+ The Ubuntu desktop called mycomputer now has access to your
1627+ Launchpad account. Within a few seconds, you should be able to
1628+ start using its Launchpad integration features.
1629+
1630+ >>> print token.is_reviewed
1631+ True
1632+ >>> print token.permission.name
1633+ DESKTOP_INTEGRATION
1634+ >>> print token.date_expires
1635+ None
1636+
1637+Accepting time-limited integration
1638+----------------------------------
1639+
1640+If you allow integration for a limited time, the request token is
1641+reviewed and given an expiration date. Here, we authorize a token for
1642+one hour.
1643+
1644+ >>> token = integrate_desktop("For One Hour")
1645+
1646+ >>> print extract_text(find_tag_by_id(browser.contents, 'maincontent'))
1647+ Almost finished ...
1648+ The Ubuntu desktop called mycomputer now has access to your
1649+ Launchpad account. Within a few seconds, you should be able to
1650+ start using its Launchpad integration features.
1651+ The integration you just authorized will expire in 59 minutes. At
1652+ that time, you'll have to re-authorize the Ubuntu desktop called
1653+ mycomputer, if you want to keep using its Launchpad integration
1654+ features.
1655+
1656+ >>> print token.is_reviewed
1657+ True
1658+ >>> print token.permission.name
1659+ DESKTOP_INTEGRATION
1660+ >>> token.date_expires is None
1661+ False
1662+
1663+Note that a single computer (in this case "mycomputer") may have more
1664+than one desktop integration token. This is because there's no way to
1665+know that a user hasn't given more than one computer the same name
1666+(eg. "ubuntu" or "localhost"). The assignment of computer names to
1667+integration tokens is a useful convention, not something we try to
1668+enforce.
1669+
1670+Here we authorize a token for one day.
1671+
1672+ >>> token = integrate_desktop("For One Day")
1673+
1674+ >>> print extract_text(find_tag_by_id(browser.contents, 'maincontent'))
1675+ Almost finished ...
1676+ The integration you just authorized will expire in 23 hours.
1677+ ...
1678+
1679+ >>> print token.is_reviewed
1680+ True
1681+ >>> token.date_expires is None
1682+ False
1683+
1684+Here, we authorize a token for a week. The expiration time is given as
1685+a date.
1686+
1687+ >>> token = integrate_desktop("For One Week")
1688+
1689+ >>> print extract_text(find_tag_by_id(browser.contents, 'maincontent'))
1690+ Almost finished ...
1691+ The integration you just authorized will expire 2...
1692+ ...
1693+
1694+ >>> print token.is_reviewed
1695+ True
1696+ >>> print token.permission.name
1697+ DESKTOP_INTEGRATION
1698+ >>> token.date_expires is None
1699+ False
1700+
1701+Declining integration
1702+---------------------
1703+
1704+If the client declines integration, the request token is reviewed but
1705+cannot be exchanged for an access token.
1706+
1707+ >>> token = integrate_desktop(
1708+ ... """Do Not Allow "mycomputer" to Access my Launchpad Account.""")
1709+
1710+ >>> print extract_text(find_tag_by_id(browser.contents, 'maincontent'))
1711+ You decided against desktop integration
1712+ You decided not to give the Ubuntu desktop called mycomputer
1713+ access to your Launchpad account. You can always change your mind
1714+ later.
1715+
1716+ >>> print token.is_reviewed
1717+ True
1718+ >>> print token.permission.name
1719+ UNAUTHORIZED
1720
1721=== modified file 'lib/canonical/launchpad/pagetests/oauth/managing-tokens.txt'
1722--- lib/canonical/launchpad/pagetests/oauth/managing-tokens.txt 2010-10-03 15:30:06 +0000
1723+++ lib/canonical/launchpad/pagetests/oauth/managing-tokens.txt 2010-10-21 19:08:55 +0000
1724@@ -5,9 +5,10 @@
1725
1726 # Create a request token, but don't convert it to an access token.
1727 >>> from zope.component import getUtility
1728+ >>> from canonical.launchpad.interfaces.oauth import IOAuthConsumerSet
1729 >>> from canonical.launchpad.webapp.interfaces import OAuthPermission
1730- >>> from canonical.launchpad.interfaces import (
1731- ... IOAuthConsumerSet, IPersonSet, IProductSet)
1732+ >>> from lp.registry.interfaces.person import IPersonSet
1733+ >>> from lp.registry.interfaces.product import IProductSet
1734 >>> login('salgado@ubuntu.com')
1735 >>> token = getUtility(IOAuthConsumerSet).getByKey(
1736 ... 'foobar123451432').newRequestToken()
1737
1738=== modified file 'lib/canonical/launchpad/pagetests/standalone/xx-opstats.txt'
1739--- lib/canonical/launchpad/pagetests/standalone/xx-opstats.txt 2010-10-09 16:36:22 +0000
1740+++ lib/canonical/launchpad/pagetests/standalone/xx-opstats.txt 2010-10-21 19:08:55 +0000
1741@@ -261,8 +261,8 @@
1742
1743 But our database connections are broken.
1744
1745+ >>> from canonical.launchpad.interfaces.lpstorm import IStore
1746 >>> from lp.registry.model.person import Person
1747- >>> from canonical.launchpad.interfaces.lpstorm import IStore
1748 >>> IStore(Person).find(Person, name='janitor')
1749 Traceback (most recent call last):
1750 ...
1751
1752=== modified file 'lib/canonical/launchpad/pagetests/standalone/xx-request-expired.txt'
1753--- lib/canonical/launchpad/pagetests/standalone/xx-request-expired.txt 2010-07-05 19:25:14 +0000
1754+++ lib/canonical/launchpad/pagetests/standalone/xx-request-expired.txt 2010-10-21 19:08:55 +0000
1755@@ -6,9 +6,9 @@
1756 slightly longer then the soft_request_timeout value to generate, thus
1757 causing a soft timeout to be logged.
1758
1759- >>> from textwrap import dedent
1760 >>> from canonical.config import config
1761 >>> from canonical.launchpad.webapp.errorlog import globalErrorUtility
1762+ >>> from textwrap import dedent
1763 >>> old_lastid = globalErrorUtility.getLastOopsReport().id
1764 >>> test_data = dedent("""
1765 ... [database]
1766
1767=== modified file 'lib/canonical/launchpad/pagetests/standalone/xx-soft-timeout.txt'
1768--- lib/canonical/launchpad/pagetests/standalone/xx-soft-timeout.txt 2010-07-05 19:25:14 +0000
1769+++ lib/canonical/launchpad/pagetests/standalone/xx-soft-timeout.txt 2010-10-21 19:08:55 +0000
1770@@ -39,8 +39,8 @@
1771 slightly longer then the soft_request_timeout value to generate, thus
1772 causing a soft timeout to be logged.
1773
1774+ >>> from canonical.launchpad.webapp.errorlog import globalErrorUtility
1775 >>> from textwrap import dedent
1776- >>> from canonical.launchpad.webapp.errorlog import globalErrorUtility
1777 >>> old_lastid = globalErrorUtility.getLastOopsReport().id
1778 >>> test_data = (dedent("""
1779 ... [database]
1780
1781=== modified file 'lib/canonical/launchpad/pagetests/webservice/xx-service.txt'
1782--- lib/canonical/launchpad/pagetests/webservice/xx-service.txt 2010-10-09 16:36:22 +0000
1783+++ lib/canonical/launchpad/pagetests/webservice/xx-service.txt 2010-10-21 19:08:55 +0000
1784@@ -45,8 +45,8 @@
1785 >>> config.push('beta_data', beta_data)
1786
1787 >>> from lp.testing import ANONYMOUS, login, logout
1788+ >>> from zope.component import getUtility
1789 >>> from canonical.launchpad.testing.pages import webservice_for_person
1790- >>> from zope.component import getUtility
1791 >>> from lp.registry.interfaces.person import IPersonSet
1792 >>> login(ANONYMOUS)
1793 >>> beta_admin = getUtility(IPersonSet).getByEmail(
1794
1795=== modified file 'lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt'
1796--- lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt 2010-03-29 14:30:51 +0000
1797+++ lib/canonical/launchpad/pagetests/webservice/xx-wadl.txt 2010-10-21 19:08:55 +0000
1798@@ -61,8 +61,8 @@
1799
1800 Unlike the test strings we used earlier, this is a valid WADL file.
1801
1802+ >>> from canonical.lazr.xml import XMLValidator
1803 >>> from lazr.restful import WADL_SCHEMA_FILE
1804- >>> from canonical.lazr.xml import XMLValidator
1805 >>> wadl_schema = XMLValidator(WADL_SCHEMA_FILE)
1806
1807 # We need to replace the nbsp entity, because the validator
1808
1809=== modified file 'lib/canonical/launchpad/templates/oauth-authorize.pt'
1810--- lib/canonical/launchpad/templates/oauth-authorize.pt 2010-10-05 16:06:02 +0000
1811+++ lib/canonical/launchpad/templates/oauth-authorize.pt 2010-10-21 19:08:55 +0000
1812@@ -23,17 +23,14 @@
1813 <div metal:fill-slot="extra_top">
1814
1815 <tal:desktop-integration-token condition="token/consumer/is_integrated_desktop">
1816- <h1>Integrating
1817- <tal:hostname replace="structure
1818- token/consumer/integrated_desktop_name" />
1819- into your Launchpad account</h1>
1820+ <h1>Confirm Computer Access</h1>
1821 <p>The
1822 <tal:desktop replace="structure
1823 token/consumer/integrated_desktop_type" />
1824 called
1825 <strong tal:content="token/consumer/integrated_desktop_name">hostname</strong>
1826- wants access to your Launchpad account. If you allow the
1827- integration, all applications running
1828+ wants access to your Launchpad account. If you allow this,
1829+ every application running
1830 on <strong tal:content="token/consumer/integrated_desktop_name">hostname</strong>
1831 will have read-write access to your Launchpad account,
1832 including to your private data.</p>
1833@@ -42,14 +39,37 @@
1834 <strong tal:content="token/consumer/integrated_desktop_name">hostname</strong>
1835 is not the computer you're using right now, or if
1836 something just doesn't feel right about this situation,
1837- you should choose "No, thanks, I don't trust
1838+ you should choose "Do Not Allow
1839 '<tal:hostname replace="structure
1840- token/consumer/integrated_desktop_name" />'",
1841- or close this window now. You can always try
1842- again later.</p>
1843-
1844- <p>Even if you decide to allow the integration, you can
1845- change your mind later.</p>
1846+ token/consumer/integrated_desktop_name" />' to Access
1847+ my Launchpad Account", or close this window now. You can
1848+ always try again later.</p>
1849+
1850+ <p>Even if you decide to give
1851+ <strong tal:content="token/consumer/integrated_desktop_name">hostname</strong>
1852+ access to your Launchpad account, you can change your
1853+ mind later.</p>
1854+
1855+ <p>
1856+ Allow <strong tal:content="token/consumer/integrated_desktop_name">hostname</strong>
1857+ to access my Launchpad account:
1858+ </p>
1859+ <p class="subordinate">
1860+ <tal:actions
1861+ repeat="action view/visible_desktop_integration_actions">
1862+ <input tal:replace="structure action/render" />
1863+ </tal:actions>
1864+ </p>
1865+
1866+ <p>or</p>
1867+ <p class="subordinate">
1868+ <input
1869+ tal:replace="structure view/unauthorized_action/render" />
1870+ </p>
1871+
1872+ <input type="hidden" name="allow_permission"
1873+ value="DESKTOP_INTEGRATION" />
1874+
1875 </tal:desktop-integration-token>
1876
1877 <tal:web-integration-token condition="not:token/consumer/is_integrated_desktop">
1878@@ -67,29 +87,29 @@
1879 </tal:has-context>
1880 Launchpad on your behalf. What level of access
1881 do you want to grant?</p>
1882+
1883+ <table>
1884+ <tr tal:repeat="action view/visible_actions">
1885+ <td style="text-align: right">
1886+ <tal:action replace="structure action/render" />
1887+ <input type="hidden" name="allow_permission"
1888+ tal:attributes="value action/permission/name" />
1889+ </td>
1890+
1891+ <td>
1892+ <span class="lesser"
1893+ tal:content="action/permission/description" />
1894+ </td>
1895+ </tr>
1896+ </table>
1897 </tal:web-integration-token>
1898-
1899- <table>
1900- <tr tal:repeat="action view/visible_actions">
1901- <td style="text-align: right">
1902- <tal:action replace="structure action/render" />
1903- </td>
1904-
1905- <tal:web-integration-token
1906- condition="not:token/consumer/is_integrated_desktop">
1907- <td>
1908- <span class="lesser"
1909- tal:content="action/permission/description" />
1910- </td>
1911- </tal:web-integration-token>
1912- </tr>
1913- </table>
1914 </div>
1915
1916 <div metal:fill-slot="extra_bottom">
1917 <input type="hidden" name="oauth_token"
1918 tal:condition="request/form/oauth_token|nothing"
1919 tal:attributes="value request/form/oauth_token" />
1920+
1921 <input type="hidden" name="oauth_callback"
1922 tal:condition="request/form/oauth_callback|nothing"
1923 tal:attributes="value request/form/oauth_callback" />
1924
1925=== modified file 'lib/canonical/launchpad/templates/token-authorized.pt'
1926--- lib/canonical/launchpad/templates/token-authorized.pt 2009-07-17 17:59:07 +0000
1927+++ lib/canonical/launchpad/templates/token-authorized.pt 2010-10-21 19:08:55 +0000
1928@@ -8,25 +8,71 @@
1929 >
1930 <body>
1931 <div class="top-portlet" metal:fill-slot="main">
1932- <tal:unauthorized condition="view/token/permission/enumvalue:UNAUTHORIZED">
1933- <h1>Access not granted to application</h1>
1934- <p>
1935- The application identified as
1936- <strong tal:content="view/token/consumer/key">key</strong> has not
1937- been given access to your protected resources on Launchpad.
1938- </p>
1939- </tal:unauthorized>
1940-
1941- <tal:authorized condition="not:view/token/permission/enumvalue:UNAUTHORIZED">
1942- <h1>Almost finished ...</h1>
1943- <p>
1944+
1945+ <tal:desktop condition="view/token/consumer/is_integrated_desktop">
1946+
1947+ <tal:unauthorized condition="view/token/permission/enumvalue:UNAUTHORIZED">
1948+ <h1>You decided against desktop integration</h1>
1949+
1950+ <p>
1951+ You decided not to give the
1952+ <tal:desktop replace="structure view/token/consumer/integrated_desktop_type" />
1953+ called
1954+ <strong tal:content="view/token/consumer/integrated_desktop_name">hostname</strong>
1955+ access to your Launchpad account. You can always change your
1956+ mind later.
1957+ </p>
1958+ </tal:unauthorized>
1959+
1960+ <tal:authorized condition="not:view/token/permission/enumvalue:UNAUTHORIZED">
1961+ <h1>Almost finished ...</h1>
1962+
1963+ <p>The
1964+ <tal:desktop replace="structure view/token/consumer/integrated_desktop_type" />
1965+ called
1966+ <strong tal:content="view/token/consumer/integrated_desktop_name">hostname</strong>
1967+ now has access to your Launchpad account. Within a few
1968+ seconds, you should be able to start using its Launchpad
1969+ integration features.</p>
1970+
1971+ <p tal:condition="view/token/date_expires">
1972+ The integration you just authorized will expire
1973+ <tal:date
1974+ replace="structure view/token/date_expires/fmt:approximatedate" />.
1975+ At that time, you'll have to re-authorize the
1976+ <tal:desktop replace="structure view/token/consumer/integrated_desktop_type" />
1977+ called
1978+ <strong tal:content="view/token/consumer/integrated_desktop_name">hostname</strong>,
1979+ if you want to keep using its Launchpad integration features.
1980+
1981+ </p>
1982+
1983+ </tal:authorized>
1984+ </tal:desktop>
1985+
1986+ <tal:application condition="not:view/token/consumer/is_integrated_desktop">
1987+
1988+ <tal:unauthorized condition="view/token/permission/enumvalue:UNAUTHORIZED">
1989+ <h1>Access not granted to application</h1>
1990+ <p>
1991+ The application identified as
1992+ <strong tal:content="view/token/consumer/key">key</strong> has not
1993+ been given access to your protected resources on Launchpad.
1994+ </p>
1995+ </tal:unauthorized>
1996+
1997+ <tal:authorized condition="not:view/token/permission/enumvalue:UNAUTHORIZED">
1998+ <h1>Almost finished ...</h1>
1999+ <p>
2000 To finish authorizing the application identified as
2001 <strong tal:content="view/token/consumer/key">key</strong> to access
2002 Launchpad on your behalf you should go back to the application window
2003 in which you started the process and inform it that you have done your
2004 part of the process.
2005- </p>
2006- </tal:authorized>
2007+ </p>
2008+ </tal:authorized>
2009+
2010+ </tal:application>
2011 </div>
2012
2013 </body>
2014
2015=== modified file 'lib/canonical/launchpad/webapp/ftests/test_adapter_timeout.txt.disabled'
2016--- lib/canonical/launchpad/webapp/ftests/test_adapter_timeout.txt.disabled 2009-06-02 08:20:49 +0000
2017+++ lib/canonical/launchpad/webapp/ftests/test_adapter_timeout.txt.disabled 2010-10-21 19:08:55 +0000
2018@@ -16,9 +16,9 @@
2019 First we create a view that will provoke a TimeoutError, a view for the
2020 exception, and a time machine.
2021
2022+ >>> from zope.publisher.browser import BrowserView
2023+ >>> from zope.testbrowser.testing import Browser
2024 >>> from textwrap import dedent
2025- >>> from zope.testbrowser.testing import Browser
2026- >>> from zope.publisher.browser import BrowserView
2027 >>> from zope.publisher.interfaces.browser import (
2028 ... IBrowserRequest, IBrowserView, IBrowserPublisher)
2029 >>> from zope.interface import Interface, implements
2030
2031=== modified file 'lib/canonical/launchpad/webapp/tests/test_preferredcharsets.txt'
2032--- lib/canonical/launchpad/webapp/tests/test_preferredcharsets.txt 2006-07-14 14:45:31 +0000
2033+++ lib/canonical/launchpad/webapp/tests/test_preferredcharsets.txt 2010-10-21 19:08:55 +0000
2034@@ -1,8 +1,8 @@
2035 We have a custom IUserPreferredCharsets which always returns
2036 utf-8 as the preferred charset.
2037
2038+ >>> from zope.publisher.browser import TestRequest
2039 >>> from canonical.launchpad.webapp import Utf8PreferredCharsets
2040- >>> from zope.publisher.browser import TestRequest
2041 >>> user_preferred = Utf8PreferredCharsets(TestRequest())
2042
2043 >>> from zope.i18n.interfaces import IUserPreferredCharsets
2044
2045=== modified file 'lib/canonical/launchpad/webapp/tests/test_request_expire_render.txt'
2046--- lib/canonical/launchpad/webapp/tests/test_request_expire_render.txt 2010-09-13 04:45:59 +0000
2047+++ lib/canonical/launchpad/webapp/tests/test_request_expire_render.txt 2010-10-21 19:08:55 +0000
2048@@ -12,8 +12,8 @@
2049 since get_request_remaining_seconds will raise. However, if the user is logged
2050 in, a query will be issued to render the "Logged in as No Privileges Person".
2051
2052+ >>> from canonical.config import config
2053 >>> from textwrap import dedent
2054- >>> from canonical.config import config
2055 >>> test_data = dedent("""
2056 ... [database]
2057 ... db_statement_timeout: 10000
2058
2059=== modified file 'lib/canonical/lazr/doc/menus.txt'
2060--- lib/canonical/lazr/doc/menus.txt 2010-09-28 19:10:51 +0000
2061+++ lib/canonical/lazr/doc/menus.txt 2010-10-21 19:08:55 +0000
2062@@ -76,8 +76,8 @@
2063 # objects. This function does most of the work, but views must be
2064 # assigned to the _last_obj_traversed attribute.
2065
2066+ >>> from canonical.launchpad.webapp import canonical_url
2067 >>> from canonical.lazr.testing.menus import make_fake_request
2068- >>> from canonical.launchpad.webapp import canonical_url
2069
2070 >>> root = Root('', None)
2071 >>> cookbook = Cookbook('joy-of-cooking', root)
2072@@ -932,8 +932,8 @@
2073 >>> from zope.traversing.adapters import DefaultTraversable
2074 >>> from zope.traversing.interfaces import IPathAdapter, ITraversable
2075 >>> from canonical.launchpad.ftests import test_tales
2076+ >>> from canonical.lazr.testing.menus import summarise_tal_links
2077 >>> from lp.app.browser.tales import MenuAPI
2078- >>> from canonical.lazr.testing.menus import summarise_tal_links
2079
2080 # MenuAPI is normally registered as an IPathAdapter in ZCML. This
2081 # approximates what is done by the code:
2082
2083=== modified file 'lib/canonical/lazr/doc/timeout.txt'
2084--- lib/canonical/lazr/doc/timeout.txt 2010-04-22 18:53:09 +0000
2085+++ lib/canonical/lazr/doc/timeout.txt 2010-10-21 19:08:55 +0000
2086@@ -10,8 +10,8 @@
2087 The time to wait can be passed using the timeout parameter to the
2088 decorator.
2089
2090+ >>> from canonical.lazr.timeout import with_timeout
2091 >>> from select import select
2092- >>> from canonical.lazr.timeout import with_timeout
2093
2094 >>> @with_timeout(timeout=0.5)
2095 ... def wait_for(time):
2096
2097=== modified file 'lib/lp/answers/browser/tests/views.txt'
2098--- lib/lp/answers/browser/tests/views.txt 2010-07-30 12:56:27 +0000
2099+++ lib/lp/answers/browser/tests/views.txt 2010-10-21 19:08:55 +0000
2100@@ -100,8 +100,8 @@
2101
2102 # Setup a harness to easily test the view.
2103
2104- >>> from canonical.launchpad.ftests import LaunchpadFormHarness
2105 >>> from canonical.launchpad.browser import QuestionWorkflowView
2106+ >>> from canonical.launchpad.ftests import LaunchpadFormHarness
2107 >>> workflow_harness = LaunchpadFormHarness(
2108 ... firefox_question, QuestionWorkflowView)
2109
2110@@ -708,8 +708,8 @@
2111 retrieve the set of languages in which the user is assumed to be
2112 interested.
2113
2114+ >>> from canonical.launchpad.browser import UserSupportLanguagesMixin
2115 >>> from canonical.launchpad.webapp import LaunchpadView
2116- >>> from canonical.launchpad.browser import UserSupportLanguagesMixin
2117
2118 >>> class UserSupportLanguagesView(UserSupportLanguagesMixin,
2119 ... LaunchpadView):
2120
2121=== modified file 'lib/lp/answers/doc/emailinterface.txt.disabled'
2122--- lib/lp/answers/doc/emailinterface.txt.disabled 2010-10-04 19:50:45 +0000
2123+++ lib/lp/answers/doc/emailinterface.txt.disabled 2010-10-21 19:08:55 +0000
2124@@ -98,17 +98,17 @@
2125 # be the question owner and Sample Person who will play the role of
2126 # answer contact. Foo Bar is used to change the status of the
2127 # question.
2128+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2129 >>> from lp.registry.interfaces.person import IPersonSet
2130- >>> from lp.registry.interfaces.distribution import IDistributionSet
2131 >>> login('no-priv@canonical.com')
2132 >>> personset = getUtility(IPersonSet)
2133 >>> sample_person = personset.getByEmail('test@canonical.com')
2134 >>> no_priv = personset.getByEmail('no-priv@canonical.com')
2135 >>> foo_bar = personset.getByEmail('foo.bar@canonical.com')
2136
2137- >>> from canonical.testing.layers import LaunchpadZopelessLayer
2138 >>> from canonical.config import config
2139 >>> from canonical.database.sqlbase import commit
2140+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
2141
2142 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
2143 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
2144
2145=== modified file 'lib/lp/answers/doc/expiration.txt'
2146--- lib/lp/answers/doc/expiration.txt 2010-07-30 12:56:27 +0000
2147+++ lib/lp/answers/doc/expiration.txt 2010-10-21 19:08:55 +0000
2148@@ -19,8 +19,8 @@
2149
2150 # Sanity check in case somebody modifies the question sampledata and
2151 # forget to update this script.
2152+ >>> from lp.answers.interfaces.questionenums import QuestionStatus
2153 >>> from lp.answers.model.question import Question
2154- >>> from lp.answers.interfaces.questionenums import QuestionStatus
2155 >>> Question.select('status IN (%i,%i)' % (
2156 ... QuestionStatus.OPEN.value,
2157 ... QuestionStatus.NEEDSINFO.value)).count()
2158@@ -43,8 +43,8 @@
2159 >>> two_weeks_ago = now - timedelta(days=14)
2160 >>> a_month_ago = now - timedelta(days=31)
2161 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
2162+ >>> from lp.answers.interfaces.questioncollection import IQuestionSet
2163 >>> from lp.registry.interfaces.person import IPersonSet
2164- >>> from lp.answers.interfaces.questioncollection import IQuestionSet
2165 >>> login('no-priv@canonical.com')
2166 >>> no_priv = getUtility(ILaunchBag).user
2167
2168
2169=== modified file 'lib/lp/answers/doc/faq-vocabulary.txt'
2170--- lib/lp/answers/doc/faq-vocabulary.txt 2010-08-02 02:33:53 +0000
2171+++ lib/lp/answers/doc/faq-vocabulary.txt 2010-10-21 19:08:55 +0000
2172@@ -4,10 +4,10 @@
2173 collection. It provides the IHugeVocabulary interface.
2174
2175 >>> from zope.component import getUtility
2176- >>> from lp.registry.interfaces.product import IProductSet
2177+ >>> from zope.schema.vocabulary import getVocabularyRegistry
2178 >>> from canonical.launchpad.webapp.testing import verifyObject
2179 >>> from canonical.launchpad.webapp.vocabulary import IHugeVocabulary
2180- >>> from zope.schema.vocabulary import getVocabularyRegistry
2181+ >>> from lp.registry.interfaces.product import IProductSet
2182
2183 >>> vocabulary_registry = getVocabularyRegistry()
2184 >>> firefox = getUtility(IProductSet).getByName('firefox')
2185
2186=== modified file 'lib/lp/answers/doc/faq.txt'
2187--- lib/lp/answers/doc/faq.txt 2010-07-30 12:56:27 +0000
2188+++ lib/lp/answers/doc/faq.txt 2010-10-21 19:08:55 +0000
2189@@ -10,12 +10,12 @@
2190 are associated to distributions or products. The IFAQTarget interface is
2191 provided by objects that can host FAQs.
2192
2193+ >>> from zope.security.proxy import removeSecurityProxy
2194 >>> from canonical.launchpad.webapp.testing import verifyObject
2195- >>> from zope.security.proxy import removeSecurityProxy
2196
2197+ >>> from lp.answers.interfaces.faqtarget import IFAQTarget
2198 >>> from lp.registry.interfaces.distribution import IDistributionSet
2199 >>> from lp.registry.interfaces.product import IProductSet
2200- >>> from lp.answers.interfaces.faqtarget import IFAQTarget
2201
2202 >>> firefox = getUtility(IProductSet).getByName('firefox')
2203
2204
2205=== modified file 'lib/lp/answers/doc/faqtarget.txt'
2206--- lib/lp/answers/doc/faqtarget.txt 2010-10-03 15:30:06 +0000
2207+++ lib/lp/answers/doc/faqtarget.txt 2010-10-21 19:08:55 +0000
2208@@ -31,8 +31,8 @@
2209 the target.
2210
2211 >>> login('no-priv@canonical.com')
2212- >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
2213 >>> from canonical.launchpad.webapp.authorization import check_permission
2214+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
2215 >>> check_permission('launchpad.Append', target)
2216 False
2217
2218
2219=== modified file 'lib/lp/answers/doc/notifications.txt'
2220--- lib/lp/answers/doc/notifications.txt 2010-07-30 12:56:27 +0000
2221+++ lib/lp/answers/doc/notifications.txt 2010-10-21 19:08:55 +0000
2222@@ -83,8 +83,8 @@
2223 Register the Ubuntu Team as Ubuntu's answer contact, so that they get
2224 notified about the changes as well:
2225
2226- >>> from lp.services.worlddata.interfaces.language import ILanguageSet
2227 >>> from lp.registry.interfaces.person import IPersonSet
2228+ >>> from lp.services.worlddata.interfaces.language import ILanguageSet
2229 >>> ubuntu_team = getUtility(IPersonSet).getByName('ubuntu-team')
2230 >>> ubuntu_team.addLanguage(getUtility(ILanguageSet)['en'])
2231 >>> ubuntu.addAnswerContact(ubuntu_team)
2232@@ -103,9 +103,9 @@
2233 If we edit the title and description of the question, a notification
2234 will be sent.
2235
2236+ >>> from zope.interface import providedBy
2237 >>> from lazr.lifecycle.event import ObjectModifiedEvent
2238 >>> from lazr.lifecycle.snapshot import Snapshot
2239- >>> from zope.interface import providedBy
2240
2241 >>> login('no-priv@canonical.com')
2242 >>> no_priv = getUtility(ILaunchBag).user
2243
2244=== modified file 'lib/lp/answers/doc/person.txt'
2245--- lib/lp/answers/doc/person.txt 2010-06-09 17:07:49 +0000
2246+++ lib/lp/answers/doc/person.txt 2010-10-21 19:08:55 +0000
2247@@ -14,8 +14,8 @@
2248 commented on, or answered. Various subsets can be selected by using the
2249 various search criteria.
2250
2251+ >>> from lp.answers.interfaces.questionsperson import IQuestionsPerson
2252 >>> from lp.registry.interfaces.person import IPersonSet
2253- >>> from lp.answers.interfaces.questionsperson import IQuestionsPerson
2254 >>> personset = getUtility(IPersonSet)
2255 >>> foo_bar_raw = personset.getByEmail('foo.bar@canonical.com')
2256 >>> foo_bar = IQuestionsPerson(foo_bar_raw)
2257
2258=== modified file 'lib/lp/answers/doc/projectgroup.txt'
2259--- lib/lp/answers/doc/projectgroup.txt 2010-07-30 12:56:27 +0000
2260+++ lib/lp/answers/doc/projectgroup.txt 2010-10-21 19:08:55 +0000
2261@@ -24,8 +24,8 @@
2262 You can search for all questions filed against projects in a project using the
2263 project group's searchQuestions() method.
2264
2265+ >>> from lp.registry.interfaces.person import IPersonSet
2266 >>> from lp.registry.interfaces.product import IProductSet
2267- >>> from lp.registry.interfaces.person import IPersonSet
2268
2269 >>> login('test@canonical.com')
2270 >>> thunderbird = getUtility(IProductSet).getByName('thunderbird')
2271
2272=== modified file 'lib/lp/answers/doc/question.txt'
2273--- lib/lp/answers/doc/question.txt 2010-10-03 15:30:06 +0000
2274+++ lib/lp/answers/doc/question.txt 2010-10-21 19:08:55 +0000
2275@@ -11,9 +11,9 @@
2276 >>> login('test@canonical.com')
2277
2278 >>> from canonical.launchpad.webapp.testing import verifyObject
2279+ >>> from lp.answers.interfaces.questiontarget import IQuestionTarget
2280+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2281 >>> from lp.registry.interfaces.person import IPersonSet
2282- >>> from lp.registry.interfaces.distribution import IDistributionSet
2283- >>> from lp.answers.interfaces.questiontarget import IQuestionTarget
2284 >>> from lp.registry.interfaces.product import IProductSet
2285
2286 >>> firefox = getUtility(IProductSet)['firefox']
2287@@ -86,8 +86,8 @@
2288
2289 Questions are manipulated through the IQuestion interface.
2290
2291+ >>> from zope.security.proxy import removeSecurityProxy
2292 >>> from lp.answers.interfaces.question import IQuestion
2293- >>> from zope.security.proxy import removeSecurityProxy
2294
2295 # The complete interface is not necessarily available to the
2296 # logged in user.
2297
2298=== modified file 'lib/lp/answers/doc/questionsets.txt'
2299--- lib/lp/answers/doc/questionsets.txt 2010-10-03 15:30:06 +0000
2300+++ lib/lp/answers/doc/questionsets.txt 2010-10-21 19:08:55 +0000
2301@@ -177,10 +177,10 @@
2302
2303 Then some recent questions are created on a number of projects.
2304
2305+ >>> from lp.answers.testing import QuestionFactory
2306 >>> from lp.registry.interfaces.distribution import IDistributionSet
2307 >>> from lp.registry.interfaces.person import IPersonSet
2308 >>> from lp.registry.interfaces.product import IProductSet
2309- >>> from lp.answers.testing import QuestionFactory
2310
2311 >>> firefox = getUtility(IProductSet).getByName('firefox')
2312 >>> landscape = getUtility(IProductSet).getByName('landscape')
2313
2314=== modified file 'lib/lp/answers/doc/questiontarget.txt'
2315--- lib/lp/answers/doc/questiontarget.txt 2010-10-03 15:30:06 +0000
2316+++ lib/lp/answers/doc/questiontarget.txt 2010-10-21 19:08:55 +0000
2317@@ -532,9 +532,9 @@
2318 copied to the question.
2319
2320 >>> from datetime import datetime
2321- >>> from pytz import UTC
2322 >>> from lp.bugs.interfaces.bug import CreateBugParams
2323 >>> from lp.registry.interfaces.product import IProductSet
2324+ >>> from pytz import UTC
2325
2326 >>> now = datetime.now(UTC)
2327 >>> target = getUtility(IProductSet)['jokosher']
2328
2329=== modified file 'lib/lp/answers/doc/workflow.txt'
2330--- lib/lp/answers/doc/workflow.txt 2010-10-03 15:30:06 +0000
2331+++ lib/lp/answers/doc/workflow.txt 2010-10-21 19:08:55 +0000
2332@@ -602,8 +602,8 @@
2333 # Register an event listener that will print events it receives.
2334 >>> from lazr.lifecycle.interfaces import (
2335 ... IObjectCreatedEvent, IObjectModifiedEvent)
2336+ >>> from canonical.lazr.testing.event import TestEventListener
2337 >>> from lp.answers.interfaces.question import IQuestion
2338- >>> from canonical.lazr.testing.event import TestEventListener
2339
2340 >>> def print_event(object, event):
2341 ... print "Received %s on %s" % (
2342
2343=== modified file 'lib/lp/answers/stories/distribution-package-answer-contact.txt'
2344--- lib/lp/answers/stories/distribution-package-answer-contact.txt 2010-07-30 12:56:27 +0000
2345+++ lib/lp/answers/stories/distribution-package-answer-contact.txt 2010-10-21 19:08:55 +0000
2346@@ -7,10 +7,10 @@
2347 # Register a Sample Person as an answer contact for the distribution.
2348 >>> from zope.component import getUtility
2349 >>> from canonical.launchpad.ftests import login, logout
2350+ >>> from canonical.database.sqlbase import flush_database_updates
2351 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
2352+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2353 >>> from lp.services.worlddata.interfaces.language import ILanguageSet
2354- >>> from lp.registry.interfaces.distribution import IDistributionSet
2355- >>> from canonical.database.sqlbase import flush_database_updates
2356 >>> login('test@canonical.com')
2357 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
2358 >>> # Answer contacts must speak a language
2359
2360=== modified file 'lib/lp/answers/tests/questiontarget-sourcepackage.txt'
2361--- lib/lp/answers/tests/questiontarget-sourcepackage.txt 2010-07-30 12:56:27 +0000
2362+++ lib/lp/answers/tests/questiontarget-sourcepackage.txt 2010-10-21 19:08:55 +0000
2363@@ -13,8 +13,8 @@
2364 of the DistributionSourcePackage (and not the SourcePackage):
2365
2366 >>> login('no-priv@canonical.com')
2367+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2368 >>> from lp.registry.interfaces.person import IPersonSet
2369- >>> from lp.registry.interfaces.distribution import IDistributionSet
2370 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
2371 >>> firefox = ubuntu.currentseries.getSourcePackage('mozilla-firefox')
2372
2373
2374=== modified file 'lib/lp/app/browser/tests/base-layout.txt'
2375--- lib/lp/app/browser/tests/base-layout.txt 2010-09-29 03:26:01 +0000
2376+++ lib/lp/app/browser/tests/base-layout.txt 2010-10-21 19:08:55 +0000
2377@@ -10,9 +10,9 @@
2378 in the root element of the page template. The base layout template uses the
2379 YUI grid classes for positioning.
2380
2381- >>> from z3c.ptcompat import ViewPageTemplateFile
2382 >>> from canonical.launchpad.webapp.publisher import LaunchpadView
2383 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2384+ >>> from z3c.ptcompat import ViewPageTemplateFile
2385
2386 >>> user = factory.makePerson(name='waffles')
2387 >>> request = LaunchpadTestRequest(
2388
2389=== modified file 'lib/lp/app/browser/tests/launchpadform-view.txt'
2390--- lib/lp/app/browser/tests/launchpadform-view.txt 2010-06-22 17:12:23 +0000
2391+++ lib/lp/app/browser/tests/launchpadform-view.txt 2010-10-21 19:08:55 +0000
2392@@ -6,15 +6,15 @@
2393 widget rendering is wrapped with a <div> using the widget_class, which
2394 can be used for subordinate field indentation, for example.
2395
2396- >>> from z3c.ptcompat import ViewPageTemplateFile
2397 >>> from zope.app.form.browser import TextWidget
2398 >>> from zope.interface import Interface
2399 >>> from zope.schema import TextLine
2400 >>> from canonical.config import config
2401+ >>> from z3c.ptcompat import ViewPageTemplateFile
2402 >>> from canonical.launchpad.webapp.launchpadform import (
2403 ... custom_widget, LaunchpadFormView)
2404+ >>> from canonical.launchpad.testing.pages import find_tags_by_class
2405 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2406- >>> from canonical.launchpad.testing.pages import find_tags_by_class
2407
2408 >>> class ITestSchema(Interface):
2409 ... displayname = TextLine(title=u"Title")
2410
2411=== modified file 'lib/lp/app/doc/tales.txt'
2412--- lib/lp/app/doc/tales.txt 2010-10-09 16:36:22 +0000
2413+++ lib/lp/app/doc/tales.txt 2010-10-21 19:08:55 +0000
2414@@ -113,8 +113,8 @@
2415
2416 And finally Copy archives.
2417
2418+ >>> from lp.soyuz.enums import ArchivePurpose
2419 >>> from lp.soyuz.interfaces.archive import IArchiveSet
2420- >>> from lp.soyuz.enums import ArchivePurpose
2421 >>> copy = getUtility(IArchiveSet).new(
2422 ... owner=mark, purpose=ArchivePurpose.COPY,
2423 ... distribution=ubuntu, name='rebuild')
2424@@ -197,8 +197,8 @@
2425
2426 The 'building' build is 14x14:
2427
2428+ >>> from zope.security.proxy import removeSecurityProxy
2429 >>> from lp.buildmaster.enums import BuildStatus
2430- >>> from zope.security.proxy import removeSecurityProxy
2431 >>> removeSecurityProxy(build).status = BuildStatus.BUILDING
2432 >>> print test_tales("build/image:icon", build=build)
2433 <img width="14" height="14"...src="/@@/processing" />
2434@@ -1181,8 +1181,8 @@
2435
2436 Test the 'fmt:url' namespace for canonical urls.
2437
2438+ >>> from zope.interface import implements
2439 >>> from canonical.launchpad.webapp.interfaces import ICanonicalUrlData
2440- >>> from zope.interface import implements
2441 >>> class ObjectThatHasUrl:
2442 ... implements(ICanonicalUrlData)
2443 ... path = 'bonobo/saki'
2444
2445=== modified file 'lib/lp/app/stories/basics/xx-beta-testers-redirection.txt'
2446--- lib/lp/app/stories/basics/xx-beta-testers-redirection.txt 2010-10-03 15:30:06 +0000
2447+++ lib/lp/app/stories/basics/xx-beta-testers-redirection.txt 2010-10-21 19:08:55 +0000
2448@@ -203,8 +203,8 @@
2449 Add Foo Bar to the beta team.
2450
2451 >>> from zope.component import getUtility
2452- >>> from canonical.launchpad.interfaces import (
2453- ... ILaunchpadCelebrities, IPersonSet)
2454+ >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
2455+ >>> from lp.registry.interfaces.person import IPersonSet
2456 >>> from canonical.launchpad.ftests import login, logout
2457 >>> login('foo.bar@canonical.com')
2458 >>> foo_bar = getUtility(IPersonSet).getByName('name16')
2459
2460=== modified file 'lib/lp/archivepublisher/tests/archive-signing.txt'
2461--- lib/lp/archivepublisher/tests/archive-signing.txt 2010-09-02 11:45:19 +0000
2462+++ lib/lp/archivepublisher/tests/archive-signing.txt 2010-10-21 19:08:55 +0000
2463@@ -32,8 +32,8 @@
2464 `IArchiveSet.getPPAsPendingSigningKey` allows call-sites to query for
2465 PPA pending signing key generation.
2466
2467+ >>> from lp.registry.interfaces.person import IPersonSet
2468 >>> from lp.soyuz.interfaces.archive import IArchiveSet
2469- >>> from lp.registry.interfaces.person import IPersonSet
2470
2471 Only PPAs with at least one source publication are considered.
2472
2473
2474=== modified file 'lib/lp/archivepublisher/tests/publishing-meta-data-files.txt'
2475--- lib/lp/archivepublisher/tests/publishing-meta-data-files.txt 2010-08-24 13:47:37 +0000
2476+++ lib/lp/archivepublisher/tests/publishing-meta-data-files.txt 2010-10-21 19:08:55 +0000
2477@@ -11,12 +11,12 @@
2478
2479 >>> from canonical.launchpad.interfaces.librarian import (
2480 ... ILibraryFileAliasSet)
2481+ >>> from cStringIO import StringIO
2482 >>> from lp.archiveuploader.tests import mock_logger
2483 >>> from lp.registry.interfaces.distribution import IDistributionSet
2484+ >>> from lp.soyuz.enums import PackageUploadCustomFormat
2485 >>> from lp.soyuz.interfaces.publishing import PackagePublishingPocket
2486- >>> from lp.soyuz.enums import PackageUploadCustomFormat
2487 >>> from lp.soyuz.model.queue import PackageUploadCustom
2488- >>> from cStringIO import StringIO
2489
2490 >>> bat = getUtility(IDistributionSet)['ubuntutest']['breezy-autotest']
2491 >>> ppa = factory.makeArchive(distribution=bat.distribution)
2492
2493=== modified file 'lib/lp/archiveuploader/tests/nascentupload-announcements.txt'
2494--- lib/lp/archiveuploader/tests/nascentupload-announcements.txt 2010-10-03 15:30:06 +0000
2495+++ lib/lp/archiveuploader/tests/nascentupload-announcements.txt 2010-10-21 19:08:55 +0000
2496@@ -52,8 +52,9 @@
2497 distroseries so that we can upload to it. Also adjust 'changeslist'
2498 address and allow uploads to universe:
2499
2500- >>> from canonical.launchpad.interfaces import (
2501- ... SeriesStatus, IDistributionSet, ILibraryFileAliasSet)
2502+ >>> from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
2503+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2504+ >>> from lp.registry.interfaces.series import SeriesStatus
2505 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
2506 >>> hoary = ubuntu['hoary']
2507 >>> hoary.status = SeriesStatus.DEVELOPMENT
2508@@ -249,10 +250,10 @@
2509
2510 A PPA upload will contain the X-Launchpad-PPA header.
2511
2512+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2513+ >>> from lp.registry.interfaces.person import IPersonSet
2514 >>> from lp.soyuz.enums import ArchivePurpose
2515 >>> from lp.soyuz.interfaces.archive import IArchiveSet
2516- >>> from lp.registry.interfaces.distribution import IDistributionSet
2517- >>> from lp.registry.interfaces.person import IPersonSet
2518
2519 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
2520 >>> name16 = getUtility(IPersonSet).getByName('name16')
2521
2522=== modified file 'lib/lp/archiveuploader/tests/nascentupload-closing-bugs.txt'
2523--- lib/lp/archiveuploader/tests/nascentupload-closing-bugs.txt 2010-10-09 16:36:22 +0000
2524+++ lib/lp/archiveuploader/tests/nascentupload-closing-bugs.txt 2010-10-21 19:08:55 +0000
2525@@ -32,8 +32,9 @@
2526
2527 >>> from canonical.testing.layers import LaunchpadZopelessLayer
2528 >>> from lp.bugs.interfaces.bug import IBugSet
2529- >>> from canonical.launchpad.interfaces import (
2530- ... IBugTaskSet, IDistributionSet, IPersonSet)
2531+ >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
2532+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2533+ >>> from lp.registry.interfaces.person import IPersonSet
2534 >>> login('no-priv@canonical.com')
2535 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
2536
2537
2538=== modified file 'lib/lp/archiveuploader/tests/nascentupload-packageset.txt'
2539--- lib/lp/archiveuploader/tests/nascentupload-packageset.txt 2010-10-09 16:36:22 +0000
2540+++ lib/lp/archiveuploader/tests/nascentupload-packageset.txt 2010-10-21 19:08:55 +0000
2541@@ -4,11 +4,12 @@
2542 >>> from lp.archiveuploader.tests import (
2543 ... datadir, getPolicy, mock_logger_quiet)
2544 >>> from canonical.database.sqlbase import commit
2545+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
2546+ >>> from lp.registry.interfaces.person import IPersonSet
2547+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
2548 >>> from lp.soyuz.enums import ArchivePermissionType
2549- >>> from canonical.launchpad.interfaces import (
2550- ... IArchivePermissionSet, IPackagesetSet,
2551- ... IPersonSet, ISourcePackageNameSet)
2552- >>> from canonical.testing.layers import LaunchpadZopelessLayer
2553+ >>> from lp.soyuz.interfaces.archivepermission import IArchivePermissionSet
2554+ >>> from lp.soyuz.interfaces.packageset import IPackagesetSet
2555
2556 >>> insecure_policy = getPolicy(
2557 ... name='insecure', distro='ubuntu', distroseries='hoary')
2558
2559=== modified file 'lib/lp/archiveuploader/tests/nascentupload.txt'
2560--- lib/lp/archiveuploader/tests/nascentupload.txt 2010-10-19 09:00:29 +0000
2561+++ lib/lp/archiveuploader/tests/nascentupload.txt 2010-10-21 19:08:55 +0000
2562@@ -12,8 +12,8 @@
2563 For the purpose of this test, hoary needs to be an open (development)
2564 distroseries so that we can upload to it.
2565
2566- >>> from canonical.launchpad.interfaces import (
2567- ... SeriesStatus, IDistributionSet)
2568+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2569+ >>> from lp.registry.interfaces.series import SeriesStatus
2570 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
2571 >>> hoary = ubuntu['hoary']
2572 >>> hoary.status = SeriesStatus.DEVELOPMENT
2573@@ -740,8 +740,8 @@
2574 False
2575
2576 >>> from canonical.launchpad.webapp.testing import verifyObject
2577- >>> from canonical.launchpad.interfaces import (
2578- ... IGPGKey, IPersonSet)
2579+ >>> from lp.registry.interfaces.gpg import IGPGKey
2580+ >>> from lp.registry.interfaces.person import IPersonSet
2581
2582 >>> verifyObject(IGPGKey, bar_ok.changes.dsc.signingkey)
2583 True
2584@@ -815,8 +815,8 @@
2585
2586 >>> commit()
2587 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
2588+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
2589 >>> from lp.soyuz.enums import ArchivePermissionType
2590- >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
2591 >>> bar_name = getUtility(ISourcePackageNameSet).getOrCreateByName("bar")
2592 >>> discard = ArchivePermission(
2593 ... archive=ubuntu.main_archive, person=name16,
2594
2595=== modified file 'lib/lp/archiveuploader/tests/upload-karma.txt'
2596--- lib/lp/archiveuploader/tests/upload-karma.txt 2010-10-10 15:39:28 +0000
2597+++ lib/lp/archiveuploader/tests/upload-karma.txt 2010-10-21 19:08:55 +0000
2598@@ -49,9 +49,9 @@
2599
2600 Poke the queue entry so it looks like Foo Bar (name16) uploaded it:
2601
2602+ >>> from zope.security.proxy import removeSecurityProxy
2603 >>> from lp.registry.interfaces.gpg import IGPGKeySet
2604 >>> from lp.registry.interfaces.person import IPersonSet
2605- >>> from zope.security.proxy import removeSecurityProxy
2606 >>> name16 = getUtility(IPersonSet).getByName('name16')
2607 >>> key = getUtility(IGPGKeySet).getGPGKeysForPeople([name16])[0]
2608 >>> removeSecurityProxy(foo_src.queue_root).signing_key = key
2609@@ -83,9 +83,9 @@
2610 will generate another different karma event for the uploader.
2611
2612 >>> from lp.archiveuploader.tests import getPolicy
2613+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2614 >>> from lp.soyuz.enums import ArchivePurpose
2615 >>> from lp.soyuz.interfaces.archive import IArchiveSet
2616- >>> from lp.registry.interfaces.distribution import IDistributionSet
2617 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
2618 >>> name16_ppa = getUtility(IArchiveSet).new(
2619 ... owner=name16, distribution=ubuntu, purpose=ArchivePurpose.PPA)
2620
2621=== modified file 'lib/lp/archiveuploader/tests/uploadpolicy.txt'
2622--- lib/lp/archiveuploader/tests/uploadpolicy.txt 2010-10-06 11:46:51 +0000
2623+++ lib/lp/archiveuploader/tests/uploadpolicy.txt 2010-10-21 19:08:55 +0000
2624@@ -78,8 +78,8 @@
2625 approve an upload automatically (I.E. move it straight to ACCEPTED
2626 instead of UNAPPROVED)
2627
2628- >>> from canonical.launchpad.interfaces import (
2629- ... SeriesStatus, IDistributionSet)
2630+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2631+ >>> from lp.registry.interfaces.series import SeriesStatus
2632 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
2633 >>> hoary = ubuntu['hoary']
2634
2635
2636=== modified file 'lib/lp/blueprints/doc/spec-mail-exploder.txt'
2637--- lib/lp/blueprints/doc/spec-mail-exploder.txt 2010-10-12 14:03:44 +0000
2638+++ lib/lp/blueprints/doc/spec-mail-exploder.txt 2010-10-21 19:08:55 +0000
2639@@ -268,8 +268,8 @@
2640 ... config.launchpad.specs_domain)
2641 >>> moin_change['Sender'] = 'webmaster@ubuntu.com'
2642
2643+ >>> from lp.services.mail.incoming import handleMail
2644 >>> from lp.services.mail.sendmail import sendmail
2645- >>> from lp.services.mail.incoming import handleMail
2646 >>> sendmail(moin_change, bulk=False)
2647 '...'
2648
2649
2650=== modified file 'lib/lp/blueprints/doc/specgraph.txt'
2651--- lib/lp/blueprints/doc/specgraph.txt 2010-07-30 12:56:27 +0000
2652+++ lib/lp/blueprints/doc/specgraph.txt 2010-10-21 19:08:55 +0000
2653@@ -256,8 +256,8 @@
2654 >>> from zope.component import getMultiAdapter
2655 >>> from lp.blueprints.browser.specification import (
2656 ... SpecificationTreeImageTag)
2657+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2658 >>> from lp.registry.interfaces.product import IProductSet
2659- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2660
2661 >>> firefox = getUtility(IProductSet).getByName('firefox')
2662 >>> svg_support = firefox.getSpecification('svg-support')
2663
2664=== modified file 'lib/lp/blueprints/doc/specification-branch.txt'
2665--- lib/lp/blueprints/doc/specification-branch.txt 2010-07-30 12:56:27 +0000
2666+++ lib/lp/blueprints/doc/specification-branch.txt 2010-10-21 19:08:55 +0000
2667@@ -14,8 +14,8 @@
2668 >>> from zope.component import getUtility
2669 >>> from canonical.launchpad.interfaces.launchpad import (
2670 ... ILaunchpadCelebrities)
2671+ >>> from lp.code.interfaces.branchlookup import IBranchLookup
2672 >>> from lp.registry.interfaces.person import IPersonSet
2673- >>> from lp.code.interfaces.branchlookup import IBranchLookup
2674
2675 >>> ubuntu = getUtility(ILaunchpadCelebrities).ubuntu
2676 >>> spec = ubuntu.getSpecification('media-integrity-check')
2677
2678=== modified file 'lib/lp/blueprints/doc/specification-notifications.txt'
2679--- lib/lp/blueprints/doc/specification-notifications.txt 2010-07-30 12:56:27 +0000
2680+++ lib/lp/blueprints/doc/specification-notifications.txt 2010-10-21 19:08:55 +0000
2681@@ -8,8 +8,8 @@
2682 Changing the status:
2683
2684 >>> from zope.component import getMultiAdapter
2685+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2686 >>> from lp.registry.interfaces.product import IProductSet
2687- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2688
2689 >>> login('foo.bar@canonical.com')
2690 >>> firefox = getUtility(IProductSet).getByName('firefox')
2691
2692=== modified file 'lib/lp/blueprints/doc/specification.txt'
2693--- lib/lp/blueprints/doc/specification.txt 2010-07-30 12:56:27 +0000
2694+++ lib/lp/blueprints/doc/specification.txt 2010-10-21 19:08:55 +0000
2695@@ -117,9 +117,9 @@
2696 ISpecification.getDelta(). If there are no changes, None will be
2697 returned:
2698
2699+ >>> from zope.interface import providedBy
2700+ >>> from lazr.lifecycle.snapshot import Snapshot
2701 >>> from lp.bugs.interfaces.bug import IBugSet
2702- >>> from lazr.lifecycle.snapshot import Snapshot
2703- >>> from zope.interface import providedBy
2704 >>> unmodified_spec = Snapshot(ubuspec, providing=providedBy(ubuspec))
2705 >>> ubuspec.getDelta(unmodified_spec, jdub) is None
2706 True
2707
2708=== modified file 'lib/lp/blueprints/doc/sprint-agenda.txt'
2709--- lib/lp/blueprints/doc/sprint-agenda.txt 2009-07-24 12:55:03 +0000
2710+++ lib/lp/blueprints/doc/sprint-agenda.txt 2010-10-21 19:08:55 +0000
2711@@ -9,8 +9,8 @@
2712 First, lets get hold of some people, a product, a sprint and a spec.
2713
2714 >>> from lp.blueprints.model.sprint import SprintSet
2715+ >>> from lp.registry.model.person import PersonSet
2716 >>> from lp.registry.model.product import ProductSet
2717- >>> from lp.registry.model.person import PersonSet
2718 >>> upstream_firefox = ProductSet()['firefox']
2719 >>> canvas = upstream_firefox.getSpecification('canvas')
2720 >>> guacamole = SprintSet()['uds-guacamole']
2721
2722=== modified file 'lib/lp/blueprints/doc/sprint-meeting-export.txt'
2723--- lib/lp/blueprints/doc/sprint-meeting-export.txt 2010-07-30 12:56:27 +0000
2724+++ lib/lp/blueprints/doc/sprint-meeting-export.txt 2010-10-21 19:08:55 +0000
2725@@ -13,10 +13,10 @@
2726 >>> from pytz import timezone
2727 >>> from zope.component import getUtility, getMultiAdapter
2728 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2729+ >>> from lp.blueprints.browser.sprint import SprintMeetingExportView
2730+ >>> from lp.blueprints.interfaces.sprint import ISprintSet
2731 >>> from lp.registry.interfaces.person import IPersonSet
2732 >>> from lp.registry.interfaces.product import IProductSet
2733- >>> from lp.blueprints.interfaces.sprint import ISprintSet
2734- >>> from lp.blueprints.browser.sprint import SprintMeetingExportView
2735
2736 Look up a few Launchpad objects to be used in the tests
2737
2738
2739=== modified file 'lib/lp/blueprints/doc/sprint.txt'
2740--- lib/lp/blueprints/doc/sprint.txt 2010-07-30 12:56:27 +0000
2741+++ lib/lp/blueprints/doc/sprint.txt 2010-10-21 19:08:55 +0000
2742@@ -4,8 +4,8 @@
2743 Sprints or meetings can be coordinated using Launchpad.
2744
2745 >>> from zope.component import getUtility
2746+ >>> from lp.blueprints.interfaces.sprint import ISprintSet
2747 >>> from lp.registry.interfaces.person import IPersonSet
2748- >>> from lp.blueprints.interfaces.sprint import ISprintSet
2749 >>> sprintset = getUtility(ISprintSet)
2750
2751 To find a sprint by name, use:
2752@@ -15,9 +15,9 @@
2753 The major pillars, product, distribution and project, have some
2754 properties which give us the sprints relevant to them.
2755
2756+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2757 >>> from lp.registry.interfaces.product import IProductSet
2758 >>> from lp.registry.interfaces.projectgroup import IProjectGroupSet
2759- >>> from lp.registry.interfaces.distribution import IDistributionSet
2760
2761 >>> productset = getUtility(IProductSet)
2762 >>> projectset = getUtility(IProjectGroupSet)
2763@@ -156,8 +156,8 @@
2764
2765 Inactive products are excluded from the listings.
2766
2767- >>> from lp.registry.interfaces.product import IProductSet
2768 >>> from canonical.launchpad.ftests import login
2769+ >>> from lp.registry.interfaces.product import IProductSet
2770
2771 >>> firefox = getUtility(IProductSet).getByName('firefox')
2772 >>> login("foo.bar@canonical.com")
2773
2774=== modified file 'lib/lp/blueprints/stories/sprints/20-sprint-registration.txt'
2775--- lib/lp/blueprints/stories/sprints/20-sprint-registration.txt 2010-07-30 12:56:27 +0000
2776+++ lib/lp/blueprints/stories/sprints/20-sprint-registration.txt 2010-10-21 19:08:55 +0000
2777@@ -157,9 +157,9 @@
2778 First, we add a couple of IRC nicknames for Carlos.
2779
2780 >>> from canonical.launchpad.ftests import login, logout
2781+ >>> from zope.component import getUtility
2782 >>> from lp.registry.interfaces.person import IPersonSet
2783 >>> from lp.registry.model.person import IrcID
2784- >>> from zope.component import getUtility
2785 >>> login('carlos@canonical.com')
2786 >>> carlos = getUtility(IPersonSet).getByName('carlos')
2787 >>> IrcID(person=carlos, network='freenode', nickname='carlos')
2788
2789=== modified file 'lib/lp/bugs/browser/tests/bug-nomination-views.txt'
2790--- lib/lp/bugs/browser/tests/bug-nomination-views.txt 2010-10-11 16:17:45 +0000
2791+++ lib/lp/bugs/browser/tests/bug-nomination-views.txt 2010-10-21 19:08:55 +0000
2792@@ -7,9 +7,9 @@
2793
2794 >>> from zope.component import getUtility, getMultiAdapter
2795
2796- >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
2797 >>> from canonical.launchpad.webapp.interfaces import IOpenLaunchBag
2798 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2799+ >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
2800
2801 >>> login("no-priv@canonical.com")
2802
2803
2804=== modified file 'lib/lp/bugs/browser/tests/bug-views.txt'
2805--- lib/lp/bugs/browser/tests/bug-views.txt 2010-10-14 18:42:19 +0000
2806+++ lib/lp/bugs/browser/tests/bug-views.txt 2010-10-21 19:08:55 +0000
2807@@ -27,10 +27,19 @@
2808 comment, of the bug report.
2809
2810 >>> from zope.component import getMultiAdapter, getUtility
2811- >>> from canonical.launchpad.interfaces import (
2812- ... BugTaskSearchParams, IDistributionSet, IBugSet, IBugTaskSet,
2813- ... ILaunchBag, IOpenLaunchBag, IPersonSet, IProductSet)
2814+ >>> from canonical.launchpad.webapp.interfaces import (
2815+ ... ILaunchBag,
2816+ ... IOpenLaunchBag,
2817+ ... )
2818 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2819+ >>> from lp.bugs.interfaces.bug import IBugSet
2820+ >>> from lp.bugs.interfaces.bugtask import (
2821+ ... BugTaskSearchParams,
2822+ ... IBugTaskSet,
2823+ ... )
2824+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2825+ >>> from lp.registry.interfaces.person import IPersonSet
2826+ >>> from lp.registry.interfaces.product import IProductSet
2827
2828 >>> launchbag = getUtility(IOpenLaunchBag)
2829 >>> login("foo.bar@canonical.com")
2830@@ -444,8 +453,8 @@
2831 returned results, because an approved nomination will have created a
2832 task anyway.
2833
2834+ >>> from lp.bugs.interfaces.bugnomination import IBugNomination
2835 >>> from lp.bugs.interfaces.bugtask import IBugTask
2836- >>> from lp.bugs.interfaces.bugnomination import IBugNomination
2837
2838 >>> def get_object_type(task_or_nomination):
2839 ... if IBugTask.providedBy(task_or_nomination):
2840
2841=== modified file 'lib/lp/bugs/browser/tests/buglinktarget-views.txt'
2842--- lib/lp/bugs/browser/tests/buglinktarget-views.txt 2010-10-03 15:30:06 +0000
2843+++ lib/lp/bugs/browser/tests/buglinktarget-views.txt 2010-10-21 19:08:55 +0000
2844@@ -4,9 +4,10 @@
2845
2846 >>> from zope.component import getMultiAdapter
2847 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2848- >>> from canonical.launchpad.interfaces import (
2849- ... IBugLinkTarget, IBugSet, ICveSet)
2850 >>> from lazr.lifecycle.event import ObjectModifiedEvent
2851+ >>> from lp.bugs.interfaces.bug import IBugSet
2852+ >>> from lp.bugs.interfaces.buglink import IBugLinkTarget
2853+ >>> from lp.bugs.interfaces.cve import ICveSet
2854
2855 >>> bugset = getUtility(IBugSet)
2856 >>> cve = getUtility(ICveSet)['2005-2730']
2857
2858=== modified file 'lib/lp/bugs/browser/tests/bugs-views.txt'
2859--- lib/lp/bugs/browser/tests/bugs-views.txt 2010-10-11 16:17:45 +0000
2860+++ lib/lp/bugs/browser/tests/bugs-views.txt 2010-10-21 19:08:55 +0000
2861@@ -4,9 +4,9 @@
2862 doesn't use its context for anything, so we don't have to supply one
2863 when creating it.
2864
2865- >>> from lp.bugs.browser.bug import MaloneView
2866 >>> from canonical.launchpad.systemhomes import MaloneApplication
2867 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2868+ >>> from lp.bugs.browser.bug import MaloneView
2869 >>> bugs_view = MaloneView(MaloneApplication(), LaunchpadTestRequest())
2870 >>> bugs_view.initialize()
2871
2872@@ -31,8 +31,8 @@
2873 in the future.
2874
2875 >>> login('test@canonical.com')
2876+ >>> from canonical.launchpad.ftests import syncUpdate
2877 >>> from lp.bugs.interfaces.bug import IBugSet
2878- >>> from canonical.launchpad.ftests import syncUpdate
2879 >>> bug_eight = getUtility(IBugSet).get(8)
2880 >>> len(bug_eight.bugtasks)
2881 1
2882
2883=== modified file 'lib/lp/bugs/browser/tests/bugtask-adding-views.txt'
2884--- lib/lp/bugs/browser/tests/bugtask-adding-views.txt 2010-10-09 16:36:22 +0000
2885+++ lib/lp/bugs/browser/tests/bugtask-adding-views.txt 2010-10-21 19:08:55 +0000
2886@@ -97,8 +97,8 @@
2887 most likely to get added. Let's take a look how it works for packages,
2888 which can have packaging links that helps us choose the product.
2889
2890- >>> from canonical.launchpad.interfaces import (
2891- ... CreateBugParams, IDistributionSet)
2892+ >>> from lp.bugs.interfaces.bug import CreateBugParams
2893+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2894 >>> owner = getUtility(ILaunchBag).user
2895 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
2896 >>> ubuntu_firefox = ubuntu.getSourcePackage('mozilla-firefox')
2897@@ -168,8 +168,8 @@
2898 event listener and register it:
2899
2900 >>> from zope.interface import Interface
2901+ >>> from canonical.launchpad.ftests.event import TestEventListener
2902 >>> from lazr.lifecycle.interfaces import IObjectCreatedEvent
2903- >>> from canonical.launchpad.ftests.event import TestEventListener
2904
2905 >>> def on_created_event(object, event):
2906 ... print "ObjectCreatedEvent: %r" % object
2907
2908=== modified file 'lib/lp/bugs/browser/tests/bugtask-edit-views.txt'
2909--- lib/lp/bugs/browser/tests/bugtask-edit-views.txt 2010-10-09 16:36:22 +0000
2910+++ lib/lp/bugs/browser/tests/bugtask-edit-views.txt 2010-10-21 19:08:55 +0000
2911@@ -10,8 +10,8 @@
2912 Person:
2913
2914 >>> from zope.component import getMultiAdapter
2915+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2916 >>> from lp.bugs.interfaces.bug import IBugSet
2917- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2918 >>> login('test@canonical.com')
2919 >>> bug_nine = getUtility(IBugSet).get(9)
2920 >>> ubuntu_thunderbird_task = bug_nine.bugtasks[1]
2921@@ -83,8 +83,8 @@
2922 distribution task already has, an error message will occur. First,
2923 let's add an evolution (Ubuntu) task to bug two.
2924
2925- >>> from canonical.launchpad.interfaces import (
2926- ... IBugTaskSet, IDistributionSet)
2927+ >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
2928+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2929 >>> bug_two = getUtility(IBugSet).get(2)
2930 >>> ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
2931 >>> ubuntu_evolution = ubuntu.getSourcePackage('evolution')
2932
2933=== modified file 'lib/lp/bugs/browser/tests/bugtask-search-views.txt'
2934--- lib/lp/bugs/browser/tests/bugtask-search-views.txt 2010-10-09 16:36:22 +0000
2935+++ lib/lp/bugs/browser/tests/bugtask-search-views.txt 2010-10-21 19:08:55 +0000
2936@@ -3,8 +3,8 @@
2937 In the 'Bugs' facet of a distribution we can find a list of bugs
2938 reported in that distribution and simple and advanced search forms.
2939
2940- >>> from canonical.launchpad.interfaces import (
2941- ... IOpenLaunchBag, IDistributionSet)
2942+ >>> from canonical.launchpad.webapp.interfaces import IOpenLaunchBag
2943+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2944 >>> launchbag = getUtility(IOpenLaunchBag)
2945 >>> debian = getUtility(IDistributionSet).getByName('debian')
2946
2947@@ -230,8 +230,8 @@
2948 And now we'll change the status of one of the bugtasks, but first we
2949 need to be logged in.
2950
2951+ >>> from canonical.database.sqlbase import flush_database_updates
2952 >>> from canonical.launchpad.ftests import login
2953- >>> from canonical.database.sqlbase import flush_database_updates
2954
2955 >>> login("test@canonical.com")
2956
2957
2958=== modified file 'lib/lp/bugs/browser/tests/distrosourcepackage-bug-views.txt'
2959--- lib/lp/bugs/browser/tests/distrosourcepackage-bug-views.txt 2010-10-03 15:30:06 +0000
2960+++ lib/lp/bugs/browser/tests/distrosourcepackage-bug-views.txt 2010-10-21 19:08:55 +0000
2961@@ -5,9 +5,9 @@
2962 Simple searching is possible on the distro source package bug view page.
2963
2964 >>> from zope.component import getMultiAdapter, getUtility
2965- >>> from canonical.launchpad.interfaces import (
2966- ... IDistributionSet, ISourcePackageNameSet)
2967 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
2968+ >>> from lp.registry.interfaces.distribution import IDistributionSet
2969+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
2970
2971 >>> debian = getUtility(IDistributionSet).get(3)
2972 >>> mozilla_firefox = getUtility(ISourcePackageNameSet).get(1)
2973
2974=== modified file 'lib/lp/bugs/browser/tests/person-bug-views.txt'
2975--- lib/lp/bugs/browser/tests/person-bug-views.txt 2010-10-09 16:36:22 +0000
2976+++ lib/lp/bugs/browser/tests/person-bug-views.txt 2010-10-21 19:08:55 +0000
2977@@ -87,8 +87,8 @@
2978 Using the advanced form we can also query for closed bugs reported by someone.
2979 Let's first close a bug setting its status to 'Invalid'.
2980
2981+ >>> from canonical.database.sqlbase import flush_database_updates
2982 >>> from canonical.launchpad.ftests import login
2983- >>> from canonical.database.sqlbase import flush_database_updates
2984
2985 >>> login("foo.bar@canonical.com")
2986
2987
2988=== modified file 'lib/lp/bugs/doc/bug-change.txt'
2989--- lib/lp/bugs/doc/bug-change.txt 2010-10-03 15:30:06 +0000
2990+++ lib/lp/bugs/doc/bug-change.txt 2010-10-21 19:08:55 +0000
2991@@ -3,10 +3,10 @@
2992 The base class for BugChanges doesn't actually implement anything.
2993
2994 >>> import pytz
2995+ >>> from canonical.launchpad.webapp.testing import verifyObject
2996 >>> from datetime import datetime
2997 >>> from lp.bugs.adapters.bugchange import BugChangeBase
2998 >>> from lp.bugs.interfaces.bugchange import IBugChange
2999- >>> from canonical.launchpad.webapp.testing import verifyObject
3000
3001 >>> from lp.testing.factory import LaunchpadObjectFactory
3002 >>> factory = LaunchpadObjectFactory()
3003
3004=== modified file 'lib/lp/bugs/doc/bug-export.txt'
3005--- lib/lp/bugs/doc/bug-export.txt 2010-10-03 15:30:06 +0000
3006+++ lib/lp/bugs/doc/bug-export.txt 2010-10-21 19:08:55 +0000
3007@@ -23,10 +23,11 @@
3008 ... import xml.etree.cElementTree as ET
3009 ... except ImportError:
3010 ... import cElementTree as ET
3011+ >>> from zope.component import getUtility
3012 >>> from cStringIO import StringIO
3013- >>> from zope.component import getUtility
3014- >>> from canonical.launchpad.interfaces import (
3015- ... IBugSet, IPersonSet, IProductSet)
3016+ >>> from lp.bugs.interfaces.bug import IBugSet
3017+ >>> from lp.registry.interfaces.person import IPersonSet
3018+ >>> from lp.registry.interfaces.product import IProductSet
3019 >>> from lp.bugs.scripts.bugexport import (
3020 ... serialise_bugtask, export_bugtasks)
3021
3022
3023=== modified file 'lib/lp/bugs/doc/bug-nomination.txt'
3024--- lib/lp/bugs/doc/bug-nomination.txt 2010-10-09 16:36:22 +0000
3025+++ lib/lp/bugs/doc/bug-nomination.txt 2010-10-21 19:08:55 +0000
3026@@ -6,9 +6,9 @@
3027
3028 >>> from zope.component import getUtility
3029 >>> from zope.interface.verify import verifyClass
3030- >>> from lp.bugs.model.bugnomination import BugNomination
3031 >>> from lp.bugs.interfaces.bug import IBugSet
3032 >>> from lp.bugs.interfaces.bugnomination import IBugNomination
3033+ >>> from lp.bugs.model.bugnomination import BugNomination
3034 >>> from lp.registry.interfaces.distribution import IDistributionSet
3035 >>> from lp.registry.interfaces.person import IPersonSet
3036
3037
3038=== modified file 'lib/lp/bugs/doc/bug-private-by-default.txt'
3039--- lib/lp/bugs/doc/bug-private-by-default.txt 2010-10-04 19:50:45 +0000
3040+++ lib/lp/bugs/doc/bug-private-by-default.txt 2010-10-21 19:08:55 +0000
3041@@ -4,8 +4,9 @@
3042 (this is enforced by a DB constraint).
3043
3044 >>> from canonical.testing.layers import LaunchpadZopelessLayer
3045- >>> from canonical.launchpad.interfaces import (
3046- ... IPersonSet, CreateBugParams, IProductSet)
3047+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3048+ >>> from lp.registry.interfaces.person import IPersonSet
3049+ >>> from lp.registry.interfaces.product import IProductSet
3050 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
3051 >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
3052 >>> name16 = getUtility(IPersonSet).get(16)
3053
3054=== modified file 'lib/lp/bugs/doc/bug-reported-acknowledgement.txt'
3055--- lib/lp/bugs/doc/bug-reported-acknowledgement.txt 2010-10-09 16:36:22 +0000
3056+++ lib/lp/bugs/doc/bug-reported-acknowledgement.txt 2010-10-21 19:08:55 +0000
3057@@ -7,8 +7,9 @@
3058
3059 >>> login('foo.bar@canonical.com')
3060
3061- >>> from canonical.launchpad.interfaces import (
3062- ... IDistributionSet, IProjectGroupSet, IProductSet)
3063+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3064+ >>> from lp.registry.interfaces.product import IProductSet
3065+ >>> from lp.registry.interfaces.projectgroup import IProjectGroupSet
3066
3067 >>> distribution = getUtility(IDistributionSet).getByName('ubuntu')
3068 >>> distribution_source_package = (
3069
3070=== modified file 'lib/lp/bugs/doc/bug-reporting-guidelines.txt'
3071--- lib/lp/bugs/doc/bug-reporting-guidelines.txt 2010-10-09 16:36:22 +0000
3072+++ lib/lp/bugs/doc/bug-reporting-guidelines.txt 2010-10-21 19:08:55 +0000
3073@@ -6,8 +6,9 @@
3074
3075 >>> login('foo.bar@canonical.com')
3076
3077- >>> from canonical.launchpad.interfaces import (
3078- ... IDistributionSet, IProjectGroupSet, IProductSet)
3079+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3080+ >>> from lp.registry.interfaces.product import IProductSet
3081+ >>> from lp.registry.interfaces.projectgroup import IProjectGroupSet
3082
3083 >>> distribution = getUtility(IDistributionSet).getByName('ubuntu')
3084 >>> distribution_source_package = (
3085
3086=== modified file 'lib/lp/bugs/doc/bug-set-status.txt'
3087--- lib/lp/bugs/doc/bug-set-status.txt 2010-10-09 16:36:22 +0000
3088+++ lib/lp/bugs/doc/bug-set-status.txt 2010-10-21 19:08:55 +0000
3089@@ -10,9 +10,9 @@
3090 >>> login('no-priv@canonical.com')
3091 >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
3092
3093- >>> from canonical.launchpad.interfaces import (
3094- ... CreateBugParams, IProductSet)
3095+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3096 >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
3097+ >>> from lp.registry.interfaces.product import IProductSet
3098 >>> bug_params = CreateBugParams(
3099 ... owner=no_priv, title='Sample bug', comment='This is a sample bug.')
3100 >>> firefox = getUtility(IProductSet).getByName('firefox')
3101
3102=== modified file 'lib/lp/bugs/doc/bug-tags.txt'
3103--- lib/lp/bugs/doc/bug-tags.txt 2010-10-11 16:17:45 +0000
3104+++ lib/lp/bugs/doc/bug-tags.txt 2010-10-21 19:08:55 +0000
3105@@ -67,9 +67,9 @@
3106 To make it easy editing the tags as a space separated text string, we
3107 use BugTagsWidget.
3108
3109- >>> from lp.bugs.interfaces.bug import IBug
3110 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3111 >>> from canonical.widgets.bug import BugTagsWidget
3112+ >>> from lp.bugs.interfaces.bug import IBug
3113 >>> bug_tags_field = IBug['tags'].bind(bug_one)
3114 >>> tag_field = bug_tags_field.value_type
3115 >>> request = LaunchpadTestRequest()
3116@@ -178,9 +178,9 @@
3117
3118 We can search for bugs with some specific tag.
3119
3120- >>> from canonical.launchpad.interfaces import (
3121- ... BugTaskSearchParams, IDistributionSet)
3122 >>> from canonical.launchpad.searchbuilder import all
3123+ >>> from lp.bugs.interfaces.bugtask import BugTaskSearchParams
3124+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3125 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
3126 >>> svg_tasks = ubuntu.searchTasks(
3127 ... BugTaskSearchParams(tag=all(u'svg'), user=None))
3128
3129=== modified file 'lib/lp/bugs/doc/bug.txt'
3130--- lib/lp/bugs/doc/bug.txt 2010-08-30 05:19:46 +0000
3131+++ lib/lp/bugs/doc/bug.txt 2010-10-21 19:08:55 +0000
3132@@ -313,8 +313,8 @@
3133 Note that a search will return all public bugs, omitting bug 14 which is
3134 private:
3135
3136+ >>> from canonical.launchpad.interfaces.lpstorm import IStore
3137 >>> from lp.bugs.model.bug import Bug
3138- >>> from canonical.launchpad.interfaces.lpstorm import IStore
3139 >>> all_bugs = set(IStore(Bug).find(Bug).values(Bug.id))
3140
3141 >>> def hidden_bugs():
3142
3143=== modified file 'lib/lp/bugs/doc/bugactivity.txt'
3144--- lib/lp/bugs/doc/bugactivity.txt 2010-10-09 16:36:22 +0000
3145+++ lib/lp/bugs/doc/bugactivity.txt 2010-10-21 19:08:55 +0000
3146@@ -22,9 +22,13 @@
3147 >>> from zope.event import notify
3148 >>> from lazr.lifecycle.event import (
3149 ... ObjectCreatedEvent, ObjectModifiedEvent)
3150- >>> from canonical.launchpad.interfaces import (
3151- ... IUpstreamBugTask, IDistroBugTask, IProductSet, IBugTaskSet)
3152 >>> from lazr.lifecycle.snapshot import Snapshot
3153+ >>> from lp.bugs.interfaces.bugtask import (
3154+ ... IBugTaskSet,
3155+ ... IDistroBugTask,
3156+ ... IUpstreamBugTask,
3157+ ... )
3158+ >>> from lp.registry.interfaces.product import IProductSet
3159 >>> user = getUtility(ILaunchBag).user
3160
3161
3162@@ -67,8 +71,8 @@
3163
3164 >>> from lazr.lifecycle.snapshot import Snapshot
3165 >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
3166- >>> from canonical.launchpad.interfaces import (
3167- ... ISourcePackageNameSet, IDistributionSet)
3168+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3169+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
3170 >>> mozilla_firefox = getUtility(ISourcePackageNameSet)['mozilla-firefox']
3171 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
3172 >>> source_package_assignment = getUtility(IBugTaskSet).createTask(
3173
3174=== modified file 'lib/lp/bugs/doc/bugattachments.txt'
3175--- lib/lp/bugs/doc/bugattachments.txt 2010-10-03 15:30:06 +0000
3176+++ lib/lp/bugs/doc/bugattachments.txt 2010-10-21 19:08:55 +0000
3177@@ -10,8 +10,10 @@
3178 >>> from canonical.launchpad.ftests import login
3179 >>> login("foo.bar@canonical.com")
3180
3181- >>> from canonical.launchpad.interfaces import (
3182- ... IBugAttachment, IBugSet, IMessageSet, IPersonSet)
3183+ >>> from canonical.launchpad.interfaces.message import IMessageSet
3184+ >>> from lp.bugs.interfaces.bug import IBugSet
3185+ >>> from lp.bugs.interfaces.bugattachment import IBugAttachment
3186+ >>> from lp.registry.interfaces.person import IPersonSet
3187 >>> bugset = getUtility(IBugSet)
3188 >>> bug_one = bugset.get(1)
3189 >>> bug_one.attachments.count()
3190@@ -382,8 +384,11 @@
3191
3192 We can search for attachment of a specific types:
3193
3194- >>> from canonical.launchpad.interfaces import (
3195- ... BugAttachmentType, BugTaskSearchParams, IBugTaskSet)
3196+ >>> from lp.bugs.interfaces.bugattachment import BugAttachmentType
3197+ >>> from lp.bugs.interfaces.bugtask import (
3198+ ... BugTaskSearchParams,
3199+ ... IBugTaskSet,
3200+ ... )
3201 >>> bugtaskset = getUtility(IBugTaskSet)
3202 >>> attachmenttype = BugAttachmentType.UNSPECIFIED
3203 >>> params = BugTaskSearchParams(attachmenttype=attachmenttype, user=None)
3204
3205=== modified file 'lib/lp/bugs/doc/bugcomment.txt'
3206--- lib/lp/bugs/doc/bugcomment.txt 2010-10-14 18:42:19 +0000
3207+++ lib/lp/bugs/doc/bugcomment.txt 2010-10-21 19:08:55 +0000
3208@@ -5,8 +5,8 @@
3209 independently.
3210
3211 >>> from zope.component import getMultiAdapter
3212+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3213 >>> from lp.bugs.interfaces.bug import IBugSet
3214- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3215
3216
3217 == Handling of the bug's first comment ==
3218
3219=== modified file 'lib/lp/bugs/doc/bugmessage-visibility.txt'
3220--- lib/lp/bugs/doc/bugmessage-visibility.txt 2010-10-09 16:36:22 +0000
3221+++ lib/lp/bugs/doc/bugmessage-visibility.txt 2010-10-21 19:08:55 +0000
3222@@ -6,8 +6,8 @@
3223 A bug message has a visible field, which is True by default.
3224
3225 # Setup for creating a new message
3226+ >>> from lp.bugs.interfaces.bug import IBugSet
3227 >>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
3228- >>> from lp.bugs.interfaces.bug import IBugSet
3229 >>> from lp.registry.interfaces.person import IPersonSet
3230
3231 >>> bugmessageset = getUtility(IBugMessageSet)
3232
3233=== modified file 'lib/lp/bugs/doc/bugnotification-email.txt'
3234--- lib/lp/bugs/doc/bugnotification-email.txt 2010-10-09 16:36:22 +0000
3235+++ lib/lp/bugs/doc/bugnotification-email.txt 2010-10-21 19:08:55 +0000
3236@@ -28,9 +28,13 @@
3237 examples that follow:
3238
3239 >>> from zope.component import getUtility
3240- >>> from canonical.launchpad.interfaces import (
3241- ... IBugDelta, IBugSet, IEmailAddressSet, IPersonSet)
3242+ >>> from canonical.launchpad.interfaces.emailaddress import IEmailAddressSet
3243 >>> from lp.bugs.adapters.bugdelta import BugDelta
3244+ >>> from lp.bugs.interfaces.bug import (
3245+ ... IBugDelta,
3246+ ... IBugSet,
3247+ ... )
3248+ >>> from lp.registry.interfaces.person import IPersonSet
3249
3250 = Filing a bug =
3251
3252@@ -280,10 +284,13 @@
3253
3254 We use a BugTaskDelta to represent changes to a BugTask.
3255
3256- >>> from canonical.launchpad.interfaces import (
3257- ... BugTaskStatus, IBugTaskDelta, IBugTaskSet)
3258+ >>> from canonical.launchpad.webapp.testing import verifyObject
3259+ >>> from lp.bugs.interfaces.bugtask import (
3260+ ... BugTaskStatus,
3261+ ... IBugTaskDelta,
3262+ ... IBugTaskSet,
3263+ ... )
3264 >>> from lp.bugs.model.bugtask import BugTaskDelta
3265- >>> from canonical.launchpad.webapp.testing import verifyObject
3266 >>> example_bug_task = factory.makeBugTask()
3267 >>> example_delta = BugTaskDelta(example_bug_task)
3268 >>> verifyObject(IBugTaskDelta, example_delta)
3269
3270=== modified file 'lib/lp/bugs/doc/bugnotification-sending.txt'
3271--- lib/lp/bugs/doc/bugnotification-sending.txt 2010-10-11 16:17:45 +0000
3272+++ lib/lp/bugs/doc/bugnotification-sending.txt 2010-10-21 19:08:55 +0000
3273@@ -54,8 +54,8 @@
3274 Anyway, let's start our demonstration by adding a comment to a bug:
3275
3276 >>> login('test@canonical.com')
3277+ >>> from canonical.launchpad.interfaces.message import IMessageSet
3278 >>> from lp.bugs.interfaces.bug import IBugSet
3279- >>> from canonical.launchpad.interfaces.message import IMessageSet
3280 >>> bug_one = getUtility(IBugSet).get(1)
3281 >>> sample_person = getUtility(ILaunchBag).user
3282 >>> comment = getUtility(IMessageSet).fromText(
3283@@ -374,8 +374,8 @@
3284
3285 We will also need a fresh new bug.
3286
3287- >>> from canonical.launchpad.interfaces import (
3288- ... IDistributionSet, CreateBugParams)
3289+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3290+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3291 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
3292 >>> description = getUtility(IMessageSet).fromText(
3293 ... 'subject', 'a description of the bug.', sample_person,
3294
3295=== modified file 'lib/lp/bugs/doc/bugnotification-threading.txt'
3296--- lib/lp/bugs/doc/bugnotification-threading.txt 2010-10-11 16:17:45 +0000
3297+++ lib/lp/bugs/doc/bugnotification-threading.txt 2010-10-21 19:08:55 +0000
3298@@ -9,8 +9,8 @@
3299
3300 Let's add add change notification and see how it works:
3301
3302+ >>> from canonical.database.sqlbase import flush_database_updates
3303 >>> from canonical.launchpad.database import MessageSet
3304- >>> from canonical.database.sqlbase import flush_database_updates
3305
3306 >>> login('test@canonical.com')
3307
3308
3309=== modified file 'lib/lp/bugs/doc/bugnotificationrecipients.txt'
3310--- lib/lp/bugs/doc/bugnotificationrecipients.txt 2010-10-09 16:36:22 +0000
3311+++ lib/lp/bugs/doc/bugnotificationrecipients.txt 2010-10-21 19:08:55 +0000
3312@@ -11,16 +11,16 @@
3313 action:
3314
3315 >>> from lp.bugs.model.bug import Bug
3316+ >>> from lp.registry.model.distribution import Distribution
3317 >>> from lp.registry.model.product import Product
3318- >>> from lp.registry.model.distribution import Distribution
3319 >>> bug_one = Bug.get(1)
3320 >>> recipients = bug_one.getBugNotificationRecipients()
3321
3322 The instance of BugNotificationRecipients we get back correctly
3323 implements INotificationRecipientSet:
3324
3325+ >>> from canonical.launchpad.interfaces.launchpad import INotificationRecipientSet
3326 >>> from canonical.launchpad.webapp.testing import verifyObject
3327- >>> from canonical.launchpad.interfaces.launchpad import INotificationRecipientSet
3328 >>> verifyObject(INotificationRecipientSet, recipients)
3329 True
3330
3331
3332=== modified file 'lib/lp/bugs/doc/bugnotifications.txt'
3333--- lib/lp/bugs/doc/bugnotifications.txt 2010-10-10 15:39:28 +0000
3334+++ lib/lp/bugs/doc/bugnotifications.txt 2010-10-21 19:08:55 +0000
3335@@ -26,9 +26,12 @@
3336 >>> from zope.event import notify
3337 >>> from lazr.lifecycle.event import (
3338 ... ObjectModifiedEvent, ObjectCreatedEvent)
3339- >>> from canonical.launchpad.interfaces import (
3340- ... CreateBugParams, IDistributionSet, IDistroSeriesSet, IPersonSet,
3341- ... IProductSet, ISourcePackageNameSet)
3342+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3343+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3344+ >>> from lp.registry.interfaces.distroseries import IDistroSeriesSet
3345+ >>> from lp.registry.interfaces.person import IPersonSet
3346+ >>> from lp.registry.interfaces.product import IProductSet
3347+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
3348
3349 >>> bug_submitter = getUtility(IPersonSet).get(12)
3350 >>> firefox = getUtility(IProductSet).get(4)
3351@@ -51,8 +54,8 @@
3352
3353 === Editing a bug report ===
3354
3355+ >>> from lazr.lifecycle.snapshot import Snapshot
3356 >>> from lp.bugs.interfaces.bug import IBug
3357- >>> from lazr.lifecycle.snapshot import Snapshot
3358 >>> bug_before_modification = Snapshot(firefox_crashes, providing=IBug)
3359 >>> firefox_crashes.description = "a new description"
3360 >>> firefox_crashes_modified = ObjectModifiedEvent(
3361@@ -207,9 +210,11 @@
3362 Let's demonstrate a notification email where Sample Person marks a
3363 task Fixed, and assigns himself to it.
3364
3365- >>> from canonical.launchpad.interfaces import (
3366- ... BugTaskStatus, IDistroBugTask)
3367 >>> from lazr.lifecycle.snapshot import Snapshot
3368+ >>> from lp.bugs.interfaces.bugtask import (
3369+ ... BugTaskStatus,
3370+ ... IDistroBugTask,
3371+ ... )
3372
3373 >>> bugtask_before_modification = Snapshot(
3374 ... firefox_crashes_in_debian, providing=IDistroBugTask)
3375
3376=== modified file 'lib/lp/bugs/doc/bugsubscription.txt'
3377--- lib/lp/bugs/doc/bugsubscription.txt 2010-10-15 14:26:57 +0000
3378+++ lib/lp/bugs/doc/bugsubscription.txt 2010-10-21 19:08:55 +0000
3379@@ -12,8 +12,8 @@
3380
3381 IBug has a subscriptions attribute:
3382
3383+ >>> from zope.component import getUtility
3384 >>> from lp.bugs.interfaces.bug import IBugSet
3385- >>> from zope.component import getUtility
3386 >>> bugset = getUtility(IBugSet)
3387 >>> bug = bugset.get(1)
3388 >>> bug.subscriptions.count()
3389@@ -43,8 +43,10 @@
3390 Let's create a new bug to demonstrate how direct and indirect
3391 subscriptions work.
3392
3393- >>> from canonical.launchpad.interfaces import (
3394- ... IDistributionSet, ILaunchBag, IPersonSet, CreateBugParams)
3395+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
3396+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3397+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3398+ >>> from lp.registry.interfaces.person import IPersonSet
3399 >>> ubuntu = getUtility(IDistributionSet).getByName("ubuntu")
3400 >>> personset = getUtility(IPersonSet)
3401
3402
3403=== modified file 'lib/lp/bugs/doc/bugtarget.txt'
3404--- lib/lp/bugs/doc/bugtarget.txt 2010-10-03 15:30:06 +0000
3405+++ lib/lp/bugs/doc/bugtarget.txt 2010-10-21 19:08:55 +0000
3406@@ -12,8 +12,9 @@
3407 target (such as in filterable e-mail messages).
3408
3409 >>> from zope.component import getUtility
3410- >>> from canonical.launchpad.interfaces import (
3411- ... IBugTarget, IDistributionSet, IProductSet)
3412+ >>> from lp.bugs.interfaces.bugtarget import IBugTarget
3413+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3414+ >>> from lp.registry.interfaces.product import IProductSet
3415 >>> distroset = getUtility(IDistributionSet)
3416 >>> debian = distroset.getByName("debian")
3417 >>> debian_firefox = debian.getSourcePackage("mozilla-firefox")
3418
3419=== modified file 'lib/lp/bugs/doc/bugtask-bugwatch-widget.txt'
3420--- lib/lp/bugs/doc/bugtask-bugwatch-widget.txt 2010-10-09 16:36:22 +0000
3421+++ lib/lp/bugs/doc/bugtask-bugwatch-widget.txt 2010-10-21 19:08:55 +0000
3422@@ -19,8 +19,8 @@
3423
3424 Now we can create a widget using a test request:
3425
3426+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3427 >>> from canonical.widgets.bugtask import BugTaskBugWatchWidget
3428- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3429 >>> request = LaunchpadTestRequest()
3430 >>> bugwatch_widget = BugTaskBugWatchWidget(
3431 ... bugwatch_field, bugwatch_field.vocabulary, request)
3432
3433=== modified file 'lib/lp/bugs/doc/bugtask-expiration.txt'
3434--- lib/lp/bugs/doc/bugtask-expiration.txt 2010-10-09 16:36:22 +0000
3435+++ lib/lp/bugs/doc/bugtask-expiration.txt 2010-10-21 19:08:55 +0000
3436@@ -31,9 +31,11 @@
3437 (min_days_old) that the bugtask has been in the unattended Incomplete
3438 status. It also requires specifying the user that is doing the search.
3439
3440+ >>> from lp.bugs.interfaces.bugtask import (
3441+ ... BugTaskStatus,
3442+ ... IBugTaskSet,
3443+ ... )
3444 >>> from storm.store import Store
3445- >>> from canonical.launchpad.interfaces import (
3446- ... BugTaskStatus, IBugTaskSet)
3447 >>> bugtaskset = getUtility(IBugTaskSet)
3448
3449 >>> expirable_bugtasks = bugtaskset.findExpirableBugTasks()
3450@@ -64,8 +66,9 @@
3451 can_expire avoid an expensive db, in the case where we can easily tell
3452 that no bug tasks can be expired.
3453
3454- >>> from canonical.launchpad.interfaces import (
3455- ... IDistributionSet, IPersonSet, IProductSet)
3456+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3457+ >>> from lp.registry.interfaces.person import IPersonSet
3458+ >>> from lp.registry.interfaces.product import IProductSet
3459 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
3460 >>> jokosher = getUtility(IProductSet).getByName('jokosher')
3461 >>> sample_person = getUtility(IPersonSet).getByEmail(
3462
3463=== modified file 'lib/lp/bugs/doc/bugtask-find-similar.txt'
3464--- lib/lp/bugs/doc/bugtask-find-similar.txt 2010-10-09 16:36:22 +0000
3465+++ lib/lp/bugs/doc/bugtask-find-similar.txt 2010-10-21 19:08:55 +0000
3466@@ -11,8 +11,9 @@
3467 It doesn't make much sense to find bugs similar to an empty string, so
3468 no results will be returned.
3469
3470- >>> from canonical.launchpad.interfaces import (
3471- ... IBugTaskSet, IPersonSet, IProductSet)
3472+ >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
3473+ >>> from lp.registry.interfaces.person import IPersonSet
3474+ >>> from lp.registry.interfaces.product import IProductSet
3475 >>> firefox = getUtility(IProductSet).getByName('firefox')
3476 >>> sample_person = getUtility(IPersonSet).getByEmail('test@canonical.com')
3477 >>> similar_bugs = getUtility(IBugTaskSet).findSimilar(
3478@@ -80,8 +81,8 @@
3479 the Firefox bug to private, and repeat the search as a user who isn't
3480 allowed to view it, only the Thunderbird bug will be returned this time.
3481
3482+ >>> from canonical.launchpad.ftests import syncUpdate
3483 >>> from lp.bugs.interfaces.bug import IBugSet
3484- >>> from canonical.launchpad.ftests import syncUpdate
3485 >>> login('test@canonical.com')
3486 >>> firefox_svg_bug = getUtility(IBugSet).get(1)
3487 >>> firefox_svg_bug.setPrivate(True, getUtility(ILaunchBag).user)
3488
3489=== modified file 'lib/lp/bugs/doc/bugtask-package-widget.txt'
3490--- lib/lp/bugs/doc/bugtask-package-widget.txt 2010-10-10 15:39:28 +0000
3491+++ lib/lp/bugs/doc/bugtask-package-widget.txt 2010-10-21 19:08:55 +0000
3492@@ -12,9 +12,9 @@
3493 to map the package names, we need a distribution, so we give the widget
3494 a distribution task to work with.
3495
3496+ >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3497 >>> from lp.bugs.interfaces.bug import IBugSet
3498 >>> from lp.bugs.interfaces.bugtask import IDistroBugTask
3499- >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3500 >>> bug_one = getUtility(IBugSet).get(1)
3501 >>> ubuntu_task = bug_one.bugtasks[-2]
3502 >>> ubuntu_task.distribution.name
3503
3504=== modified file 'lib/lp/bugs/doc/bugtask-retrieval.txt'
3505--- lib/lp/bugs/doc/bugtask-retrieval.txt 2010-10-03 15:30:06 +0000
3506+++ lib/lp/bugs/doc/bugtask-retrieval.txt 2010-10-21 19:08:55 +0000
3507@@ -5,9 +5,11 @@
3508 implementation of IBugTaskSet, allowing retrieval of any bug task in
3509 Launchpad. We'll use this implementation for demonstration purposes:
3510
3511- >>> from canonical.launchpad.interfaces import (
3512- ... IBugTask, IBugTaskSet)
3513 >>> from lp.app.errors import NotFoundError
3514+ >>> from lp.bugs.interfaces.bugtask import (
3515+ ... IBugTask,
3516+ ... IBugTaskSet,
3517+ ... )
3518 >>> task_set = getUtility(IBugTaskSet)
3519
3520
3521
3522=== modified file 'lib/lp/bugs/doc/bugtask-search.txt'
3523--- lib/lp/bugs/doc/bugtask-search.txt 2010-10-09 16:36:22 +0000
3524+++ lib/lp/bugs/doc/bugtask-search.txt 2010-10-21 19:08:55 +0000
3525@@ -4,8 +4,10 @@
3526 method, but they all delegate the search to IBugTaskSet.search(). That
3527 method accepts a single parameter; an BugTaskSearchParams instance.
3528
3529- >>> from canonical.launchpad.interfaces import (
3530- ... BugTaskSearchParams, IBugTaskSet)
3531+ >>> from lp.bugs.interfaces.bugtask import (
3532+ ... BugTaskSearchParams,
3533+ ... IBugTaskSet,
3534+ ... )
3535 >>> bugtask_set = getUtility(IBugTaskSet)
3536 >>> all_public = BugTaskSearchParams(user=None)
3537 >>> found_bugtasks = bugtask_set.search(all_public)
3538@@ -293,8 +295,10 @@
3539
3540 Add an Ubuntu bugtask for a bug that is confirmed upstream.
3541
3542- >>> from canonical.launchpad.interfaces import (
3543- ... BugTaskImportance, BugTaskStatus)
3544+ >>> from lp.bugs.interfaces.bugtask import (
3545+ ... BugTaskImportance,
3546+ ... BugTaskStatus,
3547+ ... )
3548 >>> from lp.bugs.tests.test_bugtask_1 import (
3549 ... BugTaskSearchBugsElsewhereTest)
3550 >>> def bugTaskInfo(bugtask):
3551@@ -736,9 +740,12 @@
3552 It's possible to search for bugs with an attachment of a certain type.
3553
3554 >>> from StringIO import StringIO
3555- >>> from canonical.launchpad.interfaces import (
3556- ... BugAttachmentType, IBugAttachmentSet, ILibraryFileAliasSet,
3557- ... IMessageSet)
3558+ >>> from canonical.launchpad.interfaces.librarian import ILibraryFileAliasSet
3559+ >>> from canonical.launchpad.interfaces.message import IMessageSet
3560+ >>> from lp.bugs.interfaces.bugattachment import (
3561+ ... BugAttachmentType,
3562+ ... IBugAttachmentSet,
3563+ ... )
3564 >>> product = factory.makeProduct()
3565 >>> patch_bug = factory.makeBug(
3566 ... product=product)
3567
3568=== modified file 'lib/lp/bugs/doc/bugtask-status-workflow.txt'
3569--- lib/lp/bugs/doc/bugtask-status-workflow.txt 2010-10-09 16:36:22 +0000
3570+++ lib/lp/bugs/doc/bugtask-status-workflow.txt 2010-10-21 19:08:55 +0000
3571@@ -11,8 +11,9 @@
3572 a new bug to work with:
3573
3574 >>> from zope.component import getUtility
3575- >>> from canonical.launchpad.interfaces import (
3576- ... IDistributionSet, ILaunchBag, CreateBugParams)
3577+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
3578+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3579+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3580
3581 >>> login("foo.bar@canonical.com")
3582 >>> foobar = getUtility(ILaunchBag).user
3583
3584=== modified file 'lib/lp/bugs/doc/bugtask.txt'
3585--- lib/lp/bugs/doc/bugtask.txt 2010-10-10 15:39:28 +0000
3586+++ lib/lp/bugs/doc/bugtask.txt 2010-10-21 19:08:55 +0000
3587@@ -41,8 +41,10 @@
3588
3589 Next, we need to grab some values to provide for importance and status.
3590
3591- >>> from canonical.launchpad.interfaces import (
3592- ... BugTaskImportance, BugTaskStatus)
3593+ >>> from lp.bugs.interfaces.bugtask import (
3594+ ... BugTaskImportance,
3595+ ... BugTaskStatus,
3596+ ... )
3597 >>> STATUS_NEW = BugTaskStatus.NEW
3598 >>> STATUS_CONFIRMED = BugTaskStatus.CONFIRMED
3599 >>> STATUS_FIXRELEASED = BugTaskStatus.FIXRELEASED
3600@@ -105,8 +107,8 @@
3601
3602 == Bug Task Targets ==
3603
3604+ >>> from lp.registry.interfaces.distributionsourcepackage import IDistributionSourcePackage
3605 >>> from lp.registry.model.distributionsourcepackage import DistributionSourcePackage
3606- >>> from lp.registry.interfaces.distributionsourcepackage import IDistributionSourcePackage
3607
3608 The "target" of an IBugTask can be one of the items in the following
3609 list.
3610@@ -165,8 +167,8 @@
3611
3612 * a distroseries sourcepackage
3613
3614+ >>> from lp.registry.interfaces.sourcepackage import ISourcePackage
3615 >>> from lp.registry.model.sourcepackage import SourcePackage
3616- >>> from lp.registry.interfaces.sourcepackage import ISourcePackage
3617 >>> distro_series_sp_task = bugtaskset.get(16)
3618 >>> expected_target = SourcePackage(
3619 ... distroseries=distro_series_sp_task.distroseries,
3620@@ -825,8 +827,8 @@
3621 later on the interaction between privacy and teams (see the section
3622 entitled _Privacy and Team Awareness_):
3623
3624+ >>> from lazr.lifecycle.snapshot import Snapshot
3625 >>> from lp.bugs.interfaces.bug import IBug
3626- >>> from lazr.lifecycle.snapshot import Snapshot
3627
3628 >>> bug_upstream_firefox_no_svg_support = bugtaskset.get(2)
3629
3630
3631=== modified file 'lib/lp/bugs/doc/bugtracker.txt'
3632--- lib/lp/bugs/doc/bugtracker.txt 2010-10-09 16:36:22 +0000
3633+++ lib/lp/bugs/doc/bugtracker.txt 2010-10-21 19:08:55 +0000
3634@@ -139,8 +139,8 @@
3635 bugtracker it will use make_bugtracker_name() to generate a name for the
3636 bug tracker.
3637
3638- >>> from canonical.launchpad.interfaces import (
3639- ... BugTrackerType, IPersonSet)
3640+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
3641+ >>> from lp.registry.interfaces.person import IPersonSet
3642 >>> sample_person = getUtility(IPersonSet).getByEmail(
3643 ... 'test@canonical.com')
3644 >>> a_bugtracker = bugtracker_set.ensureBugTracker(
3645@@ -325,8 +325,8 @@
3646
3647 We will forge some BugMessage records before trying again:
3648
3649+ >>> from zope.security.proxy import removeSecurityProxy
3650 >>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
3651- >>> from zope.security.proxy import removeSecurityProxy
3652
3653 >>> for num, bug_watch in enumerate(mozilla_bugzilla.watches):
3654 ... bug_message = getUtility(IBugMessageSet).createMessage(
3655
3656=== modified file 'lib/lp/bugs/doc/bugwatch.txt'
3657--- lib/lp/bugs/doc/bugwatch.txt 2010-10-09 16:36:22 +0000
3658+++ lib/lp/bugs/doc/bugwatch.txt 2010-10-21 19:08:55 +0000
3659@@ -59,8 +59,9 @@
3660 Watches of Email Address bugtrackers are slightly different: the `url`
3661 property is always the same as the bugtracker baseurl property.
3662
3663- >>> from canonical.launchpad.interfaces import (
3664- ... IBugSet, IBugTrackerSet, IPersonSet)
3665+ >>> from lp.bugs.interfaces.bug import IBugSet
3666+ >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3667+ >>> from lp.registry.interfaces.person import IPersonSet
3668 >>> bugtrackerset = getUtility(IBugTrackerSet)
3669
3670 >>> email_bugtracker = bugtrackerset['email']
3671@@ -267,8 +268,8 @@
3672 ... print "%s => %s" % (old_bugtask.importance.title,
3673 ... bugtask.importance.title)
3674 >>> from canonical.launchpad.ftests.event import TestEventListener
3675+ >>> from lazr.lifecycle.interfaces import IObjectModifiedEvent
3676 >>> from lp.bugs.interfaces.bugtask import IBugTask
3677- >>> from lazr.lifecycle.interfaces import IObjectModifiedEvent
3678 >>> event_listener = TestEventListener(
3679 ... IBugTask, IObjectModifiedEvent, print_bugtask_modified)
3680
3681@@ -417,9 +418,13 @@
3682
3683 >>> from zope.component import getUtility
3684 >>> from canonical.database.sqlbase import flush_database_updates
3685- >>> from canonical.launchpad.interfaces import (
3686- ... CreateBugParams, BugTrackerType, IBugTaskSet,
3687- ... IBugTrackerSet, IDistributionSet)
3688+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3689+ >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
3690+ >>> from lp.bugs.interfaces.bugtracker import (
3691+ ... BugTrackerType,
3692+ ... IBugTrackerSet,
3693+ ... )
3694+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3695
3696 >>> ubuntu = getUtility(IDistributionSet).get(1)
3697 >>> firefox = ubuntu.getSourcePackage('mozilla-firefox')
3698@@ -462,8 +467,8 @@
3699 >>> import transaction
3700 >>> from lp.bugs.tests.externalbugtracker import (
3701 ... TestRoundup)
3702+ >>> from canonical.launchpad.scripts.logger import FakeLogger
3703 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
3704- >>> from canonical.launchpad.scripts.logger import FakeLogger
3705 >>> bug_watch_updater = CheckwatchesMaster(transaction, FakeLogger())
3706 >>> external_bugtracker = TestRoundup(bug_tracker.baseurl)
3707 >>> bug_watch_updater.updateBugWatches(external_bugtracker, [bug_watch])
3708@@ -550,8 +555,8 @@
3709 next_check time for the watch will be in the past (or in this case is
3710 now) and therefore it will be checked with the next checkwatches run.
3711
3712+ >>> from datetime import datetime
3713 >>> from pytz import utc
3714- >>> from datetime import datetime
3715 >>> schedulable_watch.next_check = datetime.now(utc)
3716 >>> schedulable_watch.can_be_rescheduled
3717 False
3718
3719=== modified file 'lib/lp/bugs/doc/bugwidget.txt'
3720--- lib/lp/bugs/doc/bugwidget.txt 2010-10-09 16:36:22 +0000
3721+++ lib/lp/bugs/doc/bugwidget.txt 2010-10-21 19:08:55 +0000
3722@@ -3,8 +3,8 @@
3723 The BugWidget converts string bug ids to the corresponding bug object.
3724
3725 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3726+ >>> from canonical.widgets.bug import BugWidget
3727 >>> from lp.services.fields import BugField
3728- >>> from canonical.widgets.bug import BugWidget
3729 >>> bug_field = BugField(__name__='bug', title=u'Bug')
3730 >>> request = LaunchpadTestRequest(form={'field.bug': '1'})
3731 >>> bug_widget = BugWidget(bug_field, request)
3732
3733=== modified file 'lib/lp/bugs/doc/bugzilla-import.txt'
3734--- lib/lp/bugs/doc/bugzilla-import.txt 2010-10-03 15:30:06 +0000
3735+++ lib/lp/bugs/doc/bugzilla-import.txt 2010-10-21 19:08:55 +0000
3736@@ -106,9 +106,10 @@
3737
3738 >>> from zope.component import getUtility
3739 >>> from canonical.launchpad.ftests import login
3740- >>> from canonical.launchpad.interfaces import (
3741- ... IBugSet, ILaunchpadCelebrities, IPersonSet)
3742+ >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
3743+ >>> from lp.bugs.interfaces.bug import IBugSet
3744 >>> from lp.bugs.scripts import bugzilla
3745+ >>> from lp.registry.interfaces.person import IPersonSet
3746
3747 Get a reference to the Ubuntu bug tracker, and log in:
3748
3749
3750=== modified file 'lib/lp/bugs/doc/checkwatches-batching.txt'
3751--- lib/lp/bugs/doc/checkwatches-batching.txt 2010-04-21 10:30:24 +0000
3752+++ lib/lp/bugs/doc/checkwatches-batching.txt 2010-10-21 19:08:55 +0000
3753@@ -67,9 +67,9 @@
3754 For bug watches that have been checked before, the remote system is
3755 asked which of a list of bugs have been modified since a given date.
3756
3757+ >>> from zope.security.proxy import removeSecurityProxy
3758 >>> from datetime import datetime
3759 >>> from pytz import UTC
3760- >>> from zope.security.proxy import removeSecurityProxy
3761
3762 >>> class QueryableRemoteSystem:
3763 ... sync_comments = False
3764
3765=== modified file 'lib/lp/bugs/doc/checkwatches-cli-switches.txt'
3766--- lib/lp/bugs/doc/checkwatches-cli-switches.txt 2010-10-04 19:50:45 +0000
3767+++ lib/lp/bugs/doc/checkwatches-cli-switches.txt 2010-10-21 19:08:55 +0000
3768@@ -87,8 +87,8 @@
3769
3770 >>> import pytz
3771 >>> from datetime import datetime
3772+ >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3773 >>> from lp.testing.factory import LaunchpadObjectFactory
3774- >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3775
3776 >>> factory = LaunchpadObjectFactory()
3777 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
3778
3779=== modified file 'lib/lp/bugs/doc/checkwatches.txt'
3780--- lib/lp/bugs/doc/checkwatches.txt 2010-10-09 16:36:22 +0000
3781+++ lib/lp/bugs/doc/checkwatches.txt 2010-10-21 19:08:55 +0000
3782@@ -20,8 +20,8 @@
3783
3784 >>> from canonical.config import config
3785 >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
3786+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
3787 >>> from lp.testing.factory import LaunchpadObjectFactory
3788- >>> from canonical.testing.layers import LaunchpadZopelessLayer
3789
3790 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
3791
3792@@ -104,14 +104,13 @@
3793 First, we create some bug watches to test with:
3794
3795 >>> from datetime import datetime
3796+ >>> from lp.bugs.interfaces.bug import IBugSet
3797+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
3798+ >>> from lp.bugs.model.bugtracker import BugTracker
3799 >>> from pytz import utc
3800- >>> from lp.bugs.model.bugtracker import BugTracker
3801- >>> from canonical.launchpad.interfaces import (
3802- ... BugTrackerType, IBugSet)
3803 >>> from lp.bugs.scripts.checkwatches import (
3804 ... CheckwatchesMaster)
3805- >>> from canonical.launchpad.interfaces import (
3806- ... IPersonSet)
3807+ >>> from lp.registry.interfaces.person import IPersonSet
3808 >>> sample_person = getUtility(IPersonSet).getByEmail(
3809 ... 'test@canonical.com')
3810
3811@@ -257,8 +256,8 @@
3812 batch size. We will also monkey-patch urllib2.urlopen again so that no
3813 requests are actually made.
3814
3815- >>> from lp.bugs import externalbugtracker
3816 >>> from canonical.launchpad.scripts import FakeLogger
3817+ >>> from lp.bugs import externalbugtracker
3818
3819 >>> transaction.commit()
3820 >>> updater = CheckwatchesMaster(transaction.manager)
3821
3822=== modified file 'lib/lp/bugs/doc/displaying-bugs-and-tasks.txt'
3823--- lib/lp/bugs/doc/displaying-bugs-and-tasks.txt 2010-10-11 16:17:45 +0000
3824+++ lib/lp/bugs/doc/displaying-bugs-and-tasks.txt 2010-10-21 19:08:55 +0000
3825@@ -16,8 +16,10 @@
3826 >>> from zope.component import getUtility
3827 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
3828 >>> from lp.bugs.interfaces.bugtask import BugTaskImportance, IBugTaskSet
3829- >>> from canonical.launchpad.ftests import test_tales
3830- >>> from canonical.launchpad.ftests import login
3831+ >>> from canonical.launchpad.ftests import (
3832+ ... login,
3833+ ... test_tales,
3834+ ... )
3835
3836 >>> login("foo.bar@canonical.com")
3837 >>> bugtaskset = getUtility(IBugTaskSet)
3838@@ -97,10 +99,10 @@
3839 We define a helper that uses the BugTaskListingView class (obtained via
3840 +listing-view) to render the status:
3841
3842- >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
3843- >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
3844 >>> from zope.component import getMultiAdapter
3845+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
3846 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
3847+ >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
3848
3849 >>> def render_bugtask_status(task):
3850 ... view = getMultiAdapter(
3851
3852=== modified file 'lib/lp/bugs/doc/externalbugtracker-bug-imports.txt'
3853--- lib/lp/bugs/doc/externalbugtracker-bug-imports.txt 2010-10-09 16:36:22 +0000
3854+++ lib/lp/bugs/doc/externalbugtracker-bug-imports.txt 2010-10-21 19:08:55 +0000
3855@@ -24,8 +24,8 @@
3856 ... def getBugTargetName(self, remote_bug):
3857 ... return self._bugs[remote_bug]['package']
3858
3859- >>> from canonical.launchpad.interfaces import (
3860- ... BugTrackerType, IDistributionSet)
3861+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
3862+ >>> from lp.registry.interfaces.distribution import IDistributionSet
3863 >>> from lp.bugs.tests.externalbugtracker import (
3864 ... new_bugtracker)
3865 >>> bugtracker = new_bugtracker(BugTrackerType.BUGZILLA)
3866@@ -45,8 +45,8 @@
3867 imported into, and the remote bug number. At the moment only
3868 distributions are supported as the bug target.
3869
3870+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
3871 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
3872- >>> from canonical.testing.layers import LaunchpadZopelessLayer
3873 >>> debian = getUtility(IDistributionSet).getByName('debian')
3874 >>> external_bugtracker._bugs['3'] = {
3875 ... 'package': 'evolution',
3876
3877=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt'
3878--- lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt 2010-10-15 20:45:24 +0000
3879+++ lib/lp/bugs/doc/externalbugtracker-bugzilla-api.txt 2010-10-21 19:08:55 +0000
3880@@ -386,8 +386,8 @@
3881 means that we can use it to import comments from the remote Bugzilla
3882 instance.
3883
3884+ >>> from canonical.launchpad.webapp.testing import verifyObject
3885 >>> from lp.bugs.interfaces.externalbugtracker import ISupportsCommentImport
3886- >>> from canonical.launchpad.webapp.testing import verifyObject
3887 >>> verifyObject(ISupportsCommentImport, bugzilla)
3888 True
3889
3890
3891=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt'
3892--- lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt 2010-10-09 16:36:22 +0000
3893+++ lib/lp/bugs/doc/externalbugtracker-bugzilla-lp-plugin.txt 2010-10-21 19:08:55 +0000
3894@@ -334,8 +334,8 @@
3895 means that we can use it to import comments from the remote Bugzilla
3896 instance.
3897
3898+ >>> from canonical.launchpad.webapp.testing import verifyObject
3899 >>> from lp.bugs.interfaces.externalbugtracker import ISupportsCommentImport
3900- >>> from canonical.launchpad.webapp.testing import verifyObject
3901 >>> verifyObject(ISupportsCommentImport, bugzilla)
3902 True
3903
3904
3905=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt'
3906--- lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt 2010-10-09 16:36:22 +0000
3907+++ lib/lp/bugs/doc/externalbugtracker-bugzilla-oddities.txt 2010-10-21 19:08:55 +0000
3908@@ -14,9 +14,9 @@
3909
3910 >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3911
3912+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
3913+ >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
3914 >>> from lp.bugs.tests.externalbugtracker import TestIssuezilla
3915- >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
3916- >>> from canonical.testing.layers import LaunchpadZopelessLayer
3917 >>> txn = LaunchpadZopelessLayer.txn
3918 >>> mozilla_bugzilla = getUtility(IBugTrackerSet).getByName('mozilla.org')
3919 >>> issuezilla = TestIssuezilla(mozilla_bugzilla.baseurl)
3920
3921=== modified file 'lib/lp/bugs/doc/externalbugtracker-bugzilla.txt'
3922--- lib/lp/bugs/doc/externalbugtracker-bugzilla.txt 2010-10-09 16:36:22 +0000
3923+++ lib/lp/bugs/doc/externalbugtracker-bugzilla.txt 2010-10-21 19:08:55 +0000
3924@@ -58,8 +58,8 @@
3925 Since we don't want to depend on a working network connection, we use a
3926 slightly modified implementation.
3927
3928+ >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3929 >>> from lp.bugs.tests.externalbugtracker import TestBugzilla
3930- >>> from lp.bugs.interfaces.bugtracker import IBugTrackerSet
3931 >>> gnome_bugzilla = (
3932 ... getUtility(IBugTrackerSet).getByName('gnome-bugzilla'))
3933 >>> external_bugzilla = TestBugzilla(gnome_bugzilla.baseurl)
3934@@ -430,8 +430,9 @@
3935
3936 Let's add a handful of watches:
3937
3938- >>> from canonical.launchpad.interfaces import (
3939- ... IBugSet, IBugWatchSet, IPersonSet)
3940+ >>> from lp.bugs.interfaces.bug import IBugSet
3941+ >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
3942+ >>> from lp.registry.interfaces.person import IPersonSet
3943 >>> sample_person = getUtility(IPersonSet).getByEmail(
3944 ... 'test@canonical.com')
3945 >>> bug_one = getUtility(IBugSet).get(1)
3946
3947=== modified file 'lib/lp/bugs/doc/externalbugtracker-comment-imports.txt'
3948--- lib/lp/bugs/doc/externalbugtracker-comment-imports.txt 2010-10-04 19:50:45 +0000
3949+++ lib/lp/bugs/doc/externalbugtracker-comment-imports.txt 2010-10-21 19:08:55 +0000
3950@@ -10,10 +10,14 @@
3951 >>> from canonical.config import config
3952 >>> from lp.bugs.tests.externalbugtracker import (
3953 ... new_bugtracker)
3954- >>> from canonical.launchpad.interfaces import (
3955- ... BugTrackerType, CreateBugParams, IBugMessageSet,
3956- ... IBugWatchSet, IMessageSet, IPersonSet, IProductSet)
3957+ >>> from canonical.launchpad.interfaces.message import IMessageSet
3958 >>> from canonical.testing.layers import LaunchpadZopelessLayer
3959+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3960+ >>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
3961+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
3962+ >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
3963+ >>> from lp.registry.interfaces.person import IPersonSet
3964+ >>> from lp.registry.interfaces.product import IProductSet
3965
3966 >>> bug_tracker = new_bugtracker(BugTrackerType.BUGZILLA)
3967
3968@@ -41,8 +45,7 @@
3969
3970 >>> from lp.bugs.externalbugtracker import (
3971 ... ExternalBugTracker)
3972- >>> from canonical.launchpad.interfaces import (
3973- ... ISupportsCommentImport)
3974+ >>> from lp.bugs.interfaces.externalbugtracker import ISupportsCommentImport
3975 >>> class CommentImportingExternalBugTracker(ExternalBugTracker):
3976 ... implements(ISupportsCommentImport)
3977 ...
3978
3979=== modified file 'lib/lp/bugs/doc/externalbugtracker-comment-pushing.txt'
3980--- lib/lp/bugs/doc/externalbugtracker-comment-pushing.txt 2010-10-04 19:50:45 +0000
3981+++ lib/lp/bugs/doc/externalbugtracker-comment-pushing.txt 2010-10-21 19:08:55 +0000
3982@@ -10,10 +10,14 @@
3983 >>> from canonical.config import config
3984 >>> from lp.bugs.tests.externalbugtracker import (
3985 ... new_bugtracker)
3986- >>> from canonical.launchpad.interfaces import (
3987- ... BugTrackerType, CreateBugParams, IBugMessageSet,
3988- ... IBugWatchSet, IMessageSet, IPersonSet, IProductSet)
3989+ >>> from canonical.launchpad.interfaces.message import IMessageSet
3990 >>> from canonical.testing.layers import LaunchpadZopelessLayer
3991+ >>> from lp.bugs.interfaces.bug import CreateBugParams
3992+ >>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
3993+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
3994+ >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
3995+ >>> from lp.registry.interfaces.person import IPersonSet
3996+ >>> from lp.registry.interfaces.product import IProductSet
3997
3998 >>> bug_tracker = new_bugtracker(BugTrackerType.TRAC)
3999
4000@@ -46,8 +50,7 @@
4001 an example ExternalBugTracker that implements the
4002 ISupportsCommentPushing interface.
4003
4004- >>> from canonical.launchpad.interfaces import (
4005- ... ISupportsCommentPushing)
4006+ >>> from lp.bugs.interfaces.externalbugtracker import ISupportsCommentPushing
4007 >>> from lp.bugs.externalbugtracker import (
4008 ... ExternalBugTracker)
4009
4010@@ -187,8 +190,7 @@
4011 from the remote bugtracker. To demonstrate this, we need to create an
4012 example ExternalBugTracker that does comment importing.
4013
4014- >>> from canonical.launchpad.interfaces import (
4015- ... ISupportsCommentImport)
4016+ >>> from lp.bugs.interfaces.externalbugtracker import ISupportsCommentImport
4017 >>> class CommentImportingExternalBugTracker(
4018 ... CommentPushingExternalBugTracker):
4019 ... implements(ISupportsCommentImport)
4020
4021=== modified file 'lib/lp/bugs/doc/externalbugtracker-debbugs.txt'
4022--- lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-10-11 16:17:45 +0000
4023+++ lib/lp/bugs/doc/externalbugtracker-debbugs.txt 2010-10-21 19:08:55 +0000
4024@@ -6,8 +6,8 @@
4025 test:
4026
4027 >>> import os.path
4028+ >>> from canonical.config import config
4029 >>> from canonical.launchpad.components.ftests import __file__
4030- >>> from canonical.config import config
4031 >>> test_db_location = os.path.join(
4032 ... os.path.dirname(__file__), 'debbugs_db')
4033
4034@@ -348,8 +348,8 @@
4035
4036 >>> from lp.bugs.externalbugtracker import (
4037 ... get_external_bugtracker)
4038- >>> from canonical.launchpad.interfaces import (
4039- ... BugTrackerType, ISupportsCommentImport)
4040+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4041+ >>> from lp.bugs.interfaces.externalbugtracker import ISupportsCommentImport
4042 >>> from lp.bugs.tests.externalbugtracker import (
4043 ... new_bugtracker)
4044 >>> external_debbugs = get_external_bugtracker(
4045@@ -438,8 +438,10 @@
4046 Message. It requires a Person instance to be used as the Message's
4047 owner, so we'll turn Teun Vink into a Person.
4048
4049- >>> from canonical.launchpad.interfaces import (
4050- ... IPersonSet, PersonCreationRationale)
4051+ >>> from lp.registry.interfaces.person import (
4052+ ... IPersonSet,
4053+ ... PersonCreationRationale,
4054+ ... )
4055 >>> poster = getUtility(IPersonSet).ensurePerson(
4056 ... poster_email, poster_name, PersonCreationRationale.BUGIMPORT,
4057 ... comment='when importing comments for %s.' % bug_watch.title)
4058
4059=== modified file 'lib/lp/bugs/doc/externalbugtracker-emailaddress.txt'
4060--- lib/lp/bugs/doc/externalbugtracker-emailaddress.txt 2010-10-09 16:36:22 +0000
4061+++ lib/lp/bugs/doc/externalbugtracker-emailaddress.txt 2010-10-21 19:08:55 +0000
4062@@ -33,8 +33,11 @@
4063
4064 >>> from zope.component import getUtility
4065 >>> from canonical.launchpad.webapp.testing import verifyObject
4066- >>> from canonical.launchpad.interfaces import (
4067- ... IBugTracker, IBugTrackerSet, IPersonSet)
4068+ >>> from lp.bugs.interfaces.bugtracker import (
4069+ ... IBugTracker,
4070+ ... IBugTrackerSet,
4071+ ... )
4072+ >>> from lp.registry.interfaces.person import IPersonSet
4073
4074 >>> sample_person = getUtility(IPersonSet).getByEmail(
4075 ... 'test@canonical.com')
4076
4077=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt'
4078--- lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-10-11 16:17:45 +0000
4079+++ lib/lp/bugs/doc/externalbugtracker-mantis-csv.txt 2010-10-21 19:08:55 +0000
4080@@ -53,8 +53,8 @@
4081
4082 >>> sample_person = getUtility(IPersonSet).getByEmail('test@canonical.com')
4083
4084+ >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
4085 >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4086- >>> from canonical.launchpad.interfaces.launchpad import ILaunchpadCelebrities
4087 >>> from lp.bugs.tests.externalbugtracker import (
4088 ... new_bugtracker)
4089 >>> example_bug_tracker = new_bugtracker(BugTrackerType.MANTIS)
4090
4091=== modified file 'lib/lp/bugs/doc/externalbugtracker-mantis.txt'
4092--- lib/lp/bugs/doc/externalbugtracker-mantis.txt 2010-10-11 16:17:45 +0000
4093+++ lib/lp/bugs/doc/externalbugtracker-mantis.txt 2010-10-21 19:08:55 +0000
4094@@ -13,9 +13,9 @@
4095 >>> from lp.bugs.externalbugtracker import Mantis
4096 >>> from lp.bugs.tests.externalbugtracker import (
4097 ... new_bugtracker)
4098- >>> from canonical.launchpad.interfaces import (
4099- ... BugTrackerType, IExternalBugTracker)
4100 >>> from canonical.launchpad.webapp.testing import verifyObject
4101+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4102+ >>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTracker
4103 >>> alsa_mantis = Mantis('http://example.com/')
4104
4105 >>> verifyObject(IExternalBugTracker, alsa_mantis)
4106@@ -80,8 +80,8 @@
4107
4108 >>> transaction.commit()
4109
4110+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
4111 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
4112- >>> from canonical.testing.layers import LaunchpadZopelessLayer
4113 >>> txn = LaunchpadZopelessLayer.txn
4114 >>> bug_watch_updater = CheckwatchesMaster(txn)
4115 >>> bug_watch_updater.updateBugWatches(
4116
4117=== modified file 'lib/lp/bugs/doc/externalbugtracker-roundup.txt'
4118--- lib/lp/bugs/doc/externalbugtracker-roundup.txt 2010-10-11 16:17:45 +0000
4119+++ lib/lp/bugs/doc/externalbugtracker-roundup.txt 2010-10-21 19:08:55 +0000
4120@@ -11,8 +11,8 @@
4121 implements IExternalBugTracker.
4122
4123 >>> from lp.bugs.externalbugtracker import Roundup
4124- >>> from canonical.launchpad.interfaces import (
4125- ... BugTrackerType, IExternalBugTracker)
4126+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4127+ >>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTracker
4128 >>> from lp.bugs.tests.externalbugtracker import (
4129 ... new_bugtracker)
4130 >>> from canonical.launchpad.webapp.testing import verifyObject
4131@@ -138,8 +138,8 @@
4132
4133 >>> transaction.commit()
4134
4135+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
4136 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
4137- >>> from canonical.testing.layers import LaunchpadZopelessLayer
4138 >>> txn = LaunchpadZopelessLayer.txn
4139 >>> bug_watch_updater = CheckwatchesMaster(txn)
4140 >>> roundup = TestRoundup(example_bug_tracker.baseurl)
4141
4142=== modified file 'lib/lp/bugs/doc/externalbugtracker-rt.txt'
4143--- lib/lp/bugs/doc/externalbugtracker-rt.txt 2010-10-09 16:36:22 +0000
4144+++ lib/lp/bugs/doc/externalbugtracker-rt.txt 2010-10-21 19:08:55 +0000
4145@@ -11,8 +11,8 @@
4146
4147 >>> from lp.bugs.externalbugtracker import (
4148 ... RequestTracker)
4149- >>> from canonical.launchpad.interfaces import (
4150- ... BugTrackerType, IExternalBugTracker)
4151+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4152+ >>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTracker
4153 >>> from lp.bugs.tests.externalbugtracker import (
4154 ... new_bugtracker)
4155 >>> from canonical.launchpad.webapp.testing import verifyObject
4156@@ -155,8 +155,9 @@
4157 First, we create some bug watches to test with. Example.com hosts an RT
4158 instance which has several bugs that we wish to watch:
4159
4160- >>> from canonical.launchpad.interfaces import (
4161- ... IBugSet, IBugWatchSet, IPersonSet)
4162+ >>> from lp.bugs.interfaces.bug import IBugSet
4163+ >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
4164+ >>> from lp.registry.interfaces.person import IPersonSet
4165 >>> from lp.bugs.tests.externalbugtracker import (
4166 ... print_bugwatches)
4167
4168@@ -180,8 +181,8 @@
4169
4170 >>> transaction.commit()
4171
4172+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
4173 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
4174- >>> from canonical.testing.layers import LaunchpadZopelessLayer
4175 >>> txn = LaunchpadZopelessLayer.txn
4176 >>> bug_watch_updater = CheckwatchesMaster(txn)
4177 >>> rt = TestRequestTracker(example_bug_tracker.baseurl)
4178
4179=== modified file 'lib/lp/bugs/doc/externalbugtracker-sourceforge.txt'
4180--- lib/lp/bugs/doc/externalbugtracker-sourceforge.txt 2010-10-09 16:36:22 +0000
4181+++ lib/lp/bugs/doc/externalbugtracker-sourceforge.txt 2010-10-21 19:08:55 +0000
4182@@ -12,9 +12,9 @@
4183
4184 >>> from lp.bugs.externalbugtracker import (
4185 ... SourceForge)
4186- >>> from canonical.launchpad.interfaces import (
4187- ... BugTrackerType, IExternalBugTracker)
4188 >>> from canonical.launchpad.webapp.testing import verifyObject
4189+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4190+ >>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTracker
4191 >>> verifyObject(IExternalBugTracker,
4192 ... SourceForge('http://example.com'))
4193 True
4194@@ -161,8 +161,8 @@
4195
4196 >>> transaction.commit()
4197
4198+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
4199 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
4200- >>> from canonical.testing.layers import LaunchpadZopelessLayer
4201 >>> txn = LaunchpadZopelessLayer.txn
4202 >>> bug_watch_updater = CheckwatchesMaster(txn)
4203 >>> sourceforge = TestSourceForge(example_bug_tracker.baseurl)
4204
4205=== modified file 'lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt'
4206--- lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt 2010-10-09 16:36:22 +0000
4207+++ lib/lp/bugs/doc/externalbugtracker-trac-lp-plugin.txt 2010-10-21 19:08:55 +0000
4208@@ -31,8 +31,8 @@
4209
4210 >>> import random
4211 >>> from canonical.config import config
4212+ >>> from canonical.launchpad.interfaces.logintoken import ILoginTokenSet
4213 >>> from canonical.launchpad.webapp.url import urlappend
4214- >>> from canonical.launchpad.interfaces.logintoken import ILoginTokenSet
4215 >>> from canonical.testing.layers import LaunchpadZopelessLayer
4216
4217 >>> class FakeResponse:
4218@@ -338,8 +338,10 @@
4219 We also need an example Bug, BugTracker and BugWatch.
4220
4221 >>> from canonical.database.sqlbase import commit
4222- >>> from canonical.launchpad.interfaces import (
4223- ... BugTrackerType, CreateBugParams, IPersonSet, IProductSet)
4224+ >>> from lp.bugs.interfaces.bug import CreateBugParams
4225+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4226+ >>> from lp.registry.interfaces.person import IPersonSet
4227+ >>> from lp.registry.interfaces.product import IProductSet
4228 >>> from lp.bugs.tests.externalbugtracker import (
4229 ... new_bugtracker)
4230
4231
4232=== modified file 'lib/lp/bugs/doc/externalbugtracker-trac.txt'
4233--- lib/lp/bugs/doc/externalbugtracker-trac.txt 2010-10-11 16:17:45 +0000
4234+++ lib/lp/bugs/doc/externalbugtracker-trac.txt 2010-10-21 19:08:55 +0000
4235@@ -13,9 +13,9 @@
4236 >>> from lp.bugs.externalbugtracker import Trac
4237 >>> from lp.bugs.tests.externalbugtracker import (
4238 ... new_bugtracker)
4239- >>> from canonical.launchpad.interfaces import (
4240- ... BugTrackerType, IExternalBugTracker)
4241 >>> from canonical.launchpad.webapp.testing import verifyObject
4242+ >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4243+ >>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTracker
4244 >>> trac = Trac('http://example.com/')
4245 >>> verifyObject(IExternalBugTracker, trac)
4246 True
4247@@ -55,9 +55,9 @@
4248 a valid token, which is very unlikely), is that the broken Trac will
4249 not include a "trac_auth" cookie.
4250
4251+ >>> from StringIO import StringIO
4252 >>> from httplib import HTTPMessage
4253 >>> from urllib import addinfourl
4254- >>> from StringIO import StringIO
4255
4256 >>> class TracReturning200ForPageNotFound(Trac):
4257 ... def urlopen(self, url):
4258@@ -298,8 +298,8 @@
4259
4260 >>> transaction.commit()
4261
4262+ >>> from canonical.testing.layers import LaunchpadZopelessLayer
4263 >>> from lp.bugs.scripts.checkwatches import CheckwatchesMaster
4264- >>> from canonical.testing.layers import LaunchpadZopelessLayer
4265 >>> txn = LaunchpadZopelessLayer.txn
4266 >>> bug_watch_updater = CheckwatchesMaster(txn)
4267 >>> trac = TestTrac(example_bug_tracker.baseurl)
4268
4269=== modified file 'lib/lp/bugs/doc/externalbugtracker.txt'
4270--- lib/lp/bugs/doc/externalbugtracker.txt 2010-10-09 16:36:22 +0000
4271+++ lib/lp/bugs/doc/externalbugtracker.txt 2010-10-21 19:08:55 +0000
4272@@ -433,9 +433,9 @@
4273 getModifiedRemoteBugs(). I.e., if we have a set of newly created bug
4274 watches, the getModifiedRemoteBugs() method won't be called.
4275
4276- >>> from lp.bugs.model.bugtracker import BugTracker
4277 >>> from lp.bugs.interfaces.bug import IBugSet
4278 >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
4279+ >>> from lp.bugs.model.bugtracker import BugTracker
4280 >>> from lp.registry.interfaces.person import IPersonSet
4281
4282 >>> sample_person = getUtility(IPersonSet).getByEmail(
4283
4284=== modified file 'lib/lp/bugs/doc/hasbugs.txt'
4285--- lib/lp/bugs/doc/hasbugs.txt 2010-10-10 15:39:28 +0000
4286+++ lib/lp/bugs/doc/hasbugs.txt 2010-10-21 19:08:55 +0000
4287@@ -5,8 +5,8 @@
4288 between the object and some of the bug tasks connected to it, and allows
4289 searching through the list of bugs.
4290
4291+ >>> from zope.component import getUtility
4292 >>> from canonical.launchpad.webapp.testing import verifyObject
4293- >>> from zope.component import getUtility
4294 >>> from lp.bugs.interfaces.bugtarget import IHasBugs
4295 >>> from lp.registry.interfaces.distribution import IDistributionSet
4296 >>> distroset = getUtility(IDistributionSet)
4297@@ -30,8 +30,11 @@
4298
4299 >>> login("foo.bar@canonical.com")
4300
4301- >>> from canonical.launchpad.interfaces import (
4302- ... BugTaskImportance, BugTaskStatus, IBugTaskSet)
4303+ >>> from lp.bugs.interfaces.bugtask import (
4304+ ... BugTaskImportance,
4305+ ... BugTaskStatus,
4306+ ... IBugTaskSet,
4307+ ... )
4308
4309 >>> bug_one_in_debian_firefox = getUtility(IBugTaskSet).get(4)
4310 >>> bug_two_in_debian_firefox = getUtility(IBugTaskSet).get(5)
4311
4312=== modified file 'lib/lp/bugs/doc/initial-bug-contacts.txt'
4313--- lib/lp/bugs/doc/initial-bug-contacts.txt 2010-10-14 18:42:19 +0000
4314+++ lib/lp/bugs/doc/initial-bug-contacts.txt 2010-10-21 19:08:55 +0000
4315@@ -388,9 +388,9 @@
4316 The list of teams that a user may add to a package as a bug supervisor will
4317 only contain those teams of which the user is an administrator.
4318
4319- >>> from lp.registry.interfaces.distribution import IDistributionSet
4320 >>> from zope.component import getMultiAdapter
4321 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
4322+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4323
4324 >>> ubuntu = getUtility(IDistributionSet).getByName('ubuntu')
4325 >>> package = ubuntu.getSourcePackage('mozilla-firefox')
4326
4327=== modified file 'lib/lp/bugs/doc/malone-karma.txt'
4328--- lib/lp/bugs/doc/malone-karma.txt 2010-10-10 15:39:28 +0000
4329+++ lib/lp/bugs/doc/malone-karma.txt 2010-10-21 19:08:55 +0000
4330@@ -2,8 +2,10 @@
4331 import some stuff and define a function to help us make the
4332 documentation cleaner:
4333
4334- >>> from canonical.launchpad.interfaces import (
4335- ... IBugSet, IDistributionSet, IKarmaActionSet, IPersonSet)
4336+ >>> from lp.bugs.interfaces.bug import IBugSet
4337+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4338+ >>> from lp.registry.interfaces.karma import IKarmaActionSet
4339+ >>> from lp.registry.interfaces.person import IPersonSet
4340 >>> foo_bar = getUtility(IPersonSet).getByEmail('foo.bar@canonical.com')
4341
4342 Setup an event listener to help ensure karma is assigned when it should.
4343@@ -70,8 +72,10 @@
4344
4345 Mark a bug task as fixed:
4346
4347- >>> from canonical.launchpad.interfaces import (
4348- ... BugTaskStatus, IDistroBugTask)
4349+ >>> from lp.bugs.interfaces.bugtask import (
4350+ ... BugTaskStatus,
4351+ ... IDistroBugTask,
4352+ ... )
4353 >>> bugtask = bug.bugtasks[0]
4354 >>> old_bugtask = Snapshot(bugtask, providing=IDistroBugTask)
4355 >>> bugtask.transitionToStatus(
4356
4357=== modified file 'lib/lp/bugs/doc/malone-xmlrpc.txt'
4358--- lib/lp/bugs/doc/malone-xmlrpc.txt 2010-10-09 16:36:22 +0000
4359+++ lib/lp/bugs/doc/malone-xmlrpc.txt 2010-10-21 19:08:55 +0000
4360@@ -46,8 +46,8 @@
4361 IObjectCreatedEvent is being published when a bug is reported through
4362 the XML-RPC interface.
4363
4364+ >>> from canonical.launchpad.ftests.event import TestEventListener
4365 >>> from lazr.lifecycle.interfaces import IObjectCreatedEvent
4366- >>> from canonical.launchpad.ftests.event import TestEventListener
4367 >>> from lp.bugs.interfaces.bug import IBug
4368
4369 >>> def on_created_event(obj, event):
4370@@ -233,8 +233,10 @@
4371 for authentication with external bug trackers.
4372
4373 >>> from zope.component import getUtility
4374- >>> from canonical.launchpad.interfaces import (
4375- ... IPrivateMaloneApplication, IPrivateApplication)
4376+ >>> from canonical.launchpad.interfaces.launchpad import (
4377+ ... IPrivateApplication,
4378+ ... IPrivateMaloneApplication,
4379+ ... )
4380 >>> from canonical.launchpad.webapp.testing import verifyObject
4381
4382 >>> private_root = getUtility(IPrivateApplication)
4383@@ -245,9 +247,9 @@
4384 The API provides a single method, newBugTrackerToken(), which returns
4385 the ID of the new LoginToken.
4386
4387+ >>> from canonical.launchpad.interfaces.logintoken import ILoginTokenSet
4388 >>> from canonical.launchpad.webapp.servers import LaunchpadTestRequest
4389- >>> from canonical.launchpad.interfaces import (
4390- ... IExternalBugTrackerTokenAPI, ILoginTokenSet)
4391+ >>> from lp.bugs.interfaces.externalbugtracker import IExternalBugTrackerTokenAPI
4392 >>> from lp.bugs.xmlrpc.bug import (
4393 ... ExternalBugTrackerTokenAPI)
4394
4395
4396=== modified file 'lib/lp/bugs/doc/official-bug-tags.txt'
4397--- lib/lp/bugs/doc/official-bug-tags.txt 2010-10-09 16:36:22 +0000
4398+++ lib/lp/bugs/doc/official-bug-tags.txt 2010-10-21 19:08:55 +0000
4399@@ -3,8 +3,8 @@
4400 Distributions and products can define official bug tags.
4401
4402 >>> from zope.component import getUtility
4403- >>> from canonical.launchpad.interfaces import (
4404- ... IDistributionSet, IProductSet)
4405+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4406+ >>> from lp.registry.interfaces.product import IProductSet
4407 >>> from canonical.launchpad.webapp.interfaces import (
4408 ... IStoreSelector, MAIN_STORE, DEFAULT_FLAVOR)
4409 >>> from lp.bugs.model.bugtarget import OfficialBugTag
4410@@ -169,7 +169,7 @@
4411 >>> ubuntu.official_bug_tags = [u'foo', u'bar']
4412 Traceback (most recent call last):
4413 ...
4414- Unauthorized: (<Distribution 'Ubuntu' (ubuntu)>, 'official_bug_tags', 'launchpad.Edit')
4415+ Unauthorized: (<Distribution 'Ubuntu' (ubuntu)>, 'official_bug_tags', 'launchpad.BugSupervisor')
4416
4417 The same is available for products.
4418
4419
4420=== modified file 'lib/lp/bugs/doc/security-teams.txt'
4421--- lib/lp/bugs/doc/security-teams.txt 2010-10-11 16:17:45 +0000
4422+++ lib/lp/bugs/doc/security-teams.txt 2010-10-21 19:08:55 +0000
4423@@ -5,10 +5,10 @@
4424 a "security contact" on a Distribution or a Product.
4425
4426 >>> from zope.component import getUtility
4427+ >>> from lp.bugs.interfaces.securitycontact import IHasSecurityContact
4428 >>> from lp.registry.interfaces.distribution import IDistributionSet
4429 >>> from lp.registry.interfaces.person import IPersonSet
4430 >>> from lp.registry.interfaces.product import IProductSet
4431- >>> from lp.bugs.interfaces.securitycontact import IHasSecurityContact
4432
4433 >>> personset = getUtility(IPersonSet)
4434 >>> productset = getUtility(IProductSet)
4435@@ -280,10 +280,10 @@
4436 When a bug becomes security-related, the security contacts for the pillars it
4437 affects are subscribed to it.
4438
4439+ >>> from zope.event import notify
4440+ >>> from lazr.lifecycle.event import ObjectModifiedEvent
4441+ >>> from lazr.lifecycle.snapshot import Snapshot
4442 >>> from lp.bugs.interfaces.bug import IBug
4443- >>> from zope.event import notify
4444- >>> from lazr.lifecycle.event import ObjectModifiedEvent
4445- >>> from lazr.lifecycle.snapshot import Snapshot
4446
4447 >>> product = factory.makeProduct()
4448 >>> product.security_contact = factory.makePerson(
4449
4450=== modified file 'lib/lp/bugs/doc/sourceforge-remote-products.txt'
4451--- lib/lp/bugs/doc/sourceforge-remote-products.txt 2010-10-04 19:50:45 +0000
4452+++ lib/lp/bugs/doc/sourceforge-remote-products.txt 2010-10-21 19:08:55 +0000
4453@@ -21,8 +21,8 @@
4454 If we add a Product and link it to a SourceForge project,
4455 getSFLinkedProductsWithNoneRemoteProduct() will return it.
4456
4457+ >>> from lp.testing.factory import LaunchpadObjectFactory
4458 >>> from transaction import commit
4459- >>> from lp.testing.factory import LaunchpadObjectFactory
4460 >>> factory = LaunchpadObjectFactory()
4461
4462 >>> product_1 = factory.makeProduct(name='my-first-product')
4463
4464=== modified file 'lib/lp/bugs/stories/bug-privacy/40-unsubscribe-from-private-bug.txt'
4465--- lib/lp/bugs/stories/bug-privacy/40-unsubscribe-from-private-bug.txt 2010-10-04 20:46:55 +0000
4466+++ lib/lp/bugs/stories/bug-privacy/40-unsubscribe-from-private-bug.txt 2010-10-21 19:08:55 +0000
4467@@ -1,10 +1,11 @@
4468 First, some setup. Find out what the latest [private] bug reported on
4469 Ubuntu evolution is, so we can avoid hardcoding its ID here:
4470
4471- >>> from canonical.launchpad.interfaces import (
4472- ... IDistributionSet, BugTaskSearchParams, ILaunchBag,
4473- ... ISourcePackageNameSet)
4474 >>> from zope.component import getUtility
4475+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
4476+ >>> from lp.bugs.interfaces.bugtask import BugTaskSearchParams
4477+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4478+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
4479 >>> from canonical.launchpad.ftests import login, logout
4480
4481 >>> login("foo.bar@canonical.com")
4482
4483=== modified file 'lib/lp/bugs/stories/bug-tags/xx-official-bug-tags.txt'
4484--- lib/lp/bugs/stories/bug-tags/xx-official-bug-tags.txt 2010-10-15 14:26:57 +0000
4485+++ lib/lp/bugs/stories/bug-tags/xx-official-bug-tags.txt 2010-10-21 19:08:55 +0000
4486@@ -71,6 +71,17 @@
4487 >>> print bug_super_browser.url
4488 http://bugs.launchpad.dev/youbuntu/+manage-official-tags
4489
4490+The bug supervisor can also set the tags for the product.
4491+
4492+ >>> bug_super_browser.getControl('Official Bug Tags').value = 'foo bar'
4493+ >>> bug_super_browser.getControl('Save').click()
4494+ >>> print bug_super_browser.url
4495+ http://bugs.launchpad.dev/youbuntu
4496+ >>> bug_super_browser.open(
4497+ ... 'http://bugs.launchpad.dev/youbuntu/+manage-official-tags')
4498+ >>> print bug_super_browser.getControl('Official Bug Tags').value
4499+ bar foo
4500+
4501 == Official Tags on Bug Pages ==
4502
4503 Official tags are displayed using a different style from unofficial ones.
4504@@ -101,8 +112,8 @@
4505
4506 The tags portlet displays a mix of official and unofficial tags.
4507
4508+ >>> from zope.component import getUtility
4509 >>> from lp.registry.interfaces.product import IProductSet
4510- >>> from zope.component import getUtility
4511 >>> login('foo.bar@canonical.com')
4512 >>> firesocks = factory.makeProduct(name='firesocks')
4513 >>> firesocks_bugs_url = canonical_url(firesocks, rootsite='bugs')
4514
4515=== modified file 'lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt'
4516--- lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt 2010-10-09 16:36:22 +0000
4517+++ lib/lp/bugs/stories/bugattachments/xx-attachments-to-bug-report.txt 2010-10-21 19:08:55 +0000
4518@@ -22,8 +22,8 @@
4519 >>> import StringIO
4520 >>> from zope.component import getUtility
4521 >>> from canonical.launchpad.ftests import login, logout, syncUpdate
4522+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
4523 >>> from lp.bugs.interfaces.bug import IBugSet
4524- >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
4525 >>> login("test@canonical.com")
4526 >>> bug_11 = getUtility(IBugSet).get(11)
4527 >>> launchbag = getUtility(ILaunchBag)
4528
4529=== modified file 'lib/lp/bugs/stories/bugs/xx-bug-nomination-table-row.txt'
4530--- lib/lp/bugs/stories/bugs/xx-bug-nomination-table-row.txt 2010-10-10 15:39:28 +0000
4531+++ lib/lp/bugs/stories/bugs/xx-bug-nomination-table-row.txt 2010-10-21 19:08:55 +0000
4532@@ -12,9 +12,9 @@
4533 >>> from zope.component import getUtility
4534
4535 >>> from canonical.launchpad.ftests import login, logout
4536+ >>> from canonical.launchpad.webapp.authorization import check_permission
4537 >>> from lp.bugs.interfaces.bug import IBugSet
4538 >>> from lp.registry.interfaces.distribution import IDistributionSet
4539- >>> from canonical.launchpad.webapp.authorization import check_permission
4540
4541 >>> login("no-priv@canonical.com")
4542
4543
4544=== modified file 'lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt'
4545--- lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt 2010-10-03 15:30:06 +0000
4546+++ lib/lp/bugs/stories/bugs/xx-bugs-advanced-search-upstream-status.txt 2010-10-21 19:08:55 +0000
4547@@ -39,8 +39,9 @@
4548
4549 >>> from zope.component import getUtility
4550 >>> from canonical.launchpad.ftests import login, logout, syncUpdate
4551- >>> from canonical.launchpad.interfaces import (
4552- ... BugTaskStatus, IBugSet, ILaunchBag)
4553+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
4554+ >>> from lp.bugs.interfaces.bug import IBugSet
4555+ >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
4556
4557 >>> login("foo.bar@canonical.com")
4558
4559
4560=== modified file 'lib/lp/bugs/stories/bugs/xx-front-page-bug-lists.txt'
4561--- lib/lp/bugs/stories/bugs/xx-front-page-bug-lists.txt 2010-10-03 15:30:06 +0000
4562+++ lib/lp/bugs/stories/bugs/xx-front-page-bug-lists.txt 2010-10-21 19:08:55 +0000
4563@@ -9,8 +9,11 @@
4564 >>> from zope.component import getUtility
4565 >>> from canonical.launchpad.ftests import login, logout
4566 >>> import transaction
4567- >>> from canonical.launchpad.interfaces import (
4568- ... BugTaskImportance, BugTaskStatus, ILaunchBag)
4569+ >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
4570+ >>> from lp.bugs.interfaces.bugtask import (
4571+ ... BugTaskImportance,
4572+ ... BugTaskStatus,
4573+ ... )
4574 >>> login('foo.bar@canonical.com')
4575 >>> bigfixer = factory.makeProduct(name='bigfixer')
4576 >>> for bug_x in range(1, 11):
4577
4578=== modified file 'lib/lp/bugs/stories/bugs/xx-incomplete-bugs.txt'
4579--- lib/lp/bugs/stories/bugs/xx-incomplete-bugs.txt 2010-10-09 16:36:22 +0000
4580+++ lib/lp/bugs/stories/bugs/xx-incomplete-bugs.txt 2010-10-21 19:08:55 +0000
4581@@ -104,9 +104,9 @@
4582 detailing the amount of time that has passed since the bug's expiration
4583 date. We alter the date_last_updated field of bug 11 to demonstrate this.
4584
4585- >>> from datetime import timedelta
4586 >>> from zope.component import getUtility
4587 >>> from canonical.database.sqlbase import flush_database_updates
4588+ >>> from datetime import timedelta
4589 >>> from canonical.launchpad.ftests import login, logout
4590 >>> from lp.bugs.interfaces.bug import IBugSet
4591 >>> login('test@canonical.com')
4592
4593=== modified file 'lib/lp/bugs/stories/bugs/xx-portlets-bug-milestones.txt'
4594--- lib/lp/bugs/stories/bugs/xx-portlets-bug-milestones.txt 2010-10-08 12:06:55 +0000
4595+++ lib/lp/bugs/stories/bugs/xx-portlets-bug-milestones.txt 2010-10-21 19:08:55 +0000
4596@@ -55,8 +55,8 @@
4597 >>> print ff_bugtask.bug.id
4598 4
4599
4600+ >>> from lp.registry.interfaces.milestone import IMilestoneSet
4601 >>> from lp.registry.interfaces.product import IProductSet
4602- >>> from lp.registry.interfaces.milestone import IMilestoneSet
4603 >>> firefox = getUtility(IProductSet).getByName('firefox')
4604 >>> ff_milestone = getUtility(IMilestoneSet).getByNameAndProduct(
4605 ... "1.0", firefox)
4606
4607=== modified file 'lib/lp/bugs/stories/bugs/xx-remote-bug-comments.txt'
4608--- lib/lp/bugs/stories/bugs/xx-remote-bug-comments.txt 2010-10-14 18:42:19 +0000
4609+++ lib/lp/bugs/stories/bugs/xx-remote-bug-comments.txt 2010-10-21 19:08:55 +0000
4610@@ -72,9 +72,9 @@
4611 the 'awaiting synchronization' mark goes away.
4612
4613 >>> from zope.component import getUtility
4614+ >>> from canonical.database.sqlbase import flush_database_updates
4615 >>> from lp.bugs.interfaces.bug import IBugSet
4616 >>> from lp.bugs.interfaces.bugmessage import IBugMessageSet
4617- >>> from canonical.database.sqlbase import flush_database_updates
4618 >>> login('foo.bar@canonical.com')
4619 >>> bug_15 = getUtility(IBugSet).get(15)
4620 >>> message = bug_15.messages[-1]
4621
4622=== modified file 'lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt'
4623--- lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt 2010-10-03 15:30:06 +0000
4624+++ lib/lp/bugs/stories/bugtask-management/xx-bug-importance-change.txt 2010-10-21 19:08:55 +0000
4625@@ -23,8 +23,9 @@
4626 >>> from zope.component import getUtility
4627
4628 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
4629- >>> from canonical.launchpad.interfaces import (
4630- ... IPersonSet, IProductSet, IDistributionSet)
4631+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4632+ >>> from lp.registry.interfaces.person import IPersonSet
4633+ >>> from lp.registry.interfaces.product import IProductSet
4634
4635 >>> login("foo.bar@canonical.com")
4636
4637
4638=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt'
4639--- lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt 2010-10-06 18:27:57 +0000
4640+++ lib/lp/bugs/stories/bugtask-searches/xx-listing-basics.txt 2010-10-21 19:08:55 +0000
4641@@ -233,10 +233,11 @@
4642 Patches also appear as badges in bug listings.
4643
4644 >>> from canonical.launchpad.ftests import login, logout
4645- >>> from canonical.launchpad.interfaces import (
4646- ... IBugSet, IMessageSet, IPersonSet)
4647 >>> from zope.component import getUtility
4648 >>> from StringIO import StringIO
4649+ >>> from canonical.launchpad.interfaces.message import IMessageSet
4650+ >>> from lp.bugs.interfaces.bug import IBugSet
4651+ >>> from lp.registry.interfaces.person import IPersonSet
4652 >>> import transaction
4653 >>> login("foo.bar@canonical.com")
4654 >>> foobar = getUtility(IPersonSet).getByName("name16")
4655
4656=== modified file 'lib/lp/bugs/stories/bugtask-searches/xx-searching-by-tags.txt'
4657--- lib/lp/bugs/stories/bugtask-searches/xx-searching-by-tags.txt 2010-10-03 15:30:06 +0000
4658+++ lib/lp/bugs/stories/bugtask-searches/xx-searching-by-tags.txt 2010-10-21 19:08:55 +0000
4659@@ -7,9 +7,10 @@
4660
4661 First, we create some bugs.
4662
4663- >>> from canonical.launchpad.interfaces import (
4664- ... IPersonSet, IProductSet, CreateBugParams)
4665 >>> from zope.component import getUtility
4666+ >>> from lp.bugs.interfaces.bug import CreateBugParams
4667+ >>> from lp.registry.interfaces.person import IPersonSet
4668+ >>> from lp.registry.interfaces.product import IProductSet
4669 >>> from canonical.launchpad.ftests import login, logout
4670
4671 >>> login("no-priv@canonical.com")
4672
4673=== modified file 'lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt'
4674--- lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt 2010-08-26 14:57:11 +0000
4675+++ lib/lp/bugs/stories/bugwatches/xx-edit-bugwatch.txt 2010-10-21 19:08:55 +0000
4676@@ -60,9 +60,9 @@
4677 If we change the next_check date of the watch its will be shown in the
4678 Next check column.
4679
4680+ >>> from zope.component import getUtility
4681 >>> from datetime import datetime
4682 >>> from pytz import utc
4683- >>> from zope.component import getUtility
4684
4685 >>> from canonical.launchpad.ftests import login, logout
4686 >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
4687
4688=== modified file 'lib/lp/bugs/stories/cve/cve-linking.txt'
4689--- lib/lp/bugs/stories/cve/cve-linking.txt 2010-10-11 16:17:45 +0000
4690+++ lib/lp/bugs/stories/cve/cve-linking.txt 2010-10-21 19:08:55 +0000
4691@@ -109,9 +109,9 @@
4692 # This should use a private bug in our sample data.
4693 >>> from zope.component import getUtility
4694 >>> from canonical.launchpad.ftests import login, logout
4695+ >>> from canonical.database.sqlbase import flush_database_updates
4696 >>> from canonical.launchpad.webapp.interfaces import ILaunchBag
4697 >>> from lp.bugs.interfaces.bug import IBugSet
4698- >>> from canonical.database.sqlbase import flush_database_updates
4699 >>> login('foo.bar@canonical.com')
4700 >>> private_bug = getUtility(IBugSet).get(6)
4701 >>> current_user = getUtility(ILaunchBag).user
4702
4703=== modified file 'lib/lp/bugs/stories/feeds/xx-bug-atom.txt'
4704--- lib/lp/bugs/stories/feeds/xx-bug-atom.txt 2010-10-09 16:36:22 +0000
4705+++ lib/lp/bugs/stories/feeds/xx-bug-atom.txt 2010-10-21 19:08:55 +0000
4706@@ -338,8 +338,8 @@
4707 This feed gets the latest bugs for a whole team.
4708 First, make a team responsible for some bugs.
4709
4710+ >>> from zope.component import getUtility
4711 >>> from lp.registry.interfaces.person import IPersonSet
4712- >>> from zope.component import getUtility
4713 >>> one_mem_browser = setupBrowser(
4714 ... auth='Basic one-membership@test.com:test')
4715 >>> personset = getUtility(IPersonSet)
4716
4717=== modified file 'lib/lp/bugs/stories/feeds/xx-bug-html.txt'
4718--- lib/lp/bugs/stories/feeds/xx-bug-html.txt 2009-10-13 19:51:20 +0000
4719+++ lib/lp/bugs/stories/feeds/xx-bug-html.txt 2010-10-21 19:08:55 +0000
4720@@ -4,8 +4,10 @@
4721 The content of an HTML feed is very similar to an Atom feed, but is formatted
4722 as HTML instead of Atom.
4723
4724- >>> from BeautifulSoup import BeautifulSoup
4725- >>> from BeautifulSoup import SoupStrainer
4726+ >>> from BeautifulSoup import (
4727+ ... BeautifulSoup,
4728+ ... SoupStrainer,
4729+ ... )
4730
4731 Define a helper function for parsing the entries:
4732
4733
4734=== modified file 'lib/lp/bugs/stories/structural-subscriptions/xx-bug-subscriptions.txt'
4735--- lib/lp/bugs/stories/structural-subscriptions/xx-bug-subscriptions.txt 2010-10-06 18:53:53 +0000
4736+++ lib/lp/bugs/stories/structural-subscriptions/xx-bug-subscriptions.txt 2010-10-21 19:08:55 +0000
4737@@ -74,8 +74,8 @@
4738 Firstly, we appoint Sample Person as the driver for the distribution.
4739
4740 >>> from canonical.database.sqlbase import flush_database_updates
4741- >>> from canonical.launchpad.interfaces import (
4742- ... IDistributionSet, IPersonSet)
4743+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4744+ >>> from lp.registry.interfaces.person import IPersonSet
4745 >>> from canonical.launchpad.ftests import login, logout
4746 >>> from zope.component import getUtility
4747 >>> login('foo.bar@canonical.com')
4748
4749=== modified file 'lib/lp/bugs/stories/webservice/xx-bug.txt'
4750--- lib/lp/bugs/stories/webservice/xx-bug.txt 2010-09-20 19:23:08 +0000
4751+++ lib/lp/bugs/stories/webservice/xx-bug.txt 2010-10-21 19:08:55 +0000
4752@@ -116,8 +116,8 @@
4753 Activity is recorded and notifications are sent for newly created
4754 bugs.
4755
4756+ >>> from lp.bugs.interfaces.bug import IBugSet
4757 >>> from lp.bugs.model.bugnotification import BugNotification
4758- >>> from lp.bugs.interfaces.bug import IBugSet
4759 >>> from canonical.launchpad.ftests import ANONYMOUS, login, logout
4760 >>> from zope.component import getUtility
4761
4762
4763=== modified file 'lib/lp/bugs/tests/buglinktarget.txt'
4764--- lib/lp/bugs/tests/buglinktarget.txt 2010-10-03 15:30:06 +0000
4765+++ lib/lp/bugs/tests/buglinktarget.txt 2010-10-21 19:08:55 +0000
4766@@ -16,8 +16,11 @@
4767 # to a registered user.
4768 >>> login('no-priv@canonical.com')
4769 >>> from zope.interface.verify import verifyObject
4770- >>> from canonical.launchpad.interfaces import (
4771- ... IBugLinkTarget, IBugLink, IBugSet)
4772+ >>> from lp.bugs.interfaces.bug import IBugSet
4773+ >>> from lp.bugs.interfaces.buglink import (
4774+ ... IBugLink,
4775+ ... IBugLinkTarget,
4776+ ... )
4777
4778 >>> verifyObject(IBugLinkTarget, target)
4779 True
4780
4781=== modified file 'lib/lp/bugs/tests/bugs-emailinterface.txt'
4782--- lib/lp/bugs/tests/bugs-emailinterface.txt 2010-10-09 16:36:22 +0000
4783+++ lib/lp/bugs/tests/bugs-emailinterface.txt 2010-10-21 19:08:55 +0000
4784@@ -339,8 +339,7 @@
4785 will provide IWeaklyAuthenticatedPrincipal. Let's mark the current
4786 principal with that.
4787
4788- >>> from canonical.launchpad.interfaces import (
4789- ... IWeaklyAuthenticatedPrincipal)
4790+ >>> from canonical.launchpad.interfaces.mail import IWeaklyAuthenticatedPrincipal
4791 >>> from zope.interface import directlyProvides, directlyProvidedBy
4792 >>> from zope.security.management import queryInteraction
4793 >>> participations = queryInteraction().participations
4794@@ -1222,8 +1221,8 @@
4795 bugs directly to series.
4796
4797 >>> from canonical.config import config
4798- >>> from lp.registry.interfaces.distribution import IDistributionSet
4799 >>> from canonical.testing.layers import LaunchpadZopelessLayer
4800+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4801
4802 # The script's default user doesn't have permission to change the driver.
4803 >>> commit()
4804@@ -1648,8 +1647,8 @@
4805 The user is a package bug supervisor
4806 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4807
4808- >>> from canonical.launchpad.interfaces import (
4809- ... IDistributionSet, ISourcePackageNameSet)
4810+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4811+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
4812
4813 >>> commit()
4814 >>> LaunchpadZopelessLayer.switchDbUser('launchpad')
4815@@ -2880,8 +2879,8 @@
4816 >>> from lp.bugs.interfaces.bugtracker import BugTrackerType
4817 >>> from lp.bugs.tests.externalbugtracker import (
4818 ... new_bugtracker)
4819- >>> from canonical.launchpad.interfaces import (
4820- ... IBugWatchSet, IProductSet)
4821+ >>> from lp.bugs.interfaces.bugwatch import IBugWatchSet
4822+ >>> from lp.registry.interfaces.product import IProductSet
4823
4824 >>> firefox = getUtility(IProductSet).getByName('firefox')
4825 >>> no_priv = getUtility(IPersonSet).getByName('no-priv')
4826
4827=== modified file 'lib/lp/bugs/tests/bugtarget-questiontarget.txt'
4828--- lib/lp/bugs/tests/bugtarget-questiontarget.txt 2010-10-09 16:36:22 +0000
4829+++ lib/lp/bugs/tests/bugtarget-questiontarget.txt 2010-10-21 19:08:55 +0000
4830@@ -13,8 +13,8 @@
4831 Product, Distribution, ProductSeries, DistributionSeries,
4832 SourcePackage, or DistributionSourcePackages.
4833
4834- >>> from canonical.launchpad.interfaces import (
4835- ... IBugTarget, IQuestionTarget)
4836+ >>> from lp.answers.interfaces.questiontarget import IQuestionTarget
4837+ >>> from lp.bugs.interfaces.bugtarget import IBugTarget
4838
4839 >>> login('foo.bar@canonical.com')
4840 >>> IBugTarget.providedBy(bugtarget)
4841@@ -177,8 +177,9 @@
4842 >>> big_bug = filebug(
4843 ... bugtarget, "Print is borked", status=BugTaskStatus.NEW)
4844
4845- >>> from canonical.launchpad.interfaces import (
4846- ... IBugTaskSet, IDistributionSet, ISourcePackageNameSet)
4847+ >>> from lp.bugs.interfaces.bugtask import IBugTaskSet
4848+ >>> from lp.registry.interfaces.distribution import IDistributionSet
4849+ >>> from lp.registry.interfaces.sourcepackagename import ISourcePackageNameSet
4850
4851 >>> ubuntu = getUtility(IDistributionSet)['ubuntu']
4852 >>> evo_ubuntu = getUtility(ISourcePackageNameSet)['evolution']
4853
4854=== modified file 'lib/lp/code/browser/tests/test_branchlisting.py'
4855--- lib/lp/code/browser/tests/test_branchlisting.py 2010-08-24 02:21:50 +0000
4856+++ lib/lp/code/browser/tests/test_branchlisting.py 2010-10-21 19:08:55 +0000
4857@@ -44,6 +44,7 @@
4858 from lp.testing import (
4859 BrowserTestCase,
4860 login_person,
4861+ normalize_whitespace,
4862 person_logged_in,
4863 TestCase,
4864 TestCaseWithFactory,
4865@@ -421,5 +422,37 @@
4866 self.assertIs(None, branches)
4867
4868
4869+class TestProjectBranchListing(TestCaseWithFactory):
4870+
4871+ layer = DatabaseFunctionalLayer
4872+
4873+ def setUp(self):
4874+ super(TestProjectBranchListing, self).setUp()
4875+ self.project = self.factory.makeProject()
4876+ self.product = self.factory.makeProduct(project=self.project)
4877+
4878+ def test_no_branches_gets_message_not_listing(self):
4879+ # If there are no product branches on the project's products, then
4880+ # the view shows the no code hosting message instead of a listing.
4881+ browser = self.getUserBrowser(
4882+ canonical_url(self.project, rootsite='code'))
4883+ displayname = self.project.displayname
4884+ expected_text = normalize_whitespace(
4885+ ("Launchpad does not know where any of %s's "
4886+ "projects host their code." % displayname))
4887+ no_branch_div = find_tag_by_id(browser.contents, "no-branchtable")
4888+ text = normalize_whitespace(extract_text(no_branch_div))
4889+ self.assertEqual(expected_text, text)
4890+
4891+ def test_branches_get_listing(self):
4892+ # If a product has a branch, then the project view has a branch
4893+ # listing.
4894+ branch = self.factory.makeProductBranch(product=self.product)
4895+ browser = self.getUserBrowser(
4896+ canonical_url(self.project, rootsite='code'))
4897+ table = find_tag_by_id(browser.contents, "branchtable")
4898+ self.assertIsNot(None, table)
4899+
4900+
4901 def test_suite():
4902 return unittest.TestLoader().loadTestsFromName(__name__)
4903
4904=== modified file 'lib/lp/code/doc/branch-merge-proposal-notifications.txt'
4905--- lib/lp/code/doc/branch-merge-proposal-notifications.txt 2010-05-27 02:04:21 +0000
4906+++ lib/lp/code/doc/branch-merge-proposal-notifications.txt 2010-10-21 19:08:55 +0000
4907@@ -9,8 +9,8 @@
4908 When subscribers subscribe to branches, they can specify what level of
4909 notification they would like to receive.
4910
4911+ >>> from zope.security.proxy import removeSecurityProxy
4912 >>> from difflib import unified_diff
4913- >>> from zope.security.proxy import removeSecurityProxy
4914 >>> from lp.code.enums import (
4915 ... BranchSubscriptionDiffSize, BranchSubscriptionNotificationLevel,
4916 ... CodeReviewNotificationLevel)
4917@@ -101,7 +101,7 @@
4918 ... displayname="Eric", email="eric@example.com")
4919 >>> # To avoid needing to access branches, pre-populate diffs.
4920 >>> bmp = source_branch.addLandingTarget(
4921- ... registrant, target_branch)
4922+ ... registrant, target_branch, needs_review=True)
4923 >>> removeSecurityProxy(bmp).preview_diff = preview_diff
4924 >>> # Fake the update preview diff as done.
4925 >>> bmp.next_preview_diff_job.start()
4926@@ -156,7 +156,8 @@
4927 >>> bmp.deleteProposal()
4928 >>> bmp = source_branch.addLandingTarget(
4929 ... registrant, target_branch,
4930- ... description=initial_comment, review_requests=reviewers)
4931+ ... description=initial_comment, review_requests=reviewers,
4932+ ... needs_review=True)
4933 >>> removeSecurityProxy(bmp).preview_diff = preview_diff
4934 >>> # Fake the update preview diff as done.
4935 >>> bmp.next_preview_diff_job.start()
4936
4937=== modified file 'lib/lp/code/doc/branch-visibility.txt'
4938--- lib/lp/code/doc/branch-visibility.txt 2010-10-03 15:30:06 +0000
4939+++ lib/lp/code/doc/branch-visibility.txt 2010-10-21 19:08:55 +0000
4940@@ -60,8 +60,8 @@
4941 AccessBranch authorization class is used to authorize users for the
4942 combination of the launchpad.View permission and the IBranch interface.
4943
4944+ >>> from zope.component import getAdapter
4945 >>> from canonical.launchpad.webapp.interfaces import IAuthorization
4946- >>> from zope.component import getAdapter
4947 >>> getAdapter(branch, IAuthorization, name='launchpad.View')
4948 <canonical.launchpad.security.AccessBranch ...>
4949
4950
4951=== modified file 'lib/lp/code/doc/codeimport-event.txt'
4952--- lib/lp/code/doc/codeimport-event.txt 2010-10-03 15:30:06 +0000
4953+++ lib/lp/code/doc/codeimport-event.txt 2010-10-21 19:08:55 +0000
4954@@ -19,8 +19,8 @@
4955 ICodeImportEventSet utility.
4956
4957 >>> from zope.component import getUtility
4958+ >>> from zope.security.proxy import removeSecurityProxy
4959 >>> from canonical.launchpad.webapp.testing import verifyObject
4960- >>> from zope.security.proxy import removeSecurityProxy
4961 >>> from lp.code.interfaces.codeimportevent import ICodeImportEventSet
4962 >>> event_set = getUtility(ICodeImportEventSet)
4963 >>> verifyObject(ICodeImportEventSet, removeSecurityProxy(event_set))
4964
4965=== modified file 'lib/lp/code/doc/codeimport-job.txt'
4966--- lib/lp/code/doc/codeimport-job.txt 2009-06-12 16:36:02 +0000
4967+++ lib/lp/code/doc/codeimport-job.txt 2010-10-21 19:08:55 +0000
4968@@ -49,8 +49,8 @@
4969
4970 There are two CodeImport objects of interest in the sample data.
4971
4972- >>> from lp.code.interfaces.codeimport import ICodeImportSet
4973 >>> from lp.code.interfaces.branchlookup import IBranchLookup
4974+ >>> from lp.code.interfaces.codeimport import ICodeImportSet
4975 >>> branch_lookup = getUtility(IBranchLookup)
4976 >>> code_import_set = getUtility(ICodeImportSet)
4977
4978
4979=== modified file 'lib/lp/code/doc/codeimport.txt'
4980--- lib/lp/code/doc/codeimport.txt 2010-10-03 15:30:06 +0000
4981+++ lib/lp/code/doc/codeimport.txt 2010-10-21 19:08:55 +0000
4982@@ -23,9 +23,9 @@
4983
4984 >>> from lp.code.interfaces.branchtarget import IBranchTarget
4985 >>> from lp.code.interfaces.codeimport import ICodeImport, ICodeImportSet
4986- >>> from canonical.launchpad.webapp.testing import verifyObject
4987 >>> from zope.component import getUtility
4988 >>> from zope.security.proxy import removeSecurityProxy
4989+ >>> from canonical.launchpad.webapp.testing import verifyObject
4990 >>> code_import_set = getUtility(ICodeImportSet)
4991 >>> verifyObject(ICodeImportSet, removeSecurityProxy(code_import_set))
4992 True
4993@@ -341,8 +341,8 @@
4994 There is a separate default update interval for each version control system,
4995 set in the Launchpad configuration system.
4996
4997+ >>> from canonical.config import config
4998 >>> from datetime import timedelta
4999- >>> from canonical.config import config
5000 >>> default_interval_cvs = timedelta(
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to status/vote changes: