From bb2d070679e5f984d8da2db2149138810802c7b2 Mon Sep 17 00:00:00 2001 From: Ole Laursen Date: Tue, 3 Dec 2013 18:33:07 +0000 Subject: [PATCH] Redo tests for IPR to cover all views, fix some bugs and add some finishing touches - Legacy-Id: 6779 --- ietf/doc/tests_draft.py | 16 +- ietf/ipr/admin.py | 16 +- ietf/ipr/models.py | 17 +- ietf/ipr/new.py | 40 +- ietf/ipr/search.py | 4 +- ietf/ipr/tests.py | 372 +++++++++++++----- ietf/ipr/testurl.list | 73 ---- ietf/ipr/urls.py | 4 - ietf/ipr/views.py | 2 +- ietf/secr/ipradmin/forms.py | 4 +- ietf/secr/ipradmin/views.py | 6 +- ietf/templates/ipr/details.html | 88 +++-- .../templates/ipr/search_doctitle_result.html | 6 +- ietf/templates/ipr/search_result.html | 25 +- ietf/utils/test_data.py | 5 + ietf/wgcharter/views.py | 3 +- ietf/wginfo/edit.py | 1 - ietf/wginfo/milestones.py | 1 - 18 files changed, 396 insertions(+), 287 deletions(-) delete mode 100644 ietf/ipr/testurl.list diff --git a/ietf/doc/tests_draft.py b/ietf/doc/tests_draft.py index dc746f9ac..f11383ec9 100644 --- a/ietf/doc/tests_draft.py +++ b/ietf/doc/tests_draft.py @@ -1,7 +1,5 @@ -import unittest import StringIO -import os, shutil -from datetime import date, timedelta, time +import os, shutil, datetime from django.core.urlresolvers import reverse as urlreverse from django.conf import settings @@ -10,7 +8,7 @@ from pyquery import PyQuery import debug from ietf.doc.models import * -from ietf.doc .utils import * +from ietf.doc.utils import * from ietf.name.models import * from ietf.group.models import * from ietf.person.models import * @@ -452,11 +450,11 @@ class ExpireIDsTests(TestCase): second_cut_off = Meeting.get_second_cut_off() ietf_monday = Meeting.get_ietf_monday() - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), time(0, 0, 0)))) - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, time(0, 0, 0)))) - self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), time(0, 0, 0)))) - self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), time(0, 0, 0)))) - self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off - datetime.timedelta(days=7), datetime.time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(second_cut_off, datetime.time(0, 0, 0)))) + self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(second_cut_off + datetime.timedelta(days=7), datetime.time(0, 0, 0)))) + self.assertTrue(in_draft_expire_freeze(datetime.datetime.combine(ietf_monday - datetime.timedelta(days=1), datetime.time(0, 0, 0)))) + self.assertTrue(not in_draft_expire_freeze(datetime.datetime.combine(ietf_monday, datetime.time(0, 0, 0)))) def test_warn_expirable_drafts(self): from ietf.doc.expire import get_soon_to_expire_drafts, send_expire_warning_for_draft diff --git a/ietf/ipr/admin.py b/ietf/ipr/admin.py index 0a3b6da3f..41fa7ca16 100644 --- a/ietf/ipr/admin.py +++ b/ietf/ipr/admin.py @@ -12,16 +12,8 @@ class IprDetailAdmin(admin.ModelAdmin): search_fields = ['title', 'legal_name'] def docs(self, ipr): - res = [] - for iprdocalias in IprDocAlias.objects.filter(ipr=ipr).order_by("id").select_related("doc_alias"): - if iprdocalias.doc_alias.name.startswith("rfc"): - n = iprdocalias.doc_alias.name.upper() - elif iprdocalias.rev: - n = iprdocalias.doc_alias.name + iprdocalias.rev - else: - n = iprdocalias.doc_alias.name - res.append(n) - return u", ".join(res) + return u", ".join(a.formatted_name() for a in IprDocAlias.objects.filter(ipr=ipr).order_by("id").select_related("doc_alias")) + admin.site.register(IprDetail, IprDetailAdmin) class IprNotificationAdmin(admin.ModelAdmin): @@ -32,4 +24,6 @@ class IprUpdateAdmin(admin.ModelAdmin): pass admin.site.register(IprUpdate, IprUpdateAdmin) -admin.site.register(IprDocAlias) +class IprDocAliasAdmin(admin.ModelAdmin): + raw_id_fields = ["ipr", "doc_alias"] +admin.site.register(IprDocAlias, IprDocAliasAdmin) diff --git a/ietf/ipr/models.py b/ietf/ipr/models.py index ca3276d7d..c8655b94d 100644 --- a/ietf/ipr/models.py +++ b/ietf/ipr/models.py @@ -90,9 +90,11 @@ class IprDetail(models.Model): def __unicode__(self): return self.title + @models.permalink def get_absolute_url(self): return ('ietf.ipr.views.show', [str(self.ipr_id)]) + def get_submitter(self): try: return self.contact.get(contact_type=3) @@ -101,6 +103,9 @@ class IprDetail(models.Model): except IprContact.MultipleObjectsReturned: return self.contact.filter(contact_type=3)[0] + def docs(self): + return self.iprdocalias_set.select_related("doc_alias", "doc_alias__document").order_by("id") + class IprContact(models.Model): TYPE_CHOICES = ( (1, 'Patent Holder Contact'), @@ -138,9 +143,19 @@ class IprUpdate(models.Model): class IprDocAlias(models.Model): - ipr = models.ForeignKey(IprDetail, related_name='documents') + ipr = models.ForeignKey(IprDetail) doc_alias = models.ForeignKey(DocAlias) rev = models.CharField(max_length=2, blank=True) + + def formatted_name(self): + name = self.doc_alias.name + if name.startswith("rfc"): + return name.upper() + elif self.rev: + return "%s-%s" % (name, self.rev) + else: + return name + def __unicode__(self): if self.rev: return u"%s which applies to %s-%s" % (self.ipr, self.doc_alias.name, self.rev) diff --git a/ietf/ipr/new.py b/ietf/ipr/new.py index a1524898b..54e7c1c76 100644 --- a/ietf/ipr/new.py +++ b/ietf/ipr/new.py @@ -1,6 +1,6 @@ # Copyright The IETF Trust 2007, All Rights Reserved -import re +import re, datetime from django.shortcuts import render_to_response as render, get_object_or_404 from django.template import RequestContext @@ -10,6 +10,7 @@ from django import forms from ietf.utils import log from ietf.utils.mail import send_mail +from ietf.doc.models import Document, DocAlias from ietf.ipr.models import IprDetail, IprDocAlias, IprContact, LICENSE_CHOICES, IprUpdate from ietf.ipr.view_sections import section_table @@ -61,8 +62,6 @@ def new(request, type, update=None, submitter=None): one form containing fields from 4 tables -- don't build something like this again... """ - debug = "" - section_list = section_table[type].copy() section_list.update({"title":False, "new_intro":False, "form_intro":True, "form_submit":True, "form_legend": True, }) @@ -131,7 +130,7 @@ def new(request, type, update=None, submitter=None): for rfc in rfclist: try: DocAlias.objects.get(name="rfc%s" % int(rfc)) - except: + except (DocAlias.DoesNotExist, DocAlias.MultipleObjectsReturned, ValueError): raise forms.ValidationError("Unknown RFC number: %s - please correct this." % rfc) rfclist = " ".join(rfclist) return rfclist @@ -145,19 +144,19 @@ def new(request, type, update=None, submitter=None): if draft.endswith(".txt"): draft = draft[:-4] if re.search("-[0-9][0-9]$", draft): - filename = draft[:-3] + name = draft[:-3] rev = draft[-2:] else: - filename = draft + name = draft rev = None try: - doc = Document.objects.get(docalias__name=filename) - except Exception as e: + doc = Document.objects.get(docalias__name=name) + except (Document.DoesNotExist, Document.MultipleObjectsReturned) as e: log("Exception: %s" % e) - raise forms.ValidationError("Unknown Internet-Draft: %s - please correct this." % filename) + raise forms.ValidationError("Unknown Internet-Draft: %s - please correct this." % name) if rev and doc.rev != rev: - raise forms.ValidationError("Unexpected revision '%s' for draft %s - the current revision is %s. Please check this." % (rev, filename, id.revision)) - drafts.append("%s-%s" % (filename, doc.rev)) + raise forms.ValidationError("Unexpected revision '%s' for draft %s - the current revision is %s. Please check this." % (rev, name, doc.rev)) + drafts.append("%s-%s" % (name, doc.rev)) return " ".join(drafts) return "" def clean_licensing_option(self): @@ -178,11 +177,8 @@ def new(request, type, update=None, submitter=None): # POST of the "get updater" form, so we don't want to validate # this one. When we're posting *this* form, submitter is None, # even when updating. - if (request.method == 'POST' or '_testpost' in request.REQUEST) and not submitter: - if request.method == 'POST': - data = request.POST.copy() - else: - data = request.GET.copy() + if request.method == 'POST' and not submitter: + data = request.POST.copy() data["submitted_date"] = datetime.datetime.now().strftime("%Y-%m-%d") data["third_party"] = section_list["third_party"] data["generic"] = section_list["generic"] @@ -205,13 +201,13 @@ def new(request, type, update=None, submitter=None): # Save IprDetail instance = form.save(commit=False) - legal_name_genitive = data['legal_name'] + "'" if data['legal_name'].endswith('s') else data['legal_name'] + "'s" + legal_name_genitive = data['legal_name'] + "'" if data['legal_name'].endswith('s') else data['legal_name'] + "'s" if type == "generic": instance.title = legal_name_genitive + " General License Statement" - if type == "specific": + elif type == "specific": data["ipr_summary"] = get_ipr_summary(form.cleaned_data) instance.title = legal_name_genitive + """ Statement about IPR related to %(ipr_summary)s""" % data - if type == "third-party": + elif type == "third-party": data["ipr_summary"] = get_ipr_summary(form.cleaned_data) ietf_name_genitive = data['ietf_name'] + "'" if data['ietf_name'].endswith('s') else data['ietf_name'] + "'s" instance.title = ietf_name_genitive + """ Statement about IPR related to %(ipr_summary)s belonging to %(legal_name)s""" % data @@ -294,7 +290,7 @@ def new(request, type, update=None, submitter=None): form.unbound_form = True # log(dir(form.ietf_contact_is_submitter)) - return render("ipr/details_edit.html", {"ipr": form, "section_list":section_list, "debug": debug}, context_instance=RequestContext(request)) + return render("ipr/details_edit.html", {"ipr": form, "section_list":section_list}, context_instance=RequestContext(request)) def update(request, ipr_id=None): """Update a specific IPR disclosure""" @@ -320,9 +316,7 @@ def update(request, ipr_id=None): if request.method == 'POST': form = UpdateForm(request.POST) - elif '_testpost' in request.REQUEST: - form = UpdateForm(request.GET) - else: + else: form = UpdateForm() if not(form.is_valid()): diff --git a/ietf/ipr/search.py b/ietf/ipr/search.py index cf071401d..bd79e02f2 100644 --- a/ietf/ipr/search.py +++ b/ietf/ipr/search.py @@ -85,12 +85,12 @@ def search(request): # IPR list with documents elif search_type == "patent_search": iprs = IprDetail.objects.filter(legal_name__icontains=q, status__in=[1,3]).order_by("-submitted_date", "-ipr_id") - count = iprs.count() + count = len(iprs) iprs = [ ipr for ipr in iprs if not ipr.updated_by.all() ] return render("ipr/search_holder_result.html", {"q": q, "iprs": iprs, "count": count }, context_instance=RequestContext(request) ) - # Search by content of email or pagent_info field + # Search by patents field or content of emails for patent numbers # IPR list with documents elif search_type == "patent_info_search": if len(q) < 3: diff --git a/ietf/ipr/tests.py b/ietf/ipr/tests.py index baeb70492..261f33214 100644 --- a/ietf/ipr/tests.py +++ b/ietf/ipr/tests.py @@ -1,101 +1,281 @@ -# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. Contact: Pasi Eronen -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# -# * Neither the name of the Nokia Corporation and/or its -# subsidiary(-ies) nor the names of its contributors may be used -# to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import os, datetime, shutil + +import urllib + +from pyquery import PyQuery -import os -import unittest -from django.test.client import Client from django.conf import settings -from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest, canonicalize_feed, canonicalize_sitemap -from ietf.utils.mail import outbox, empty_outbox +from django.core.urlresolvers import reverse as urlreverse -class IprUrlTestCase(SimpleUrlTestCase): - def testUrls(self): - self.doTestUrls(__file__) - def doCanonicalize(self, url, content): - if url.startswith("/feed/"): - return canonicalize_feed(content) - elif url == "/sitemap-ipr.xml": - return canonicalize_sitemap(content) - else: - return content +from ietf.utils.test_utils import TestCase, login_testing_unauthorized +from ietf.utils.test_data import make_test_data +from ietf.utils.mail import outbox +from ietf.ipr.models import * -# this test should be ported to run on a test database instead of the -# real database, and possibly expanded -# class NewIprTestCase(unittest.TestCase,RealDatabaseTest): -# SPECIFIC_DISCLOSURE = { -# 'legal_name':'Testing Only Please Ignore', -# 'hold_name':'Test Holder', -# 'hold_telephone':'555-555-0100', -# 'hold_email':'test.holder@example.com', -# 'ietf_name':'Test Participant', -# 'ietf_telephone':'555-555-0101', -# 'ietf_email':'test.participant@example.com', -# 'rfclist':'1149', -# 'draftlist':'draft-burdis-http-sasl-00', -# 'patents':'none', -# 'date_applied':'never', -# 'country':'nowhere', -# 'licensing_option':'5', -# 'subm_name':'Test Submitter', -# 'subm_telephone':'555-555-0102', -# 'subm_email':'test.submitter@example.com' -# } -# -# def setUp(self): -# self.setUpRealDatabase() -# def tearDown(self): -# self.tearDownRealDatabase() -# -# def testNewSpecific(self): -# print " Testing IPR disclosure submission" -# empty_outbox() -# c = Client() -# response = c.post('/ipr/new-specific/', self.SPECIFIC_DISCLOSURE) -# self.assertEquals(response.status_code, 200) -# self.assert_("Your IPR disclosure has been submitted" in response.content) -# self.assertEquals(len(outbox), 1) -# print "OK (1 email found in test outbox)" + +class IprTests(TestCase): + def setUp(self): + # for patent number search + self.ipr_dir = os.path.abspath("tmp-ipr-dir") + if not os.path.exists(self.ipr_dir): + os.mkdir(self.ipr_dir) + settings.IPR_DOCUMENT_PATH = self.ipr_dir + + def tearDown(self): + shutil.rmtree(self.ipr_dir) + + def test_overview(self): + make_test_data() + ipr = IprDetail.objects.get(title="Statement regarding rights") + + r = self.client.get(urlreverse("ipr_showlist")) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + def test_iprs_for_drafts(self): + draft = make_test_data() + ipr = IprDetail.objects.get(title="Statement regarding rights") + + r = self.client.get(urlreverse("ietf.ipr.views.iprs_for_drafts_txt")) + self.assertEqual(r.status_code, 200) + self.assertTrue(draft.name in r.content) + self.assertTrue(str(ipr.pk) in r.content) + + def test_about(self): + r = self.client.get(urlreverse("ietf.ipr.views.about")) + self.assertEqual(r.status_code, 200) + self.assertTrue("File a disclosure" in r.content) + + def test_search(self): + draft = make_test_data() + ipr = IprDetail.objects.get(title="Statement regarding rights") + + url = urlreverse("ipr_search") + + r = self.client.get(url) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(q("form input[name=document_search]")) + + # find by id + r = self.client.get(url + "?option=document_search&id=%s" % draft.name) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # find draft + r = self.client.get(url + "?option=document_search&document_search=%s" % draft.name) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # search + select document + r = self.client.get(url + "?option=document_search&document_search=draft") + self.assertEqual(r.status_code, 200) + self.assertTrue(draft.name in r.content) + self.assertTrue(ipr.title not in r.content) + + DocAlias.objects.create(name="rfc321", document=draft) + + # find RFC + r = self.client.get(url + "?option=rfc_search&rfc_search=321") + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # find by patent owner + r = self.client.get(url + "?option=patent_search&patent_search=%s" % ipr.legal_name) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) - -class IprFileTestCase(unittest.TestCase): - def testFileExistence(self): - print " Testing if IPR disclosure files exist locally" - fpath = os.path.join(settings.IPR_DOCUMENT_PATH, "juniper-ipr-RFC-4875.txt") - if not os.path.exists(fpath): - print "\nERROR: IPR disclosure files not found in "+settings.IPR_DOCUMENT_PATH - print "They are needed for testing IPR searching." - print "Download them to a local directory with:" - print "wget -nd -nc -np -r ftp://ftp.ietf.org/ietf/IPR/" - print "And set IPR_DOCUMENT_PATH in settings_local.py\n" - else: - print "OK (they seem to exist)" - + # find by patent info + r = self.client.get(url + "?option=patent_info_search&patent_info_search=%s" % ipr.patents) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # find by patent info in file + filename = "ipr1.txt" + with open(os.path.join(self.ipr_dir, filename), "w") as f: + f.write("Hello world\nPTO9876") + ipr.legacy_url_0 = "/hello/world/%s" % filename + ipr.save() + + r = self.client.get(url + "?option=patent_info_search&patent_info_search=PTO9876") + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # must search for at least 3 characters with digit + r = self.client.get(url + "?option=patent_info_search&patent_info_search=a") + self.assertTrue("ipr search result error" in r.content.lower()) + + r = self.client.get(url + "?option=patent_info_search&patent_info_search=aaa") + self.assertTrue("ipr search result error" in r.content.lower()) + + # find by group acronym + r = self.client.get(url + "?option=wg_search&wg_search=%s" % draft.group.acronym) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # find by doc title + r = self.client.get(url + "?option=title_search&title_search=%s" % urllib.quote(draft.title)) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + # find by ipr title + r = self.client.get(url + "?option=ipr_title_search&ipr_title_search=%s" % urllib.quote(ipr.title)) + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + def test_feed(self): + make_test_data() + ipr = IprDetail.objects.get(title="Statement regarding rights") + + r = self.client.get("/feed/ipr/") + self.assertEqual(r.status_code, 200) + self.assertTrue(ipr.title in r.content) + + def test_sitemap(self): + make_test_data() + ipr = IprDetail.objects.get(title="Statement regarding rights") + + r = self.client.get("/sitemap-ipr.xml") + self.assertEqual(r.status_code, 200) + self.assertTrue("/ipr/%s/" % ipr.pk in r.content) + + def test_new_generic(self): + draft = make_test_data() + + url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "generic" }) + + # faulty post + r = self.client.post(url, { + "legal_name": "Test Legal", + }) + self.assertEqual(r.status_code, 200) + q = PyQuery(r.content) + self.assertTrue(len(q("ul.errorlist")) > 0) + + # succesfull post + r = self.client.post(url, { + "legal_name": "Test Legal", + "hold_name": "Test Holder", + "hold_telephone": "555-555-0100", + "hold_email": "test.holder@example.com", + "ietf_name": "Test Participant", + "ietf_telephone": "555-555-0101", + "ietf_email": "test.participant@example.com", + "patents": "none", + "date_applied": "never", + "country": "nowhere", + "licensing_option": "5", + "subm_name": "Test Submitter", + "subm_telephone": "555-555-0102", + "subm_email": "test.submitter@example.com" + }) + self.assertEqual(r.status_code, 200) + self.assertTrue("Your IPR disclosure has been submitted" in r.content) + + iprs = IprDetail.objects.filter(title__icontains="General License Statement") + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + def test_new_specific(self): + draft = make_test_data() + + url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "specific" }) + + # succesfull post + r = self.client.post(url, { + "legal_name": "Test Legal", + "hold_name": "Test Holder", + "hold_telephone": "555-555-0100", + "hold_email": "test.holder@example.com", + "ietf_name": "Test Participant", + "ietf_telephone": "555-555-0101", + "ietf_email": "test.participant@example.com", + "rfclist": DocAlias.objects.filter(name__startswith="rfc")[0].name[3:], + "draftlist": "%s-%s" % (draft.name, draft.rev), + "patents": "none", + "date_applied": "never", + "country": "nowhere", + "licensing_option": "5", + "subm_name": "Test Submitter", + "subm_telephone": "555-555-0102", + "subm_email": "test.submitter@example.com" + }) + self.assertEqual(r.status_code, 200) + self.assertTrue("Your IPR disclosure has been submitted" in r.content) + + iprs = IprDetail.objects.filter(title__icontains=draft.name) + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + def test_new_thirdparty(self): + draft = make_test_data() + + url = urlreverse("ietf.ipr.new.new", kwargs={ "type": "third-party" }) + + # succesfull post + r = self.client.post(url, { + "legal_name": "Test Legal", + "hold_name": "Test Holder", + "hold_telephone": "555-555-0100", + "hold_email": "test.holder@example.com", + "ietf_name": "Test Participant", + "ietf_telephone": "555-555-0101", + "ietf_email": "test.participant@example.com", + "rfclist": "", + "draftlist": "%s-%s" % (draft.name, draft.rev), + "patents": "none", + "date_applied": "never", + "country": "nowhere", + "licensing_option": "5", + "subm_name": "Test Submitter", + "subm_telephone": "555-555-0102", + "subm_email": "test.submitter@example.com" + }) + self.assertEqual(r.status_code, 200) + self.assertTrue("Your IPR disclosure has been submitted" in r.content) + + iprs = IprDetail.objects.filter(title__icontains="belonging to Test Legal") + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + def test_update(self): + draft = make_test_data() + original_ipr = IprDetail.objects.get(title="Statement regarding rights") + + url = urlreverse("ietf.ipr.new.update", kwargs={ "ipr_id": original_ipr.pk }) + + # succesfull post + r = self.client.post(url, { + "legal_name": "Test Legal", + "hold_name": "Test Holder", + "hold_telephone": "555-555-0100", + "hold_email": "test.holder@example.com", + "ietf_name": "Test Participant", + "ietf_telephone": "555-555-0101", + "ietf_email": "test.participant@example.com", + "rfclist": "", + "draftlist": "%s-%s" % (draft.name, draft.rev), + "patents": "none", + "date_applied": "never", + "country": "nowhere", + "licensing_option": "5", + "subm_name": "Test Submitter", + "subm_telephone": "555-555-0102", + "subm_email": "test.submitter@example.com" + }) + self.assertEqual(r.status_code, 200) + self.assertTrue("Your IPR disclosure has been submitted" in r.content) + + iprs = IprDetail.objects.filter(title__icontains=draft.name) + self.assertEqual(len(iprs), 1) + ipr = iprs[0] + self.assertEqual(ipr.legal_name, "Test Legal") + self.assertEqual(ipr.status, 0) + + self.assertTrue(ipr.updates.filter(updated=original_ipr)) diff --git a/ietf/ipr/testurl.list b/ietf/ipr/testurl.list deleted file mode 100644 index ca755d894..000000000 --- a/ietf/ipr/testurl.list +++ /dev/null @@ -1,73 +0,0 @@ -200 /ipr/ -200 /ipr/657/ # Generic disclosure -200 /ipr/564/ # Generic submitted by email -200 /ipr/834/ # Specific disclosure -200 /ipr/1121/ # Specific disclosure submitted by email (PDF) -200 /ipr/1173/ # Specific disclosure submitted by email (TXT) -200 /ipr/795/ # Third-party disclosure -200 /ipr/865/ # Third party disclosure submitted by email (TXT) -200 /ipr/1140/ # Non-ASCII patent holder name -200 /ipr/1069/ # Non-ASCII title -200 /ipr/1129/ # Non-ASCII other fields -200 /ipr/751/ # Updates others, and is updated by others -200 /ipr/765/ # Removed -404 /ipr/1066/ # Test record - -200 /ipr/new-generic/ -200 /ipr/new-specific/ -200 /ipr/new-third-party/ -200 /ipr/new-generic/?_testpost=1 -200 /ipr/new-specific/?_testpost=1 -200 /ipr/new-third-party/?_testpost=1 - -301 /ipr/update/ -200 /ipr/update/657/ # Generic -200 /ipr/update/820/ # Third-party -200 /ipr/update/844/ # Specific -404 /ipr/update/1066/ # Removed test record - -200 /ipr/update/657/?_testpost=1 # Generic -200 /ipr/update/820/?_testpost=1 # Third-party -200 /ipr/update/844/?_testpost=1 # Specific -200 /ipr/update/657/?_testpost=1&email=test@example.com&name=Test&telephone=123&update_auth=on -200 /ipr/update/820/?_testpost=1&email=test@example.com&name=Test&telephone=123&update_auth=on -200 /ipr/update/844/?_testpost=1&email=test@example.com&name=Test&telephone=123&update_auth=on - -200 /ipr/search/ -302 /ipr/search/?option=document_search # incomplete argument set gives redirect - -200 /ipr/search/?document_search=mod&option=document_search # Returns document list -200 /ipr/search/?id_document_tag=2220&option=document_search # Simple case -200 /ipr/search/?id_document_tag=2221&option=document_search # Empty result -200 /ipr/search/?id_document_tag=2221x&option=document_search # Non-numeric -200 /ipr/search/?option=document_search&document_search=draft-housley-tls-authz-extns-05 # More complex result - -200 /ipr/search/?rfc_search=1034&option=rfc_search # Loong result -200 /ipr/search/?rfc_search=4555&option=rfc_search # Simple result -200 /ipr/search/?rfc_search=4444&option=rfc_search # Empty result -200 /ipr/search/?rfc_search=4xyz&option=rfc_search # non-numeric - -200 /ipr/search/?patent_search=nortel&option=patent_search -200 /ipr/search/?patent_search=nortelxz&option=patent_search # Empty result - -200 /ipr/search/?wg_search=dnsext&option=wg_search -200 /ipr/search/?wg_search=aaa&option=wg_search -200 /ipr/search/?wg_search=acct&option=wg_search # Empty result - -200 /ipr/search/?option=title_search&title_search=AAA -200 /ipr/search/?option=title_search&title_search=AAAxz # Empty result - -200 /ipr/search/?patent_info_search=123&option=patent_info_search -200 /ipr/search/?patent_info_search=31415&option=patent_info_search # Empty result -200 /ipr/search/?patent_info_search=12&option=patent_info_search # Error: at least 3 characters -200 /ipr/search/?patent_info_search=abc&option=patent_info_search # Error: at least 1 digit - -200 /ipr/search/?option=ipr_title_search&ipr_title_search=nortel -200 /ipr/search/?option=ipr_title_search&ipr_title_search=nortelxz # Empty result -404 /ipr/search/?id_document_tag=12345 # no search type: 404 - -200 /ipr/about/ -200 /ipr/by-draft/ - -200 /feed/ipr/ -200 /sitemap-ipr.xml diff --git a/ietf/ipr/urls.py b/ietf/ipr/urls.py index 554215b0b..e27c38224 100644 --- a/ietf/ipr/urls.py +++ b/ietf/ipr/urls.py @@ -17,7 +17,3 @@ urlpatterns = patterns('', (r'^new-(?Pthird-party)/$', new.new), url(r'^search/$', search.search, name="ipr_search"), ) - - - - diff --git a/ietf/ipr/views.py b/ietf/ipr/views.py index baadc323c..bc6df1076 100644 --- a/ietf/ipr/views.py +++ b/ietf/ipr/views.py @@ -20,7 +20,7 @@ def showlist(request): generic_disclosures = disclosures.filter(status__in=[1,3], generic=1) specific_disclosures = disclosures.filter(status__in=[1,3], generic=0, third_party=0) thirdpty_disclosures = disclosures.filter(status__in=[1,3], generic=0, third_party=1) - + return render("ipr/list.html", { 'generic_disclosures' : generic_disclosures.order_by(* ['-submitted_date', ] ), diff --git a/ietf/secr/ipradmin/forms.py b/ietf/secr/ipradmin/forms.py index a7d62d4c9..ef37d1fe8 100644 --- a/ietf/secr/ipradmin/forms.py +++ b/ietf/secr/ipradmin/forms.py @@ -148,11 +148,11 @@ class IprDetailForm(BetterModelForm): self.fields['updated'].initial = updates[0].updated.ipr_id rfcs = {} - for rfc in self.instance.documents.filter(doc_alias__name__startswith='rfc'): + for rfc in self.instance.docs().filter(doc_alias__name__startswith='rfc'): rfcs[rfc.doc_alias.id] = get_rfc_num(rfc.doc_alias.document)+" "+rfc.doc_alias.document.title drafts = {} - for draft in self.instance.documents.exclude(doc_alias__name__startswith='rfc'): + for draft in self.instance.docs().exclude(doc_alias__name__startswith='rfc'): drafts[draft.doc_alias.id] = draft.doc_alias.document.name self.initial['rfc_num'] = simplejson.dumps(rfcs) self.initial['id_filename'] = simplejson.dumps(drafts) diff --git a/ietf/secr/ipradmin/views.py b/ietf/secr/ipradmin/views.py index 8e0a325e6..b1a24c73a 100644 --- a/ietf/secr/ipradmin/views.py +++ b/ietf/secr/ipradmin/views.py @@ -145,7 +145,7 @@ def admin_notify(request, ipr_id): submitter_text = get_submitter_text(ipr_id, updated_ipr_id, from_page) document_relatives = '' - for iprdocalias in ipr_dtl.documents.all(): + for iprdocalias in ipr_dtl.docs(): document_relatives += get_document_relatives(ipr_dtl, iprdocalias.doc_alias) return dict( @@ -520,8 +520,8 @@ def admin_detail(request, ipr_id): # conversion #rfcs = ipr_dtl.rfcs.all() #drafts = ipr_dtl.drafts.all() - rfcs = ipr_dtl.documents.filter(doc_alias__name__startswith='rfc') - drafts = ipr_dtl.documents.exclude(doc_alias__name__startswith='rfc') + rfcs = ipr_dtl.docs().filter(doc_alias__name__startswith='rfc') + drafts = ipr_dtl.docs().exclude(doc_alias__name__startswith='rfc') titles_data, rfcs_data, drafts_data, designations_data = (), (), (), () rfc_titles, draft_titles = [], [] if rfcs: diff --git a/ietf/templates/ipr/details.html b/ietf/templates/ipr/details.html index d62c4edb6..c657da35f 100644 --- a/ietf/templates/ipr/details.html +++ b/ietf/templates/ipr/details.html @@ -21,8 +21,10 @@ table.ipr { margin-top: 1em; } {% endblock %} {% block content %} + {% load ietf_filters %} + {% if section_list.title %} -

{{ ipr.title|escape }}

+

{{ ipr.title }}

{% endif %} @@ -59,15 +61,15 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% for item in ipr.updates.all %}

This IPR disclosure updates IPR disclosure ID #{{ item.updated.ipr_id }}, - {% ifequal item.updated.status 0 %} - "{{ item.updated.title|escape }}". + {% if item.updated.status == 0 %} + "{{ item.updated.title }}". {% else %} - {% ifequal item.updated.status 1 %} - "{{ item.updated.title|escape }}". + {% if item.updated.status == 1 %} + "{{ item.updated.title }}". {% else %} - "{{ item.updated.title|escape }}", which was removed at the request of the submitter. - {% endifequal %} - {% endifequal %} + "{{ item.updated.title }}", which was removed at the request of the submitter. + {% endif %} + {% endif %}

{% endfor %} @@ -75,11 +77,11 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if item.processed == 1 and item.ipr.status != 2 %}

This IPR disclosure has been updated by IPR disclosure ID #{{ item.ipr.ipr_id }}, - {% ifequal item.status_to_be 1 %} - "{{ item.ipr.title|escape }}". + {% if item.status_to_be == 1 %} + "{{ item.ipr.title }}". {% else %} - "{{ item.ipr.title|escape }}", which was removed at the request of the submitter. - {% endifequal %} + "{{ item.ipr.title }}", which was removed at the request of the submitter. + {% endif %}

{% endif %} {% endfor %} @@ -103,7 +105,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided - Legal Name: {{ ipr.legal_name|escape }} + Legal Name: {{ ipr.legal_name }} {% endif %} @@ -115,14 +117,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided Patent Holder's Contact for License Application - Name: {{ ipr.holder_contact.name|escape }} - Title: {{ ipr.holder_contact.title|escape }} - Department: {{ ipr.holder_contact.department|escape }} - Address1: {{ ipr.holder_contact.address1|escape }} - Address2: {{ ipr.holder_contact.address2|escape }} - Telephone: {{ ipr.holder_contact.telephone|escape }} - Fax: {{ ipr.holder_contact.fax|escape }} - Email: {{ ipr.holder_contact.email|escape }} + Name: {{ ipr.holder_contact.name }} + Title: {{ ipr.holder_contact.title }} + Department: {{ ipr.holder_contact.department }} + Address1: {{ ipr.holder_contact.address1 }} + Address2: {{ ipr.holder_contact.address2 }} + Telephone: {{ ipr.holder_contact.telephone }} + Fax: {{ ipr.holder_contact.fax }} + Email: {{ ipr.holder_contact.email }} {% endif %} @@ -136,14 +138,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.ietf_contact.name %} - Name: {{ ipr.ietf_contact.name|escape }} - Title: {{ ipr.ietf_contact.title|escape }} - Department: {{ ipr.ietf_contact.department|escape }} - Address1: {{ ipr.ietf_contact.address1|escape }} - Address2: {{ ipr.ietf_contact.address2|escape }} - Telephone: {{ ipr.ietf_contact.telephone|escape }} - Fax: {{ ipr.ietf_contact.fax|escape }} - Email: {{ ipr.ietf_contact.email|escape }} + Name: {{ ipr.ietf_contact.name }} + Title: {{ ipr.ietf_contact.title }} + Department: {{ ipr.ietf_contact.department }} + Address1: {{ ipr.ietf_contact.address1 }} + Address2: {{ ipr.ietf_contact.address2 }} + Telephone: {{ ipr.ietf_contact.telephone }} + Fax: {{ ipr.ietf_contact.fax }} + Email: {{ ipr.ietf_contact.email }} {% else %} No information submitted {% endif %} @@ -163,14 +165,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided RFC Numbers:{{ ipr.rfclist }} {% else %} {% for iprdocalias in ipr.rfcs %} - RFC {{ iprdocalias.doc_alias.document.rfc_number }}:"{{ iprdocalias.doc_alias.document.title }}" + {{ iprdocalias.formatted_name|rfcspace }}:"{{ iprdocalias.doc_alias.document.title }}" {% endfor %} {% endif %} {% if ipr.draftlist %} I-D Filenames (draft-...):{{ ipr.draftlist }} {% else %} {% for iprdocalias in ipr.drafts %} - Internet-Draft:"{{ iprdocalias.doc_alias.document.title }}"
({{ iprdocalias.doc_alias.name }}{% if iprdocalias.rev %}-{{ iprdocalias.rev }}{% endif %}) + Internet-Draft:"{{ iprdocalias.doc_alias.document.title }}"
({{ iprdocalias.formatted_name }}) {% endfor %} {% endif %} {% if ipr.other_designations %} @@ -200,7 +202,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided Date(s) granted or applied for: {{ ipr.date_applied }} Country: {{ ipr.country }} - Additional Notes:{{ ipr.notes|escape|linebreaks }} + Additional Notes:{{ ipr.notes|linebreaks }} B. Does this disclosure relate to an unpublished pending patent application?: @@ -228,7 +230,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.document_sections %} - {{ ipr.document_sections|escape|linebreaks }} + {{ ipr.document_sections|linebreaks }} {% else %} No information submitted {% endif %} @@ -283,7 +285,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.comments %} - {{ ipr.comments|escape|linebreaks }} + {{ ipr.comments|linebreaks }} {% else %} No information submitted {% endif %} @@ -353,14 +355,14 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% endif %} {% endif %} - Name: {{ ipr.submitter.name|escape }} - Title: {{ ipr.submitter.title|escape }} - Department: {{ ipr.submitter.department|escape }} - Address1: {{ ipr.submitter.address1|escape }} - Address2: {{ ipr.submitter.address2|escape }} - Telephone: {{ ipr.submitter.telephone|escape }} - Fax: {{ ipr.submitter.fax|escape }} - Email: {{ ipr.submitter.email|escape }} + Name: {{ ipr.submitter.name }} + Title: {{ ipr.submitter.title }} + Department: {{ ipr.submitter.department }} + Address1: {{ ipr.submitter.address1 }} + Address2: {{ ipr.submitter.address2 }} + Telephone: {{ ipr.submitter.telephone }} + Fax: {{ ipr.submitter.fax }} + Email: {{ ipr.submitter.email }} {% else %} No information submitted {% endif %} @@ -377,7 +379,7 @@ Template for {{ section_list.disclosure_type }}" where the submitter provided {% if ipr.other_notes %} - {{ ipr.other_notes|escape|linebreaks }} + {{ ipr.other_notes|linebreaks }} {% else %} No information submitted {% endif %} diff --git a/ietf/templates/ipr/search_doctitle_result.html b/ietf/templates/ipr/search_doctitle_result.html index 66ea47d6b..988545d17 100644 --- a/ietf/templates/ipr/search_doctitle_result.html +++ b/ietf/templates/ipr/search_doctitle_result.html @@ -19,7 +19,7 @@ - IPR that is related to {{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title|escape }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title }}"{% endif %} + IPR that is related to {{ alias.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.document.title }}"{% if alias.related %}, that was {{ alias.relation|lower }} {{ alias.related.source.name|rfcspace|lstrip:"0"|rfcnospace }}, "{{ alias.related.source.title }}"{% endif %} @@ -31,10 +31,10 @@ {% for item in ipr.updated_by.all %} {% if item.processed == 1 and item.ipr.status != 2 %} - IPR disclosure ID# {{ item.ipr.ipr_id }} "{{ item.ipr.title|escape }}" Updates + IPR disclosure ID# {{ item.ipr.ipr_id }} "{{ item.ipr.title }}" Updates {% endif %} {% endfor %} - "{{ ipr.title|escape }}" + "{{ ipr.title }}" {% endfor %} diff --git a/ietf/templates/ipr/search_result.html b/ietf/templates/ipr/search_result.html index 622a89fc3..9345e2e5b 100644 --- a/ietf/templates/ipr/search_result.html +++ b/ietf/templates/ipr/search_result.html @@ -5,6 +5,7 @@ {% block doctype %}{% endblock %} {% block title %}IPR Search Result{% endblock %} {% block content %} +{% load ietf_filters %}

IPR Disclosures

{% block search_result %} @@ -24,37 +25,37 @@ - + {% for item in ipr.updates.all %} - {% ifnotequal item ipr %} + {% if item != ipr %} - {% endifnotequal %} + {% endif %} {% endfor %} {% endfor %} diff --git a/ietf/utils/test_data.py b/ietf/utils/test_data.py index 67df82345..63e9fbc99 100644 --- a/ietf/utils/test_data.py +++ b/ietf/utils/test_data.py @@ -387,10 +387,15 @@ def make_test_data(): lic_opt_a_sub=2, lic_opt_b_sub=2, lic_opt_c_sub=2, + patents="PTO12345", + date_applied="foo", + country="Whole World", comments="", lic_checkbox=True, other_notes="", status=1, + generic=0, + third_party=0, submitted_date=datetime.date.today(), ) diff --git a/ietf/wgcharter/views.py b/ietf/wgcharter/views.py index 9a6b74bd9..a9831cf11 100644 --- a/ietf/wgcharter/views.py +++ b/ietf/wgcharter/views.py @@ -4,7 +4,6 @@ from django.http import HttpResponse, HttpResponseRedirect, HttpResponseNotFound from django.shortcuts import render_to_response, get_object_or_404, redirect from django.template.loader import render_to_string from django.core.urlresolvers import reverse as urlreverse -from django.core.urlresolvers import reverse from django.template import RequestContext from django import forms from django.forms.util import ErrorList @@ -319,7 +318,7 @@ def edit_ad(request, name): charter.time = e.time charter.save() - return HttpResponseRedirect(reverse('doc_view', kwargs={'name': charter.name})) + return redirect('doc_view', name=charter.name) else: init = { "ad" : charter.ad_id } form = AdForm(initial=init) diff --git a/ietf/wginfo/edit.py b/ietf/wginfo/edit.py index 69441242c..b14839c89 100644 --- a/ietf/wginfo/edit.py +++ b/ietf/wginfo/edit.py @@ -4,7 +4,6 @@ import re, os, datetime, shutil from django.shortcuts import render_to_response, get_object_or_404, redirect from django.http import HttpResponseForbidden -from django.core.urlresolvers import reverse from django.template import RequestContext from django import forms from django.utils import simplejson diff --git a/ietf/wginfo/milestones.py b/ietf/wginfo/milestones.py index dee1765cc..a83f2303b 100644 --- a/ietf/wginfo/milestones.py +++ b/ietf/wginfo/milestones.py @@ -3,7 +3,6 @@ import re, os, string, datetime, shutil, calendar from django.shortcuts import render_to_response, get_object_or_404, redirect -from django.core.urlresolvers import reverse from django.template import RequestContext from django import forms from django.http import HttpResponse, HttpResponseForbidden, HttpResponseBadRequest
{% block intro_prefix %}IPR that was submitted by {{ q }}, and{% endblock %} {% block related %} - {% with ipr.docs as docs %} - {% if not docs %} - is not related to a specific IETF contribution. + {% with ipr.docs as iprdocaliases %} + {% if not iprdocaliases %} + is not related to a specific IETF contribution. {% else %} is related to - {% for item in docs %} - {% if forloop.last and forloop.counter > 1 %}and{% endif %} - {{ item.document }}, "{{ item.document.title|escape }},"{% if item.document.related %}, {{ item.document.relation }} {{ item.document.related }}, "{{ item.document.related.title|escape }}"{% endif %} + {% for item in iprdocaliases %} + {% if forloop.last and forloop.counter > 1 %}and{% endif %} + {{ item.formatted_name|rfcspace }}, "{{ item.doc_alias.document.title }}"{% if not forloop.last and forloop.counter > 1 %},{% endif %} {% endfor %} {% endif %} {% endwith %} - {% endblock %} + {% endblock %} {% block intro_suffix %}{% endblock %}
{{ ipr.submitted_date }}
  • ID # {{ ipr.ipr_id }}
  • "{{ ipr.title|escape }}""{{ ipr.title }}"
    {{ item.updated.submitted_date }}
  • ID # {{ item.updated.ipr_id }}
  • - IPR disclosure ID# {{ ipr.ipr_id }} "{{ ipr.title|escape }}" - Updates {{ item.updated.title|escape }} + IPR disclosure ID# {{ ipr.ipr_id }} "{{ ipr.title }}" + Updates {{ item.updated.title }}