Repository: mrf345/flask_minify

Issue:
Some endpoints are causing errors in Flask-Minify
This is my setup:
`minify(app=app, bypass=[r'users\.register', r'users\.contact'])`
If I don't supply an argument to the bypass parameter no errors appear.

When I hit `ctrl + u` Chrome takes me to the source code of a specific page.

For example I'm currently on the home page (http://127.0.0.1:5000/home)
Now I press `ctrl + u` and it takes me to the source code of the home page 
(view-source:http://127.0.0.1:5000/home)
When I do that I'm receiving the following errors:

`Traceback (most recent call last):
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 2463, in __call__
    return self.wsgi_app(environ, start_response)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 2449, in wsgi_app
    response = self.handle_exception(e)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 1866, in handle_exception
    reraise(exc_type, exc_value, tb)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
    return self.finalize_request(rv)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 1969, in finalize_request
    response = self.process_response(response)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask\app.py", line 2266, in process_response
    response = handler(response)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask_minify\main.py", line 151, in main
    should_bypass = self.get_endpoint_matches(self.bypass)
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask_minify\main.py", line 117, in get_endpoint_matches
    [compile_re(pattern) for pattern in patterns]
  File "c:\users\anders\onedrive\computer science\python\projekter\anime-website\env\lib\site-packages\flask_minify\main.py", line 118, in <listcomp>
    if compiled_pattern.match(self.endpoint)]
TypeError: expected string or bytes-like object`


Inside the get_endpoint_matches method (`def get_endpoint_matches(self, patterns`)
`self.endpoint` returns  `None` when the URL is: view-source:http://127.0.0.1:5000/blabla...

The method should probably just ignore endpoints that are `None`, and that is exactly my current workaround for now.

original:
```
matches = [compiled_pattern for compiled_pattern in
                   [compile_re(pattern) for pattern in patterns]
                   if compiled_pattern.match(self.endpoint)]
```

workaround:
```
matches = [compiled_pattern for compiled_pattern in
                   [compile_re(pattern) for pattern in patterns]
                   if compiled_pattern.match(self.endpoint)] if self.endpoint else []

```

I think that endpoints for static files are not being handled properly by Flask-Minify.

Discussion:

Patch:
diff --git a/.travis.yml b/.travis.yml
index f21efb7..f9cd114 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,6 @@ python:
 install:
   - pip install -r requirements/test.txt
 # command to run tests
-script: py.test --cov=./flask_minify/ tests/integration.py
+script: py.test --cov=./flask_minify tests/*
 after_success:
   - coveralls
diff --git a/flask_minify/main.py b/flask_minify/main.py
index c39c8dc..053a5e0 100644
--- a/flask_minify/main.py
+++ b/flask_minify/main.py
@@ -72,7 +72,7 @@ class minify(object):
     def endpoint(self):
         ''' to get the current response endpoint, with a failsafe.'''
         with self.app.app_context():
-            return getattr(request, 'endpoint', '')
+            return getattr(request, 'endpoint', '') or ''
 
     @property
     def iter_tags_to_minify(self):


Test patch:
diff --git a/requirements/test.txt b/requirements/test.txt
index 517da61..4fb8d17 100644
--- a/requirements/test.txt
+++ b/requirements/test.txt
@@ -3,3 +3,4 @@ pytest
 pytest-cov
 coverage
 python-coveralls
+mock
\ No newline at end of file
diff --git a/tests/integration.py b/tests/integration.py
index 8d655c4..0da2219 100644
--- a/tests/integration.py
+++ b/tests/integration.py
@@ -1,6 +1,5 @@
 from sys import path as sys_path
 from os import path
-from sys import path as sys_path
 from importlib import import_module
 from pytest import fixture
 from flask import Flask
diff --git a/tests/units.py b/tests/units.py
new file mode 100644
index 0000000..f01006c
--- /dev/null
+++ b/tests/units.py
@@ -0,0 +1,44 @@
+from sys import path as sys_path
+from os import path
+from importlib import import_module
+
+
+sys_path.append(path.dirname(path.dirname(__file__)))
+minify = import_module('flask_minify').minify
+unittest = import_module('unittest')
+
+# workaround for py2 vs py3 mock import
+mock = getattr(unittest, 'mock', None) or import_module('mock')
+
+
+class TestMinifyRequest:
+    def setup(self):
+        self.mock_request = mock.Mock()
+        self.mock_app = mock.Mock()
+        self.mock_app.app_context.return_value = mock.MagicMock()
+        self.js = False
+        self.cssless = False
+        self.fail_safe = False
+        self.bypass = []
+        self.bypass_caching = []
+        self.caching_limit = 1
+        self.patch = mock.patch.multiple('flask_minify.main',
+                                         request=self.mock_request)
+
+        self.patch.start()
+
+    def teardown(self):
+        self.patch.stop()
+
+    @property
+    def minify_defaults(self):
+        return minify(self.mock_app, self.js, self.cssless, self.fail_safe,
+                      self.bypass, self.bypass_caching, self.caching_limit)
+
+    def test_request_falsy_endpoint(self):
+        ''' test edge-case of request's endpoint being falsy '''
+        endpoint = '/testing'
+        self.mock_request.endpoint = None
+        self.bypass.append(endpoint)
+
+        assert self.minify_defaults.get_endpoint_matches([endpoint]) == []