Repository: bird-house/birdy

Issue:
Inputs are given default mimetype
## Description

If an input has multiple supported formats, birdy will always use the first one in the list when creating a request. If an input has to be embedded in the request, and its mimetype is a binary format while the default mimetype is not, it crashes the `embed` function. 

## Environment

* Birdy version used, if any: 0.6.6


Discussion:

Patch:
diff --git a/CHANGES.rst b/CHANGES.rst
index 613a7d0..82eee94 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,7 +1,7 @@
 Change History
 **************
 
-0.6.7 (2020-03-10)
+0.6.8 (2020-03-10)
 ==================
 
 Changes:
diff --git a/birdy/client/base.py b/birdy/client/base.py
index 9bbf39f..d4bdf2e 100644
--- a/birdy/client/base.py
+++ b/birdy/client/base.py
@@ -250,14 +250,7 @@ class WPSClient(object):
                 if isinstance(input_param.defaultValue, ComplexData):
 
                     # Guess the mimetype of the input value
-                    mimetype, encoding = guess_type(value)
-
-                    # If unrecognized, default to the first supported mimetype
-                    if mimetype is None:
-                        mimetype = supported_mimetypes[0]
-                    else:
-                        if mimetype not in supported_mimetypes:
-                            raise ValueError(f"mimetype {mimetype} not in supported mimetypes {supported_mimetypes}.")
+                    mimetype, encoding = guess_type(value, supported_mimetypes)
 
                     if encoding is None:
                         encoding = input_param.defaultValue.encoding
diff --git a/birdy/utils.py b/birdy/utils.py
index b892acf..0a6afae 100644
--- a/birdy/utils.py
+++ b/birdy/utils.py
@@ -122,8 +122,16 @@ def _encode(content, mimetype, encoding):
         # return u'<![CDATA[{}]]>'.format(content)
 
 
-def guess_type(url):
-    """Guess the mime type of the file link.
+def guess_type(url, supported):
+    """Guess the mime type of the file link. If the mimetype is not recognized, default to the first supported value.
+
+
+    Parameters
+    ----------
+    url : str
+      Path or URL to file.
+    supported : list, tuple
+      Supported mimetypes.
 
     Returns
     -------
@@ -143,10 +151,20 @@ def guess_type(url):
     if mime == "application/x-netcdf" and "dodsC" in url:
         mime = "application/x-ogc-dods"
 
-    # application/zip vs application/x-zipped-shp
-    # TODO
+    zips = ["application/zip", "application/x-zipped-shp"]
+
+    if mime not in supported:
+        if mime in zips and set(zips).intersection(supported):
+            mime = set(zips).intersection(supported).pop()
 
     # All the various XML schemes
     # TODO
 
+    # If unrecognized, default to the first supported mimetype
+    if mime is None:
+        mime = supported[0]
+    else:
+        if mime not in supported:
+            raise ValueError(f"mimetype {mime} not in supported mimetypes {supported}.")
+
     return mime, enc


Test patch:
diff --git a/tests/test_utils.py b/tests/test_utils.py
index 5f89691..06aad07 100644
--- a/tests/test_utils.py
+++ b/tests/test_utils.py
@@ -1,7 +1,6 @@
 from birdy import utils
 from .common import resource_file
 from pathlib import Path
-import pytest
 
 
 def test_is_url():
@@ -66,9 +65,22 @@ class TestEncode:
             assert isinstance(nc, bytes)
 
 
-@pytest.mark.parametrize("value,expected", [("LSJ_LL.zip", "application/zip"),
-                                            ("https://remote.org/thredds/dodsC/a.nc", "application/x-ogc-dods"),
-                                            ("https://remote.org/thredds/file/a.nc", "application/x-netcdf")])
-def test_guess_type(value, expected):
-    mime, enc = utils.guess_type(value)
-    assert mime == expected
+class TestGuessType:
+    def test_zip(self):
+        mime, enc = utils.guess_type("LSJ_LL.zip", ["application/gml+xml",
+                                                    "application/zip",
+                                                    "application/x-zipped-shp", ])
+        assert mime == "application/zip"
+
+        mime, enc = utils.guess_type("LSJ_LL.zip", ["application/gml+xml",
+                                                    "application/x-zipped-shp", ])
+        assert mime == "application/x-zipped-shp"
+
+    def test_nc(self):
+        mime, enc = utils.guess_type("https://remote.org/thredds/dodsC/a.nc", ["application/x-netcdf",
+                                                                               "application/x-ogc-dods"])
+        assert mime == "application/x-ogc-dods"
+
+        mime, enc = utils.guess_type("https://remote.org/thredds/file/a.nc", ["application/x-ogc-dods",
+                                                                              "application/x-netcdf"])
+        assert mime == "application/x-netcdf"