Skip to content
Snippets Groups Projects
Commit ad368f6d authored by Mark Skipper's avatar Mark Skipper
Browse files

Fix table not showing the rght question types for Items

Interlally it was using add_term which did just what its name said:
it add a term for the item. There was no check that you could only
have one if the thing was a category. So I added a rudimentary support
for that and creted some more test debt. (list copied in below in case
it gets lost)

Then added the apply_term method on Item (see note about how it sucks
for this to be there) which checks the multiplicity of the taxonomy
of the incoming term and acts apporporately. Finally all taxonomies
currently say they are have optional multiplicity (i.e. categories)
whichi s fine for the question type story.

- [ ] Add tests for data_layer.models.Item.apply_Term
- [ ] refactor tests in rest api to use the api
- [ ] Are the updates to the model tags being saved and output okay? Why does that fail?
- [ ] hid/views/add_Categories should only update category if it has actually changed
- [ ] Test add_Categories (in the hid view) with multiple id/term pairs?
- [ ] Add error reporting to the bit of View/Edit screen that adds categories to items.
- [ ] Add tests for adding categories to more than one item at once via browser
- [ ] We probably need a default value in the category selector to show  that there's initailly no value selected
- [ ] Add tests for what happens when add_categories gets called with nonsense items and category names, should fail gracefully
- [ ] Add transport wrappers for listing the terms in a taxonomy, and update View/Editr screen to use these in place of modls directly
- [ ] Add transport wrappers for creating taxnonmies and terms
- [ ] add_Term in api views should retrn json of the serialized version of the new item -- currently empty dict
- [ ] Term.objects.by_taxonomy() should propbably do select related to get the term back as well, seewhere used in api.add_term
parent 2b126776
No related branches found
No related tags found
No related merge requests found
......@@ -14,6 +14,25 @@ class Message(DataLayerModel):
timestamp = models.DateTimeField(null=True)
terms = models.ManyToManyField(Term)
def apply_term(self, term):
# TODO: test this
""" Add or replace value of term.taxonomy for current Item
If the Item has no term in the taxonomy
OR if the taxonomy.is_multiple just add it.
IF the taxonmy is optional (categories)
If the Item has a term in that taxonomy already,
replace it
"""
# It bugs me that so much of the logic applying to taxonomies is here.
# This should really be built out with an explicity through model
# in taxonomies, with a generic foreign ken to the content type
# being classified, then this logic could live there.
if term.taxonomy.is_optional:
for old_term in self.terms.filter(taxonomy=term.taxonomy):
self.terms.remove(old_term)
self.terms.add(term)
def __unicode__(self):
return "{}: '{}' @{}".format(
self.id,
......
......@@ -19,35 +19,40 @@ def category():
return create_category(name="Ebola Questions").data
@pytest.fixture
def term(category):
def term_for(taxonomy, name):
""" Create, and return a Term in the given taxonomy """
return add_term(
taxonomy=category["slug"],
name="Vaccine",
taxonomy=taxonomy['slug'],
name=name,
).data
@pytest.fixture
def term(category):
return term_for(category, 'Vaccine')
@pytest.fixture
def second_term(category):
return term_for(category, 'Timescales')
@pytest.fixture
def item():
return create_item(body="Text").data
def categorize_item(item_id, taxonomy_slug, term_name):
url = reverse('item-add-term', kwargs={"pk": item_id})
term = {'taxonomy': taxonomy_slug, 'name': term_name}
def categorize_item(item, term):
url = reverse('item-add-term', kwargs={"pk": item['id']})
request = APIRequestFactory().post(url, term)
view = ItemViewSet.as_view(actions={'post': 'add_term'})
return view(request, item_pk=item_id)
return view(request, item_pk=item['id'])
@pytest.mark.django_db
def test_item_can_haz_category(category, term, item):
def test_item_can_haz_category(term, item):
# Associate category with the item
categorize_item(
item_id=item['id'],
taxonomy_slug=category['slug'],
term_name=term['name'],
)
categorize_item(item, term)
# Fetch the item
# TODO: use the API for this
......@@ -62,10 +67,29 @@ def test_item_can_haz_category(category, term, item):
@pytest.mark.django_db
def test_categorize_item_fails_gracefully_if_term_not_found(item):
response = categorize_item(
item_id=item['id'],
taxonomy_slug='unknown-slug',
term_name='unknown-term',
item,
{'taxonomy': 'unknown-slug', 'name': 'unknown-term'},
)
assert response.status_code == status.HTTP_400_BAD_REQUEST
assert response.data['detail'] == "Term matching query does not exist."
@pytest.mark.django_db
def test_only_one_category_per_item_per_taxonomy(item, term, second_term):
"""
At the time of writing, all taxonomies are categories
so there's no need yet to test that the taxonomy is a
catagory one. Ultimately this test sould be called something like
test_cardinality_constraints_on_taxonomies, and maybe move them
all to their own file. They should set the cardinality constraint
on the Taxonmy object to optional for these tests.
"""
categorize_item(item, term)
categorize_item(item, second_term)
# TODO: use the API for this
[item_orm] = Item.objects.all()
terms = item_orm.terms.all()
assert len(terms) == 1
assert terms[0].name == second_term['name']
......@@ -35,7 +35,6 @@ class ItemViewSet(viewsets.ModelViewSet, BulkDestroyModelMixin):
def add_term(self, request, item_pk):
item = Item.objects.get(pk=item_pk)
term_data = request.data
try:
term = Term.objects.by_taxonomy(
taxonomy=term_data['taxonomy'],
......@@ -45,7 +44,7 @@ class ItemViewSet(viewsets.ModelViewSet, BulkDestroyModelMixin):
data = {'detail': e.message}
return Response(data, status=status.HTTP_400_BAD_REQUEST)
item.terms.add(term)
item.apply_term(term)
data = {} # TODO should be the item containing the new term
return Response(data, status=status.HTTP_200_OK)
......
......@@ -24,6 +24,11 @@ class Taxonomy(models.Model):
self.slug = slugify(self.name)
super(Taxonomy, self).save(*args, **kwargs)
@property
def is_optional(self):
# return self.multiplicity == self.OPTIONAL
return True
def __unicode__(self):
return self.name
......
......@@ -19,17 +19,12 @@ def item_data():
@pytest.mark.django_db
def test_terms_can_be_added_to_item(item_data):
item_id = item_data['id']
# TODO: Replace with Term list() ?
item = Item.objects.get(pk=item_id)
assert item.terms.count() == 0
ebola_questions = TaxonomyFactory(name="Ebola Questions")
term = TermFactory(name="Cause", taxonomy=ebola_questions)
items.add_term(item_id, ebola_questions.slug, term.name)
term = TermFactory(name="Question", taxonomy=ebola_questions)
items.add_term(item_id, ebola_questions.slug, term.name)
for term in (TermFactory() for i in range(2)):
items.add_term(item_id, term.taxonomy.slug, term.name)
assert item.terms.count() == 2
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment