# -*- coding: utf-8 -*-
"""Unit tests for tweens.py"""
import mock
import re
import pytest
import simplejson
from mock import Mock
from pyramid.response import Response


from pyramid_swagger.exceptions import ResponseValidationError
from pyramid_swagger.tween import DEFAULT_EXCLUDED_PATHS
from pyramid_swagger.tween import get_exclude_paths
from pyramid_swagger.tween import prepare_body
from pyramid_swagger.tween import should_exclude_path
from pyramid_swagger.tween import validate_outgoing_response


def test_default_exclude_paths():
    assert get_exclude_paths(Mock(settings={})) \
        == [re.compile(r) for r in DEFAULT_EXCLUDED_PATHS]


def test_exclude_path_with_string():
    path_string = r'/foo/'
    assert get_exclude_paths(
        Mock(settings={'pyramid_swagger.exclude_paths': path_string})) \
        == [re.compile(r) for r in [path_string]]


def test_exclude_path_with_overrides():
    paths = [r'/foo/', r'/bar/']
    compiled = get_exclude_paths(
        Mock(settings={'pyramid_swagger.exclude_paths': paths}))
    assert compiled == [re.compile(r) for r in paths]


def test_exclude_path_with_old_setting():
    # TODO(#63): remove deprecated `skip_validation` setting in v2.0.
    paths = [r'/foo/', r'/bar/']
    assert get_exclude_paths(
        Mock(settings={'pyramid_swagger.skip_validation': paths})) \
        == [re.compile(r) for r in paths]


def test_response_charset_missing_raises_5xx():
    with pytest.raises(ResponseValidationError):
        prepare_body(
            Response(content_type='foo')
        )


def test_validation_skips_path_properly():
    excluded_paths = [re.compile(r) for r in DEFAULT_EXCLUDED_PATHS]
    assert should_exclude_path(excluded_paths, '/static')
    assert should_exclude_path(excluded_paths, '/static/foobar')
    assert should_exclude_path(excluded_paths, '/api-docs')
    assert should_exclude_path(excluded_paths, '/api-docs/foobar')

    assert not should_exclude_path(excluded_paths, '/sample')
    assert not should_exclude_path(excluded_paths, '/sample/resources')


# TODO: Should probably be migrated to acceptance tests after we make mocking
# schemas easier there.
def test_validation_content_type_with_json():
    fake_schema = mock.Mock(response_body_schema={'type': 'object'})
    response = Response(
        body=simplejson.dumps({'status': 'good'}),
        headers={'Content-Type': 'application/json; charset=UTF-8'},
    )
    validate_outgoing_response(response, fake_schema, None)


def test_raw_string():
    fake_schema = mock.Mock(response_body_schema={'type': 'string'})
    response = Response(
        body='abe1351f',
        headers={'Content-Type': 'application/text; charset=UTF-8'},
    )
    validate_outgoing_response(response, fake_schema, None)

@@ -500,16 +500,125 @@
 ponse%0A%0A%0A
+def assert_eq_regex_lists(left, right):%0A    assert %5Br.pattern for r in left%5D == %5Br.pattern for r in right%5D%0A%0A%0A
 def test
@@ -645,32 +645,56 @@
 hs():%0A    assert
+_eq_regex_lists(%0A       
  get_exclude_pat
@@ -714,26 +714,25 @@
 ngs=%7B%7D))
- %5C
+,
 %0A       
  == %5Bre.
@@ -715,35 +715,32 @@
 gs=%7B%7D)),%0A       
- ==
  %5Bre.compile(r) 
@@ -772,16 +772,22 @@
 _PATHS%5D%0A
+    )%0A
 %0A%0Adef te
@@ -852,41 +852,18 @@
     
-assert get_exclude_paths(%0A       
+registry =
  Moc
@@ -920,30 +920,88 @@
 string%7D)
-) %5C%0A        ==
+%0A    assert_eq_regex_lists(%0A        get_exclude_paths(registry),%0A       
  %5Bre.com
@@ -1032,16 +1032,22 @@
 tring%5D%5D%0A
+    )%0A
 %0A%0Adef te
@@ -1226,20 +1226,50 @@
 sert
- compiled ==
+_eq_regex_lists(%0A        compiled,%0A       
  %5Bre
@@ -1288,32 +1288,38 @@
 for r in paths%5D%0A
+    )%0A
 %0A%0Adef test_exclu
@@ -1459,16 +1459,40 @@
   assert
+_eq_regex_lists(%0A       
  get_exc
@@ -1495,32 +1495,36 @@
 _exclude_paths(%0A
+    
         Mock(set
@@ -1577,18 +1577,17 @@
 s%7D))
- %5C
+,
 %0A       
  == 
@@ -1582,19 +1582,16 @@
 %0A       
- ==
  %5Bre.com
@@ -1614,16 +1614,22 @@
  paths%5D%0A
+    )%0A
 %0A%0Adef te

Fix failing tests by comparing regex by their pattern.