← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~sinzui/launchpad/obsolete-add-edit into lp:launchpad/devel

 

Curtis Hovey has proposed merging lp:~sinzui/launchpad/obsolete-add-edit into lp:launchpad/devel.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)
Related bugs:
  #414857 Convert SignedCodeOfConductDeactiveView to LaunchpadFormView
  https://bugs.launchpad.net/bugs/414857
  #433074 Remove launchpad-addform.pt and launchpad-editform.pt
  https://bugs.launchpad.net/bugs/433074


This is my branch to remove addform and editform.

    lp:~sinzui/launchpad/obsolete-add-edit
    Diff size: 710
    Launchpad bug:
        https://bugs.launchpad.net/bugs/433074
        https://bugs.launchpad.net/bugs/414857
    Test command: ./bin/test -vv \
          -t coc -t codeofconduct
    Pre-implementation: no one
    Target release: 10.11


Remove addform and editform
---------------------------

These two templates are only used for their macros.

  lib/canonical/launchpad/templates/launchpad-addform.pt
  lib/canonical/launchpad/templates/launchpad-editform.pt

These are the last templates to use them.

    ./lib/lp/registry/templates/signedcodeofconduct-acknowledge.pt:11:
    ./lib/lp/registry/templates/signedcodeofconduct-activate.pt:11:
    ./lib/lp/registry/templates/signedcodeofconduct-deactivate.pt:11:


Rules
-----

    * Add tests for the existing behaviour
    * Convert the views to LaunchpadFormView
    * Update the ZCML to use the generic edit template


QA
--

As an admin, choose a user that has not signed the CoC to test with

    * Visit https://staging.launchpad.net/codeofconduct
    * Search for the user and verify he does has not signed the CoC.
    * Follow the register link.
    * Enter the user's name and choose Register.
    * Search for the user and view his signed CoC record.
    * Verify his CoC is active.
    * Choose to edit icon
    * Add a comment and choose Deactivate.
    * Verify the CoC now states it is inactive.
    * Choose to edit icon
    * Add a comment and choose Activate.
    * Verify the CoC now states it is active.


Lint
----

Linting changed files:
  lib/canonical/launchpad/zcml/widgets.zcml
  lib/lp/registry/browser/codeofconduct.py
  lib/lp/registry/browser/configure.zcml
  lib/lp/registry/browser/tests/test_codeofconduct.py
  lib/lp/registry/stories/gpg-coc/98-cocacknowledge.txt
       3: source has bad indentation.
      12: source has bad indentation.
      16: source exceeds 78 characters.
      16: source has bad indentation.
      23: source has bad indentation.
      32: source has bad indentation.

^ I can fix this after the review. The indentation changes will make the diff
difficult to read.


Test
----

    * lib/lp/registry/browser/tests/test_codeofconduct.py
      * Added tests for the signed CoC management views.
    * lib/lp/registry/stories/gpg-coc/98-cocacknowledge.txt
      * Updated the story to use the information the user sees.


Implementation
--------------

    * lib/canonical/launchpad/zcml/widgets.zcml
      * Unregistered the deleted templates.
      * I could move the two remaining templates to lp/app and extract
        the last widget ZCML to lp/app/browser/configure.zcml to remove this
        file.
    * lib/lp/registry/browser/codeofconduct.py
      * Converted the AddView and EditView views into LaunchpadFormViews.
      * This looks like a 100% rewrite in the diff, but I made these changes
        using small refactorings. I am surprised I did this much.
    * lib/lp/registry/browser/configure.zcml
      * Replaced the add/edit ZCML with page ZCML.
-- 
https://code.launchpad.net/~sinzui/launchpad/obsolete-add-edit/+merge/38377
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~sinzui/launchpad/obsolete-add-edit into lp:launchpad/devel.
=== removed file 'lib/canonical/launchpad/templates/launchpad-addform.pt'
--- lib/canonical/launchpad/templates/launchpad-addform.pt	2009-09-18 20:25:59 +0000
+++ lib/canonical/launchpad/templates/launchpad-addform.pt	1970-01-01 00:00:00 +0000
@@ -1,81 +0,0 @@
-<html
-  xmlns="http://www.w3.org/1999/xhtml";
-  xmlns:tal="http://xml.zope.org/namespaces/tal";
-  xmlns:metal="http://xml.zope.org/namespaces/metal";
-  metal:use-macro="view/macro:page/main_only"
->
-  <body>
-
-    <div metal:fill-slot="main">
-
-  <div tal:condition="nothing">
-    This file is a modified version of zope/app/form/browser/add.pt for use
-    in the Launchpad system. You should not edit this file, but rather use
-    it as the default_template attribute of your addform. You create your
-    own template for the specific addform, called table-add.pt for example,
-    which is the template which uses this one.
-  </div>
-
-  <div metal:define-macro="addform">
-
-    <form action="."
-          tal:attributes="action request/URL"
-          method="post"
-          enctype="multipart/form-data"
-          accept-charset="UTF-8">
-
-      <div metal:define-macro="formbody">
-
-        <h1
-          tal:condition="view/label"
-          tal:content="view/label"
-          metal:define-slot="heading"
-        >Add Something</h1>
-
-        <p metal:define-slot="extra_info" tal:replace="nothing">
-          This is the description of the add form.
-          This text will be in bold, beneath the title of the add form,
-          and should explain a little bit about the form.
-        </p>
-
-        <p class="error message"
-           tal:define="status view/update"
-           tal:condition="status"
-           tal:content="status" />
-
-        <div class="row"
-             metal:define-slot="extra_top"
-             tal:replace="nothing">
-            <div>Extra top</div>
-            <div><input type="text" style="width:100%" /></div>
-        </div>
-
-        <div metal:use-macro="context/@@launchpad_widget_macros/launchpad_widget_rows" />
-
-        <div class="row"
-             metal:define-slot="extra_bottom"
-             tal:replace="nothing">
-          <div>Extra bottom</div>
-          <div class="field"><input type="text" style="width:100%" /></div>
-        </div>
-
-      </div>
-      <div class="actions">
-          <input type="submit"
-                 value="Add"
-                 name="UPDATE_SUBMIT" />
-      </div>
-
-      <div class="row"
-           metal:define-slot="extra_buttons"
-           tal:replace="nothing">
-      </div>
-
-    </form>
-  </div>
-
-  </div>
-  </body>
-
-</html>
-

=== removed file 'lib/canonical/launchpad/templates/launchpad-editform.pt'
--- lib/canonical/launchpad/templates/launchpad-editform.pt	2009-09-18 20:25:59 +0000
+++ lib/canonical/launchpad/templates/launchpad-editform.pt	1970-01-01 00:00:00 +0000
@@ -1,104 +0,0 @@
-<html
-  xmlns="http://www.w3.org/1999/xhtml";
-  xmlns:tal="http://xml.zope.org/namespaces/tal";
-  xmlns:metal="http://xml.zope.org/namespaces/metal";
-  metal:use-macro="view/macro:page/main_only"
->
-  <body>
-
-  <div metal:fill-slot="main">
-
-  <div tal:condition="nothing">
-    This file is a modified version of zope/app/form/browser/edit.pt for use
-    in the Launchpad system. You should not edit this file, but rather use
-    it from your custom editform. You create your own template for the
-    specific editform, called table-edit.pt for example, which is the template
-    which uses this one.</div>
-
-    <div metal:define-macro="editform">
-
-      <h1
-        tal:condition="view/label"
-        tal:content="view/label"
-      >Edit something</h1>
-
-      <form action="." tal:attributes="action request/URL" method="post"
-            enctype="multipart/form-data">
-
-        <div metal:define-macro="formbody">
-
-          <p class="informational message"
-             tal:define="status view/update"
-             tal:condition="status"
-             tal:content="status" />
-
-          <tal:errors
-            define="errors view/errors|nothing;
-              num_errors view/errors/count:len"
-            condition="errors"
-          >
-            <p tal:condition="python: num_errors == 1" class="error message">
-              There is a problem with the information you entered.
-              Please fix it and try again.
-            </p>
-            <p tal:condition="python: num_errors > 1" class="error message">
-              There are
-              <tal:errors replace="num_errors">6</tal:errors>
-              problems with the information you entered.
-              Please fix them and try again.
-            </p>
-          </tal:errors>
-
-          <p class="error message"
-            tal:repeat="top_of_page_error view/top_of_page_errors|nothing"
-            tal:content="structure top_of_page_error">
-            Schema validation errors.
-          </p>
-
-          <div metal:define-slot="extra_info"
-            class="documentDescription"
-            tal:replace="nothing">
-            This is where a document heading paragraph can be inserted. In
-            your actual customised editform, you can fill-slot this with
-            a descriptive paragraph.
-          </div>
-
-          <div class="row"
-               metal:define-slot="extra_top" tal:replace="nothing">
-            <div>Extra top</div>
-            <div class="field"><input type="text" style="width:100%" /></div>
-          </div>
-
-          <div metal:use-macro="context/@@launchpad_widget_macros/launchpad_widget_rows" />
-
-          <div class="separator"></div>
-
-          <div class="row"
-               metal:define-slot="extra_bottom" tal:replace="nothing">
-            <div>Extra bottom</div>
-            <div class="field"><input type="text" style="width:100%" /></div>
-          </div>
-
-        </div>
-
-        <div class="actions">
-          <input
-            type="submit"
-            name="UPDATE_SUBMIT"
-            value="Change"
-          />
-        </div>
-
-        <div class="row" metal:define-slot="extra_buttons"
-              tal:replace="nothing">
-        </div>
-
-        <div class="separator"></div>
-
-      </form>
-
-    </div>
-  </div>
-
-  </body>
-</html>

=== modified file 'lib/canonical/launchpad/zcml/widgets.zcml'
--- lib/canonical/launchpad/zcml/widgets.zcml	2009-07-13 18:15:02 +0000
+++ lib/canonical/launchpad/zcml/widgets.zcml	2010-10-14 01:16:08 +0000
@@ -13,22 +13,6 @@
         in Launchpad -->
     <browser:page
         for="*"
-        name="launchpad_addform"
-        layer="canonical.launchpad.layers.LaunchpadLayer"
-        permission="zope.Public"
-        template="../templates/launchpad-addform.pt"
-        />
-
-    <browser:page
-        for="*"
-        name="launchpad_editform"
-        layer="canonical.launchpad.layers.LaunchpadLayer"
-        permission="zope.Public"
-        template="../templates/launchpad-editform.pt"
-        />
-
-    <browser:page
-        for="*"
         name="launchpad_form"
         layer="canonical.launchpad.layers.LaunchpadLayer"
         permission="zope.Public"

=== modified file 'lib/lp/registry/browser/codeofconduct.py'
--- lib/lp/registry/browser/codeofconduct.py	2010-08-20 20:31:18 +0000
+++ lib/lp/registry/browser/codeofconduct.py	2010-10-14 01:16:08 +0000
@@ -23,10 +23,6 @@
     'SignedCodeOfConductDeactiveView',
     ]
 
-from zope.app.form.browser.add import (
-    AddView,
-    EditView,
-    )
 from zope.component import getUtility
 
 from canonical.launchpad.webapp import (
@@ -49,7 +45,6 @@
     ISignedCodeOfConduct,
     ISignedCodeOfConductSet,
     )
-from lp.registry.interfaces.person import IPerson
 
 
 class SignedCodeOfConductSetNavigation(GetitemNavigation):
@@ -197,38 +192,24 @@
         return coc_set[coc_conf.currentrelease]
 
 
-class SignedCodeOfConductAckView(AddView):
+class SignedCodeOfConductAckView(LaunchpadFormView):
     """Acknowledge a Paper Submitted CoC."""
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-        self.bag = getUtility(ILaunchBag)
-        self._nextURL = '.'
-        self.page_title = self.label
-        AddView.__init__(self, context, request)
-
-    def createAndAdd(self, data):
+    schema = ISignedCodeOfConduct
+    field_names = ['owner']
+    label = 'Register a code of conduct signature'
+    page_title = label
+
+    @property
+    def next_url(self):
+        return canonical_url(self.context)
+
+    cancel_url = next_url
+
+    @action('Register', name='add')
+    def createAndAdd(self, action, data):
         """Verify and Add the Acknowledge SignedCoC entry."""
-        kw = {}
-
-        for key, value in data.items():
-            kw[str(key)] = value
-
-        # XXX cprov 2005-03-23:
-        # rename unused key:value
-        kw['user'] = kw['owner']
-        del kw['owner']
-
-        recipient = getUtility(ILaunchBag).user
-        kw['recipient'] = recipient
-
-        # use utility to store it in the database
-        sCoC_util = getUtility(ISignedCodeOfConductSet)
-        sCoC_util.acknowledgeSignature(**kw)
-
-    def nextURL(self):
-        return self._nextURL
+        self.context.acknowledgeSignature(
+            user=data['owner'], recipient=self.user)
 
 
 class SignedCodeOfConductView:
@@ -265,86 +246,39 @@
         return True
 
 
-# XXX: salgado, bug=414861, 2009-08-17: This view must be converted to a
-# LaunchpadFormView and define a 'cancel_url' so that the form gets a cancel
-# link.
-class SignedCodeOfConductActiveView(EditView):
-    """Active a SignedCodeOfConduct Entry.
-    When activating a signature:
-     * Grant a new admincomment,
-     * store the recipient,
-     * set active.
-    """
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-        self.page_title = self.label
-        EditView.__init__(self, context, request)
-
-    def changed(self):
-        admincomment = self.request.form.get('field.admincomment')
-
-        if admincomment:
-            # No verification is needed since this page is protected by
-            # lp.Admin
-            recipient = IPerson(self.request.principal, None)
-            kw = {}
-            kw['recipient'] = recipient
-            kw['admincomment'] = admincomment
-            kw['sign_id'] = self.context.id
-            kw['state'] = True
-
-            # use utility to active it in the database
-            sCoC_util = getUtility(ISignedCodeOfConductSet)
-            sCoC_util.modifySignature(**kw)
-
-            # now redirect to view the SignedCoC
-            self.request.response.redirect(self.request.URL[-1])
-
-        # XXX: cprov 2005-02-26:
-        # How to proceed with no admincomment ?
-
-
-# XXX: salgado, bug=414857, 2009-08-17: This view must be converted to a
-# LaunchpadFormView and define a 'cancel_url' so that the form gets a cancel
-# link.
-class SignedCodeOfConductDeactiveView(EditView):
-    """Deactive a SignedCodeOfConduct Entry.
-    When deactivating a signature:
-     * Grant admincomment,
-     * store recipient,
-     * clear active.
-    """
-
-    def __init__(self, context, request):
-        self.context = context
-        self.request = request
-        self.page_title = self.label
-        EditView.__init__(self, context, request)
-
-    def changed(self):
-        admincomment = self.request.form.get('field.admincomment')
-
-        if admincomment:
-            # No verification is needed since this page is protected by
-            # lp.Edit
-            recipient = IPerson(self.request.principal, None)
-
-            kw = {}
-            kw['recipient'] = recipient
-            kw['admincomment'] = admincomment
-            kw['sign_id'] = self.context.id
-            kw['state'] = False
-
-            # use utility to active it in the database
-            sCoC_util = getUtility(ISignedCodeOfConductSet)
-            sCoC_util.modifySignature(**kw)
-
-            # now redirect to view the SignedCoC
-            self.request.response.redirect(self.request.URL[-1])
-
-
-        # XXX: cprov 2005-02-26:
-        # How to proceed with no admincomment ?
-
+class SignedCodeOfConductActiveView(LaunchpadFormView):
+    """Active a SignedCodeOfConduct Entry."""
+    schema = ISignedCodeOfConduct
+    field_names = ['admincomment']
+    label = 'Activate code of conduct signature'
+    page_title = label
+    state = True
+
+    @property
+    def next_url(self):
+        return canonical_url(self.context)
+
+    cancel_url = next_url
+
+    def _change(self, action, data):
+        admincomment = data['admincomment']
+        sCoC_util = getUtility(ISignedCodeOfConductSet)
+        sCoC_util.modifySignature(
+            sign_id=self.context.id, recipient=self.user,
+            admincomment=admincomment, state=self.state)
+        self.request.response.redirect(self.next_url)
+
+    @action('Activate', name='change')
+    def activate(self, action, data):
+        self._change(action, data)
+
+
+class SignedCodeOfConductDeactiveView(SignedCodeOfConductActiveView):
+    """Deactivate a SignedCodeOfConduct Entry."""
+    label = 'Deactivate code of conduct signature'
+    page_title = label
+    state = False
+
+    @action('Deactivate', name='change')
+    def deactivate(self, action, data):
+        self._change(action, data)

=== modified file 'lib/lp/registry/browser/configure.zcml'
--- lib/lp/registry/browser/configure.zcml	2010-10-04 20:46:55 +0000
+++ lib/lp/registry/browser/configure.zcml	2010-10-14 01:16:08 +0000
@@ -231,26 +231,18 @@
                 template="../templates/signedcodeofconduct-index.pt"
                 name="+index"/>
         </browser:pages>
-        <browser:editform
+        <browser:page
             name="+activate"
             for="lp.registry.interfaces.codeofconduct.ISignedCodeOfConduct"
-            schema="lp.registry.interfaces.codeofconduct.ISignedCodeOfConduct"
             class="lp.registry.browser.codeofconduct.SignedCodeOfConductActiveView"
-            label="Activate code of conduct signature"
-            fields="admincomment"
             permission="launchpad.Admin"
-            template="../templates/signedcodeofconduct-activate.pt">
-                </browser:editform>
-        <browser:editform
+            template="../../app/templates/generic-edit.pt" />
+        <browser:page
             name="+deactivate"
             for="lp.registry.interfaces.codeofconduct.ISignedCodeOfConduct"
-            schema="lp.registry.interfaces.codeofconduct.ISignedCodeOfConduct"
             class="lp.registry.browser.codeofconduct.SignedCodeOfConductDeactiveView"
-            label="Deactivate code of conduct signature"
-            fields="admincomment"
             permission="launchpad.Admin"
-            template="../templates/signedcodeofconduct-deactivate.pt">
-                </browser:editform>
+            template="../../app/templates/generic-edit.pt" />
         <browser:url
             for="lp.registry.interfaces.codeofconduct.ISignedCodeOfConductSet"
             path_expression="string:console"
@@ -273,16 +265,12 @@
             permission="launchpad.Admin"
             template="../templates/codeofconduct-admin.pt"
             name="+index"/>
-        <browser:addform
+        <browser:page
             name="+new"
             for="lp.registry.interfaces.codeofconduct.ISignedCodeOfConductSet"
-            schema="lp.registry.interfaces.codeofconduct.ISignedCodeOfConduct"
-            label="Register a code of conduct signature"
-            fields="owner"
             class="lp.registry.browser.codeofconduct.SignedCodeOfConductAckView"
             permission="launchpad.Admin"
-            template="../templates/signedcodeofconduct-acknowledge.pt">
-                </browser:addform>
+            template="../../app/templates/generic-edit.pt" />
     </facet>
     <browser:url
         for="lp.registry.interfaces.irc.IIrcID"

=== added file 'lib/lp/registry/browser/tests/test_codeofconduct.py'
--- lib/lp/registry/browser/tests/test_codeofconduct.py	1970-01-01 00:00:00 +0000
+++ lib/lp/registry/browser/tests/test_codeofconduct.py	2010-10-14 01:16:08 +0000
@@ -0,0 +1,149 @@
+# Copyright 2010 Canonical Ltd.  This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Tests for Code of Conduct views."""
+
+__metaclass__ = type
+
+from zope.component import getUtility
+
+from canonical.testing.layers import DatabaseFunctionalLayer
+from lp.registry.interfaces.codeofconduct import ISignedCodeOfConductSet
+from lp.registry.model.codeofconduct import SignedCodeOfConduct
+from lp.testing import (
+    login_celebrity,
+    TestCaseWithFactory,
+    )
+from lp.testing.views import create_initialized_view
+
+
+class TestSignedCodeOfConductAckView(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(TestSignedCodeOfConductAckView, self).setUp()
+        self.signed_coc_set = getUtility(ISignedCodeOfConductSet)
+        self.owner = self.factory.makePerson()
+        self.admin = login_celebrity('admin')
+
+    def test_view_properties(self):
+        view = create_initialized_view(self.signed_coc_set, name="+new")
+        self.assertEqual(
+            'Register a code of conduct signature', view.label)
+        self.assertEqual(view.label, view.page_title)
+        self.assertEqual(['owner'], view.field_names)
+        url = 'http://launchpad.dev/codeofconduct/console'
+        self.assertEqual(url, view.next_url)
+        self.assertEqual(url, view.cancel_url)
+
+    def test_register_coc_signed_on_paper(self):
+        form = {
+            'field.owner': self.owner.name,
+            'field.actions.add': 'Register',
+            }
+        view = create_initialized_view(
+            self.signed_coc_set, name="+new", form=form,
+            principal=self.admin)
+        self.assertEqual([], view.errors)
+        results = self.signed_coc_set.searchByUser(self.owner.id)
+        self.assertEqual(1, results.count())
+        signed_coc = results[0]
+        self.assertEqual(self.admin, signed_coc.recipient)
+
+
+class SignCodeOfConductTestCase(TestCaseWithFactory):
+
+    layer = DatabaseFunctionalLayer
+
+    def setUp(self):
+        super(SignCodeOfConductTestCase, self).setUp()
+        user = self.factory.makePerson()
+        gpg_key = self.factory.makeGPGKey(user)
+        self.signed_coc = self.sign_coc(user, gpg_key)
+        self.admin = login_celebrity('admin')
+
+    def sign_coc(self, user, gpg_key):
+        """Return a SignedCodeOfConduct using dummy text."""
+        signed_coc = SignedCodeOfConduct(
+            owner=user, signingkey=gpg_key,
+            signedcode="Dummy CoC signed text.", active=True)
+        return signed_coc
+
+    def verify_common_view_properties(self, view):
+        self.assertEqual(['admincomment'], view.field_names)
+        self.assertEqual(
+            view.page_title, view.label)
+        url = 'http://launchpad.dev/codeofconduct/console/%d' % (
+            self.signed_coc.id)
+        self.assertEqual(url, view.next_url)
+        self.assertEqual(url, view.cancel_url)
+
+    def verify_admincomment_required(self, action_name, view_name):
+        # Empty comments are not permitted for any state change.
+        form = {
+            'field.admincomment': '',
+            'field.actions.change': action_name,
+            }
+        view = create_initialized_view(
+            self.signed_coc, name=view_name, form=form,
+            principal=self.admin)
+        self.assertEqual(1, len(view.errors))
+        self.assertEqual('admincomment', view.errors[0].field_name)
+
+
+class TestSignedCodeOfConductActiveView(SignCodeOfConductTestCase):
+
+    def test_view_properties(self):
+        self.signed_coc.active = False
+        view = create_initialized_view(self.signed_coc, name="+activate")
+        self.assertEqual(
+            'Activate code of conduct signature', view.label)
+        self.assertTrue(view.state)
+        self.verify_common_view_properties(view)
+
+    def test_activate(self):
+        self.signed_coc.active = False
+        form = {
+            'field.admincomment': 'The user is sorry.',
+            'field.actions.change': 'Activate',
+            }
+        view = create_initialized_view(
+            self.signed_coc, name="+activate", form=form,
+            principal=self.admin)
+        self.assertEqual([], view.errors)
+        self.assertTrue(self.signed_coc.active)
+        self.assertEqual(self.admin, self.signed_coc.recipient)
+        self.assertEqual(
+            'The user is sorry.', self.signed_coc.admincomment)
+
+    def test_admincomment_required(self):
+        self.verify_admincomment_required('Activate', '+activate')
+
+
+class TestSignedCodeOfConductDeactiveView(SignCodeOfConductTestCase):
+
+    def test_view_properties(self):
+        self.signed_coc.active = True
+        view = create_initialized_view(self.signed_coc, name="+deactivate")
+        self.assertEqual(
+            'Deactivate code of conduct signature', view.label)
+        self.assertFalse(view.state)
+        self.verify_common_view_properties(view)
+
+    def test_deactivate(self):
+        self.signed_coc.active = True
+        form = {
+            'field.admincomment': 'The user is bad.',
+            'field.actions.change': 'Deactivate',
+            }
+        view = create_initialized_view(
+            self.signed_coc, name="+deactivate", form=form,
+            principal=self.admin)
+        self.assertEqual([], view.errors)
+        self.assertFalse(self.signed_coc.active)
+        self.assertEqual(
+            'The user is bad.', self.signed_coc.admincomment)
+
+    def test_admincomment_required(self):
+        self.verify_admincomment_required('Deactivate', '+deactivate')

=== modified file 'lib/lp/registry/stories/gpg-coc/98-cocacknowledge.txt'
--- lib/lp/registry/stories/gpg-coc/98-cocacknowledge.txt	2009-08-18 14:17:32 +0000
+++ lib/lp/registry/stories/gpg-coc/98-cocacknowledge.txt	2010-10-14 01:16:08 +0000
@@ -14,9 +14,9 @@
   'Register a code of conduct signature'
 
   >>> admin_browser.getControl(name='field.owner').value = "mark@xxxxxxxxxxx"
-  >>> admin_browser.getControl(name='UPDATE_SUBMIT').click()
+  >>> admin_browser.getControl('Register').click()
   >>> admin_browser.url
-  'http://localhost:9000/codeofconduct/console/'
+  'http://localhost:9000/codeofconduct/console'
 
 Ensure the CoC was acknowledge by searching in the CoC Admin Console:
 

=== removed file 'lib/lp/registry/templates/signedcodeofconduct-acknowledge.pt'
--- lib/lp/registry/templates/signedcodeofconduct-acknowledge.pt	2009-08-17 15:36:10 +0000
+++ lib/lp/registry/templates/signedcodeofconduct-acknowledge.pt	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-<html
-  xmlns="http://www.w3.org/1999/xhtml";
-  xmlns:tal="http://xml.zope.org/namespaces/tal";
-  xmlns:metal="http://xml.zope.org/namespaces/metal";
-  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
-  metal:use-macro="view/macro:page/locationless"
-  i18n:domain="launchpad"
->
-   <body>
-   <div metal:fill-slot="main">
-     <div metal:use-macro="context/@@launchpad_addform/addform"/>
-   </div>
-   </body>
- </html>
-
-

=== removed file 'lib/lp/registry/templates/signedcodeofconduct-activate.pt'
--- lib/lp/registry/templates/signedcodeofconduct-activate.pt	2009-08-17 15:36:10 +0000
+++ lib/lp/registry/templates/signedcodeofconduct-activate.pt	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-<html
-  xmlns="http://www.w3.org/1999/xhtml";
-  xmlns:tal="http://xml.zope.org/namespaces/tal";
-  xmlns:metal="http://xml.zope.org/namespaces/metal";
-  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
-  metal:use-macro="view/macro:page/locationless"
-  i18n:domain="launchpad"
->
-   <body>
-   <div metal:fill-slot="main">
-     <div metal:use-macro="context/@@launchpad_editform/editform"/>
-   </div>
-   </body>
- </html>
-
-

=== removed file 'lib/lp/registry/templates/signedcodeofconduct-deactivate.pt'
--- lib/lp/registry/templates/signedcodeofconduct-deactivate.pt	2009-08-17 15:36:10 +0000
+++ lib/lp/registry/templates/signedcodeofconduct-deactivate.pt	1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
-<html
-  xmlns="http://www.w3.org/1999/xhtml";
-  xmlns:tal="http://xml.zope.org/namespaces/tal";
-  xmlns:metal="http://xml.zope.org/namespaces/metal";
-  xmlns:i18n="http://xml.zope.org/namespaces/i18n";
-  metal:use-macro="view/macro:page/locationless"
-  i18n:domain="launchpad"
->
-   <body>
-   <div metal:fill-slot="main">
-     <div metal:use-macro="context/@@launchpad_editform/editform"/>
-   </div>
-   </body>
- </html>
-
-