Repository: pypi/warehouse

Issue:
Unexpected Results on Filtering in Browse by Licence
Given the indentation on the licence tree in the  Browse by Licence view I was surprised by the following results:

 - Filter on [OSI Approved](https://pypi.org/search/?q=&o=&c=License+%3A%3A+OSI+Approved): **654** Projects
 - Add [MIT Filter](https://pypi.org/search/?q=&o=&c=License+%3A%3A+OSI+Approved&c=License+%3A%3A+OSI+Approved+%3A%3A+MIT+License): **95** projects.
  - Remove [OSI Approved](https://pypi.org/search/?q=&o=&c=License+%3A%3A+OSI+Approved+%3A%3A+MIT+License): **10,000+** Projects.
  
Knowing that MIT is OSI Approved, the indentation, _and the inclusion of OSI Approved in the MIT filter URL,_ led me to expect that filtering on OSI Approved was the same as ticking all of the boxes for all of the OSI Approved licences but it seems that instead this box is filtering on packages that explicitly set "OSI Approved" in the meta data and adding MIT, _(or any other),_ restricts this to packages what explicitly set **both** "OSI Approved" **and** "IOS Approved::MIT"!

This is not what I, _and I suspect most people,_ would expect. I do know that really this is the package authors "fault" in that they should have set **both** tags in the meta data but I am not going to raise tickets on over 10, 000 projects and expect a quick resolution.

Possible resolutions:

 1. Have a tick box within OSI Approved for Specifically OSI Approved.
 2. Any of:
   - remove the tick box for OSI Approved and make just a grouping
   - remove the grouping
   - have toggling OSI Approved (category) toogle ticks on all of the nested lines
   - change the filter for OSI Approved (category) from ::OSI Approved to ::OSI Approved* _or whatever the  appropriate wildcard is_
   - Re-Index the packages so that all packages with any of the OSI Approved licences are automatically included in the OSI Approved category.


Discussion:

Resolving patch:
diff --git a/warehouse/views.py b/warehouse/views.py
--- a/warehouse/views.py
+++ b/warehouse/views.py
@@ -276,7 +276,7 @@ def search(request):
 
     # Require match to all specified classifiers
     for classifier in request.params.getall("c"):
-        query = query.filter("terms", classifiers=[classifier])
+        query = query.query("prefix", classifiers=classifier)
 
     try:
         page_num = int(request.params.get("page", 1))


Test patch:
diff --git a/tests/unit/test_views.py b/tests/unit/test_views.py
--- a/tests/unit/test_views.py
+++ b/tests/unit/test_views.py
@@ -410,6 +410,7 @@ def test_with_classifiers(self, monkeypatch, db_request, metrics, page):
         es_query = pretend.stub(
             suggest=pretend.call_recorder(lambda *a, **kw: es_query),
             filter=pretend.call_recorder(lambda *a, **kw: es_query),
+            query=pretend.call_recorder(lambda *a, **kw: es_query),
             sort=pretend.call_recorder(lambda *a, **kw: es_query),
         )
         db_request.es = pretend.stub(
@@ -460,9 +461,9 @@ def test_with_classifiers(self, monkeypatch, db_request, metrics, page):
         assert es_query.suggest.calls == [
             pretend.call("name_suggestion", params["q"], term={"field": "name"})
         ]
-        assert es_query.filter.calls == [
-            pretend.call("terms", classifiers=["foo :: bar"]),
-            pretend.call("terms", classifiers=["fiz :: buz"]),
+        assert es_query.query.calls == [
+            pretend.call("prefix", classifiers="foo :: bar"),
+            pretend.call("prefix", classifiers="fiz :: buz"),
         ]
         assert metrics.histogram.calls == [
             pretend.call("warehouse.views.search.results", 1000)