Repository: fedora-infra/bodhi

Issue:
Unable to disable various karma/bug/test requirements
I am unable to edit an update and uncheck any of the Bug/Test/Karma requirement checkboxes, or even the "Automatically close bugs".



Discussion:
Here is the POST payload when trying to disable require bugs, testcases, and auto-request stable.

```
{
    "": [],
    "autokarma": [],
    "bugs": [
        "781425",
        "1256191"
    ],
    "builds": "python-shove-0.6.4-1.fc23",
    "close_bugs": "on",
    "csrf_token": "x",
    "edited": "python-shove-0.6.4-1.fc23",
    "notes": "ChangeLog: https://bitbucket.org/lcrees/shove/raw/f612167f6c2b6eb9d9c39852a09db8477dc0aa8f/CHANGELOG",
    "require_bugs": [],
    "require_testcases": [],
    "requirements": "rpmlint",
    "severity": "unspecified",
    "stable_karma": "1",
    "suggest": "unspecified",
    "term": [],
    "type": "enhancement",
    "unstable_karma": "-2"
}

```

Issue 341 might be the same as this?

It might be that the colander schema has `missing=True` for these fields.  A patch like this might do it:

``` diff
diff --git a/bodhi/schemas.py b/bodhi/schemas.py
index 79a60a0..c919653 100644
--- a/bodhi/schemas.py
+++ b/bodhi/schemas.py
@@ -174,7 +174,7 @@ class SaveUpdateSchema(CSRFProtectedSchema, colander.MappingSchema):
     )
     autokarma = colander.SchemaNode(
         colander.Boolean(),
-        missing=True,
+        missing=False,
     )
     stable_karma = colander.SchemaNode(
         colander.Integer(),
@@ -201,11 +201,11 @@ class SaveUpdateSchema(CSRFProtectedSchema, colander.MappingSchema):
     )
     require_bugs = colander.SchemaNode(
         colander.Boolean(),
-        missing=True,
+        missing=False,
     )
     require_testcases = colander.SchemaNode(
         colander.Boolean(),
-        missing=True,
+        missing=False,
     )
```

Yeah, I think you might be right @ralphbean. It seems that when the checkboxes are enabled, we get `"on"`, else `[]`, hopefully colander will convert the empty list to `False` for us.


Resolving patch:
diff --git a/bodhi/models/models.py b/bodhi/models/models.py
--- a/bodhi/models/models.py
+++ b/bodhi/models/models.py
@@ -777,6 +777,14 @@ def edit(cls, request, data):
         if req is not None:
             up.set_request(req, request.user.name)
 
+        if not data['autokarma']:
+            data['stable_karma'] = None
+            data['unstable_karma'] = None
+            caveats.append({
+                'name': 'autokarma',
+                'description': 'Auto-karma requests disabled.',
+            })
+
         for key, value in data.items():
             setattr(up, key, value)
 


Test patch:
diff --git a/bodhi/tests/functional/base.py b/bodhi/tests/functional/base.py
--- a/bodhi/tests/functional/base.py
+++ b/bodhi/tests/functional/base.py
@@ -121,8 +121,11 @@ def get_update(self, builds=u'bodhi-2.0-1.fc17', stable_karma=3, unstable_karma=
             'bugs': u'',
             'notes': u'this is a test update',
             'type': u'bugfix',
+            'autokarma': True,
             'stable_karma': stable_karma,
             'unstable_karma': unstable_karma,
             'requirements': 'rpmlint',
+            'require_bugs': False,
+            'require_testcases': True,
             'csrf_token': self.get_csrf_token(),
         }
diff --git a/bodhi/tests/functional/test_updates.py b/bodhi/tests/functional/test_updates.py
--- a/bodhi/tests/functional/test_updates.py
+++ b/bodhi/tests/functional/test_updates.py
@@ -1725,3 +1725,42 @@ def test_submitting_multi_release_updates(self, publish, *args):
         publish.assert_called_with(topic='update.request.testing', msg=ANY)
         # Make sure two fedmsg messages were published
         self.assertEquals(len(publish.call_args_list), 2)
+
+    @mock.patch(**mock_valid_requirements)
+    @mock.patch('bodhi.notifications.publish')
+    def test_edit_update_and_disable_features(self, publish, *args):
+        build = 'bodhi-2.0.0-2.fc17'
+        args = self.get_update('bodhi-2.0.0-2.fc17')
+        r = self.app.post_json('/updates/', args)
+        publish.assert_called_with(topic='update.request.testing', msg=ANY)
+
+        up = r.json_body
+        self.assertEquals(up['require_testcases'], True)
+        self.assertEquals(up['require_bugs'], False)
+        self.assertEquals(up['stable_karma'], 3)
+        self.assertEquals(up['unstable_karma'], -3)
+
+        # Pretend it was pushed to testing
+        update = self.db.query(Update).filter_by(title=build).one()
+        update.request = None
+        update.status = UpdateStatus.testing
+        update.pushed = True
+        self.db.flush()
+
+        # Mark it as testing
+        args['edited'] = args['builds']
+
+        # Toggle a bunch of the booleans
+        args['autokarma'] = False
+        args['require_testcases'] = False
+        args['require_bugs'] = True
+
+        r = self.app.post_json('/updates/', args)
+        up = r.json_body
+        self.assertEquals(up['status'], u'testing')
+        self.assertEquals(up['request'], None)
+
+        self.assertEquals(up['require_bugs'], True)
+        self.assertEquals(up['require_testcases'], False)
+        self.assertEquals(up['stable_karma'], None)
+        self.assertEquals(up['unstable_karma'], None)