Refactor some trove admin bits, add some test coverage
diff --git a/Allura/allura/controllers/trovecategories.py b/Allura/allura/controllers/trovecategories.py
index 6edb9d4..91450fd 100644
--- a/Allura/allura/controllers/trovecategories.py
+++ b/Allura/allura/controllers/trovecategories.py
@@ -38,6 +38,15 @@
add_category_form = forms.AddTroveCategoryForm()
+class TroveAdminException(Exception):
+ def __init__(self, flash_args, redir_params='', upper=None):
+ super(TroveAdminException, self).__init__()
+
+ self.flash_args = flash_args
+ self.redir_params = redir_params
+ self.upper = upper
+
+
class TroveCategoryController(BaseController):
@expose()
def _lookup(self, trove_cat_id, *remainder):
@@ -102,29 +111,22 @@
}
return dict(tree=OrderedDict(sorted(tree.iteritems())))
- @expose()
- @require_post()
- @validate(F.add_category_form, error_handler=index)
- def create(self, **kw):
- name = kw.get('categoryname')
- upper_id = int(kw.get('uppercategory_id', 0))
- shortname = kw.get('shortname', None)
+ @classmethod
+ def _create(cls, name, upper_id, shortname):
upper = M.TroveCategory.query.get(trove_cat_id=upper_id)
if upper_id == 0:
path = name
show_as_skill = True
elif upper is None:
- flash('Invalid upper category.', "error")
- redirect('/categories')
- return
+ raise TroveAdminException(('Invalid upper category.', "error"))
else:
path = upper.fullpath + " :: " + name
show_as_skill = upper.show_as_skill
newid = max(
[el.trove_cat_id for el in M.TroveCategory.query.find()]) + 1
- shortname = h.slugify(shortname or name)[1]
+ shortname = h.slugify(shortname or name, True)[1]
if upper:
trove_type = upper.fullpath.split(' :: ')[0]
@@ -133,10 +135,13 @@
# no parent, so making a top-level. Don't limit fullpath_re, so enforcing global uniqueness
fullpath_re = re.compile(r'')
oldcat = M.TroveCategory.query.get(shortname=shortname, fullpath=fullpath_re)
+
if oldcat:
- flash('A category with shortname "%s" already exists (%s). Try a different, unique shortname'
- % (shortname, oldcat.fullpath), "error")
- redir_params = u'?categoryname={}&shortname={}'.format(name, shortname)
+ raise TroveAdminException(
+ ('A category with shortname "%s" already exists (%s). Try a different, unique shortname' % (shortname, oldcat.fullpath), "error"),
+ u'?categoryname={}&shortname={}'.format(name, shortname),
+ upper
+ )
else:
M.TroveCategory(
trove_cat_id=newid,
@@ -145,8 +150,25 @@
shortname=shortname,
fullpath=path,
show_as_skill=show_as_skill)
- flash('Category "%s" successfully created.' % name)
- redir_params = ''
+ return upper, ('Category "%s" successfully created.' % name,), ''
+
+ @expose()
+ @require_post()
+ @validate(F.add_category_form, error_handler=index)
+ def create(self, **kw):
+ name = kw.get('categoryname')
+ upper_id = int(kw.get('uppercategory_id', 0))
+ shortname = kw.get('shortname', None)
+
+ try:
+ upper, flash_args, redir_params = self._create(name, upper_id, shortname)
+ except TroveAdminException as ex:
+ upper = ex.upper
+ flash_args = ex.flash_args
+ redir_params = ex.redir_params
+
+ flash(*flash_args)
+
if upper:
redirect(u'/categories/{}/{}'.format(upper.trove_cat_id, redir_params))
else:
diff --git a/Allura/allura/tests/functional/test_trovecategory.py b/Allura/allura/tests/functional/test_trovecategory.py
index 346a9f1..2dc438f 100644
--- a/Allura/allura/tests/functional/test_trovecategory.py
+++ b/Allura/allura/tests/functional/test_trovecategory.py
@@ -18,7 +18,7 @@
import mock
from tg import config
-from nose.tools import assert_equals, assert_true, assert_in
+from nose.tools import assert_equals, assert_true, assert_in, assert_equal
from ming.orm import session
from allura import model as M
@@ -149,4 +149,53 @@
form = r.forms[0]
r = form.submit()
assert_in("Category removed", self.webflash(r))
- assert_equals(4, M.TroveCategory.query.find().count())
\ No newline at end of file
+ assert_equals(4, M.TroveCategory.query.find().count())
+
+ def test_create_parent(self):
+ self.create_some_cats()
+ session(M.TroveCategory).flush()
+ r = self.app.get('/categories/')
+
+ form = r.forms[1]
+ form['categoryname'].value = "New Category"
+ form.submit()
+
+ possible = M.TroveCategory.query.find(dict(fullname='New Category')).all()
+ assert_equal(len(possible), 1)
+ assert_equal(possible[0].fullname, 'New Category')
+ assert_equal(possible[0].shortname, 'new-category')
+
+ def test_create_child(self):
+ self.create_some_cats()
+ session(M.TroveCategory).flush()
+ r = self.app.get('/categories/2')
+
+ form = r.forms[2]
+ form['categoryname'].value = "New Child"
+ form.submit()
+
+ possible =M.TroveCategory.query.find(dict(fullname='New Child')).all()
+ assert_equal(len(possible), 1)
+ assert_equal(possible[0].fullname, 'New Child')
+ assert_equal(possible[0].shortname, 'new-child')
+ assert_equal(possible[0].trove_parent_id, 2)
+
+ # test slugify with periods. the relevant form becomes the third, after a child has been created above.
+ r = self.app.get('/categories/2')
+ form = r.forms[3]
+ form['categoryname'].value = "New Child.io"
+ form.submit()
+ possible = M.TroveCategory.query.find(dict(fullname='New Child.io')).all()
+ assert_equal(possible[0].shortname, 'new-child.io')
+
+ def test_create_child_bad_upper(self):
+ self.create_some_cats()
+ session(M.TroveCategory).flush()
+ r = self.app.get('/categories/2')
+
+ form = r.forms[2]
+ form['categoryname'].value = "New Child"
+ form['uppercategory_id'].value = "541561615"
+ r = form.submit().follow()
+
+ assert 'Invalid upper category' in r.text