From 433efe06191a7007ca8c5bf8fafee5c7c1439ebb Mon Sep 17 00:00:00 2001
From: Michael Merickel <github@m.merickel.org>
Date: Mon, 15 Oct 2018 04:03:15 +0200
Subject: [PATCH] Merge pull request #3326 from mmerickel/fix-deprecated-accept-predicate

---
 pyramid/tests/test_config/test_views.py |  135 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 111 insertions(+), 24 deletions(-)

diff --git a/pyramid/tests/test_config/test_views.py b/pyramid/tests/test_config/test_views.py
index 1c99d2a..6565a35 100644
--- a/pyramid/tests/test_config/test_views.py
+++ b/pyramid/tests/test_config/test_views.py
@@ -842,7 +842,7 @@
         config.add_view(view=view2, renderer=null_renderer)
         wrapper = self._getViewCallable(config)
         self.assertTrue(IMultiView.providedBy(wrapper))
-        self.assertEqual([x[:2] for x in wrapper.views], [(view2, None)])
+        self.assertEqual([(x[0], x[2]) for x in wrapper.views], [(view2, None)])
         self.assertEqual(wrapper(None, None), 'OK1')
 
     def test_add_view_exc_multiview_replaces_multiviews(self):
@@ -869,13 +869,13 @@
         hot_wrapper = self._getViewCallable(
             config, ctx_iface=implementedBy(RuntimeError))
         self.assertTrue(IMultiView.providedBy(hot_wrapper))
-        self.assertEqual([x[:2] for x in hot_wrapper.views], [(view2, None)])
+        self.assertEqual([(x[0], x[2]) for x in hot_wrapper.views], [(view2, None)])
         self.assertEqual(hot_wrapper(None, None), 'OK1')
 
         exc_wrapper = self._getViewCallable(
             config, exc_iface=implementedBy(RuntimeError))
         self.assertTrue(IMultiView.providedBy(exc_wrapper))
-        self.assertEqual([x[:2] for x in exc_wrapper.views], [(view2, None)])
+        self.assertEqual([(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)])
         self.assertEqual(exc_wrapper(None, None), 'OK1')
 
     def test_add_view_exc_multiview_replaces_only_exc_multiview(self):
@@ -908,7 +908,7 @@
         exc_wrapper = self._getViewCallable(
             config, exc_iface=implementedBy(RuntimeError))
         self.assertTrue(IMultiView.providedBy(exc_wrapper))
-        self.assertEqual([x[:2] for x in exc_wrapper.views], [(view2, None)])
+        self.assertEqual([(x[0], x[2]) for x in exc_wrapper.views], [(view2, None)])
         self.assertEqual(exc_wrapper(None, None), 'OK1')
 
     def test_add_view_multiview_context_superclass_then_subclass(self):
@@ -1465,7 +1465,7 @@
         config.add_view(view=view, accept='text/xml', renderer=null_renderer)
         wrapper = self._getViewCallable(config)
         request = self._makeRequest(config)
-        request.accept = ['text/xml']
+        request.accept = DummyAccept('text/xml')
         self.assertEqual(wrapper(None, request), 'OK')
 
     def test_add_view_with_accept_nomatch(self):
@@ -1474,7 +1474,26 @@
         config.add_view(view=view, accept='text/xml')
         wrapper = self._getViewCallable(config)
         request = self._makeRequest(config)
-        request.accept = ['text/html']
+        request.accept = DummyAccept('text/html')
+        self._assertNotFound(wrapper, None, request)
+
+    def test_add_view_with_range_accept_match(self):
+        from pyramid.renderers import null_renderer
+        view = lambda *arg: 'OK'
+        config = self._makeOne(autocommit=True)
+        config.add_view(view=view, accept='text/*', renderer=null_renderer)
+        wrapper = self._getViewCallable(config)
+        request = self._makeRequest(config)
+        request.accept = DummyAccept('text/html', contains=True)
+        self.assertEqual(wrapper(None, request), 'OK')
+
+    def test_add_view_with_range_accept_nomatch(self):
+        view = lambda *arg: 'OK'
+        config = self._makeOne(autocommit=True)
+        config.add_view(view=view, accept='text/*')
+        wrapper = self._getViewCallable(config)
+        request = self._makeRequest(config)
+        request.accept = DummyAccept('application/json', contains=False)
         self._assertNotFound(wrapper, None, request)
 
     def test_add_view_with_containment_true(self):
@@ -2389,6 +2408,73 @@
         request.exception = Exception()
         self.assertEqual(derived_view(None, request), 'OK')
 
+    def test_add_view_does_not_accept_iterable_accept(self):
+        from pyramid.exceptions import ConfigurationError
+        config = self._makeOne(autocommit=True)
+        self.assertRaises(
+            ConfigurationError, config.add_view, accept=['image/*', 'text/*'],
+        )
+
+    def test_default_accept_view_order(self):
+        from pyramid.interfaces import IAcceptOrder
+        config = self._makeOne(autocommit=True)
+        order = config.registry.getUtility(IAcceptOrder)
+        result = [v for _, v in order.sorted()]
+        self.assertEqual(result, [
+            'text/html',
+            'application/xhtml+xml',
+            'application/xml',
+            'text/xml',
+            'text/plain',
+            'application/json',
+        ])
+
+    def test_add_accept_view_order_override(self):
+        from pyramid.interfaces import IAcceptOrder
+        config = self._makeOne(autocommit=False)
+        config.add_accept_view_order(
+            'text/html',
+            weighs_more_than='text/xml',
+            weighs_less_than='application/xml',
+        )
+        config.commit()
+        order = config.registry.getUtility(IAcceptOrder)
+        result = [v for _, v in order.sorted()]
+        self.assertEqual(result, [
+            'application/xhtml+xml',
+            'application/xml',
+            'text/html',
+            'text/xml',
+            'text/plain',
+            'application/json',
+        ])
+
+    def test_add_accept_view_order_throws_on_wildcard(self):
+        config = self._makeOne(autocommit=True)
+        self.assertRaises(
+            ValueError, config.add_accept_view_order, '*/*',
+        )
+
+    def test_add_accept_view_order_throws_on_type_mismatch(self):
+        config = self._makeOne(autocommit=True)
+        self.assertRaises(
+            ValueError, config.add_accept_view_order,
+            'text/*', weighs_more_than='text/html',
+        )
+        self.assertRaises(
+            ValueError, config.add_accept_view_order,
+            'text/html', weighs_less_than='application/*',
+        )
+        self.assertRaises(
+            ConfigurationError, config.add_accept_view_order,
+            'text/html', weighs_more_than='text/html;charset=utf8',
+        )
+        self.assertRaises(
+            ConfigurationError, config.add_accept_view_order,
+            'text/html;charset=utf8',
+            weighs_more_than='text/plain;charset=utf8',
+        )
+
 class Test_runtime_exc_view(unittest.TestCase):
     def _makeOne(self, view1, view2):
         from pyramid.config.views import runtime_exc_view
@@ -2499,19 +2585,18 @@
         self.assertEqual(mv.views, [(100, 'view', None)])
         mv.add('view2', 99)
         self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])
-        mv.add('view3', 100, 'text/html')
+        mv.add('view3', 100, accept='text/html')
         self.assertEqual(mv.media_views['text/html'], [(100, 'view3', None)])
-        mv.add('view4', 99, 'text/html', 'abc')
+        mv.add('view4', 99, 'abc', accept='text/html')
         self.assertEqual(mv.media_views['text/html'],
                          [(99, 'view4', 'abc'), (100, 'view3', None)])
-        mv.add('view5', 100, 'text/xml')
+        mv.add('view5', 100, accept='text/xml')
         self.assertEqual(mv.media_views['text/xml'], [(100, 'view5', None)])
         self.assertEqual(set(mv.accepts), set(['text/xml', 'text/html']))
         self.assertEqual(mv.views, [(99, 'view2', None), (100, 'view', None)])
-        mv.add('view6', 98, 'text/*')
-        self.assertEqual(mv.views, [(98, 'view6', None),
-                                    (99, 'view2', None),
-                                    (100, 'view', None)])
+        mv.add('view6', 98, accept='text/*')
+        self.assertEqual(mv.views, [
+            (98, 'view6', None), (99, 'view2', None), (100, 'view', None)])
 
     def test_add_with_phash(self):
         mv = self._makeOne()
@@ -3437,17 +3522,19 @@
     pass
 
 class DummyAccept(object):
-    def __init__(self, *matches):
+    def __init__(self, *matches, **kw):
         self.matches = list(matches)
+        self.contains = kw.pop('contains', False)
 
-    def best_match(self, offered):
-        if self.matches:
-            for match in self.matches:
-                if match in offered:
-                    self.matches.remove(match)
-                    return match
-    def __contains__(self, val):
-        return val in self.matches
+    def acceptable_offers(self, offers):
+        results = []
+        for match in self.matches:
+            if match in offers:
+                results.append((match, 1.0))
+        return results
+
+    def __contains__(self, value):
+        return self.contains
 
 class DummyConfig:
     def __init__(self):
@@ -3475,8 +3562,8 @@
     def __init__(self):
         self.views = []
         self.name = 'name'
-    def add(self, view, order, accept=None, phash=None):
-        self.views.append((view, accept, phash))
+    def add(self, view, order, phash=None, accept=None, accept_order=None):
+        self.views.append((view, phash, accept, accept_order))
     def __call__(self, context, request):
         return 'OK1'
     def __permitted__(self, context, request):

--
Gitblit v1.9.3