1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
# -*- coding: UTF-8 -*-
# =============================================================================
# Copyright (c) 2025 Tom Kralidis
#
# Authors : Tom Kralidis <tomkralidis@gmail.com>
#
# Contact email: tomkralidis@gmail.com
# =============================================================================
import codecs
from datetime import datetime, timezone
from unittest import mock
import pytest
from owslib.etree import etree
from owslib.util import clean_ows_url, build_get_url, strip_bom, extract_time, ResponseWrapper, getXMLTree, str2bool
def test_strip_bom():
assert strip_bom('<city>Hamburg</city>') == '<city>Hamburg</city>'
assert strip_bom(codecs.BOM_UTF8 + '<city>Dublin</city>'.encode('utf-8')) == \
'<city>Dublin</city>'.encode('utf-8')
assert strip_bom(codecs.BOM_UTF16 + '<city>Vancover</city>'.encode('utf-16')) == \
'<city>Vancover</city>'.encode('utf-16')
def test_clean_ows_url():
assert clean_ows_url('http//example.org/wms') == 'http//example.org/wms'
assert clean_ows_url('http//example.org/wms?service=WMS') == 'http//example.org/wms'
assert clean_ows_url('http//example.org/wms?SERVICE=WMS') == 'http//example.org/wms'
assert clean_ows_url('http//example.org/wms?SeRvIcE=WMS') == 'http//example.org/wms'
assert clean_ows_url('http//example.org/wms?SeRvIcE=WMS&version=1.3.0&request=GetCapabilities') == 'http//example.org/wms' # noqa
assert clean_ows_url('http//example.org/wms?foo=bar&SeRvIcE=WMS&version=1.3.0&request=GetCapabilities') == 'http//example.org/wms?foo=bar' # noqa
assert clean_ows_url('http://example.org/wms?map=/path/to/foo.map&SERVICE=WMS&version=1.3.0&request=GetCapabilities') == 'http://example.org/wms?map=%2Fpath%2Fto%2Ffoo.map' # noqa
clean_url = clean_ows_url('http://example.org/wms?map=/path/to/foo.map&foo=bar&&SERVICE=WMS&version=1.3.0&request=GetCapabilities') # noqa
assert 'http://example.org/wms?' in clean_url
assert 'map=%2Fpath%2Fto%2Ffoo.map' in clean_url
assert 'foo=bar' in clean_url
def test_build_get_url():
assert build_get_url("http://example.org/wps", {'service': 'WPS'}) == 'http://example.org/wps?service=WPS'
assert build_get_url("http://example.org/wms", {'SERVICE': 'wms'}) == 'http://example.org/wms?SERVICE=wms'
assert build_get_url("http://example.org/wms?map=/path/to/foo.map&", {'SERVICE': 'wms'}) == \
'http://example.org/wms?map=%2Fpath%2Fto%2Ffoo.map&SERVICE=wms'
assert build_get_url("http://example.org/wps?service=WPS", {'request': 'GetCapabilities'}) == \
'http://example.org/wps?service=WPS&request=GetCapabilities'
assert build_get_url("http://example.org/wps?service=WPS", {'request': 'GetCapabilities'}) == \
'http://example.org/wps?service=WPS&request=GetCapabilities'
# Can not overwrite parameter
assert build_get_url("http://example.org/ows?SERVICE=WPS", {'SERVICE': 'WMS'}) == \
'http://example.org/ows?SERVICE=WPS'
# Parameter is case-senstive
assert build_get_url("http://example.org/ows?SERVICE=WPS", {'service': 'WMS'}) == \
'http://example.org/ows?SERVICE=WPS&service=WMS'
# Test with trailing ampersand and doseq False (default)
assert build_get_url("http://example.org/ows?SERVICE=WFS&", {'typename': 'test', 'keys': [1, 2]}, doseq=False) == \
'http://example.org/ows?SERVICE=WFS&typename=test&keys=%5B1%2C+2%5D'
# Test with trailing ampersand and doseq True
assert build_get_url("http://example.org/ows?SERVICE=WFS&", {'typename': 'test', 'keys': [1, 2]}, doseq=True) == \
'http://example.org/ows?SERVICE=WFS&typename=test&keys=1&keys=2'
def test_build_get_url_overwrite():
# Use overwrite flag
assert build_get_url("http://example.org/ows?SERVICE=WPS", {'SERVICE': 'WMS'}, overwrite=True) == \
'http://example.org/ows?SERVICE=WMS'
def test_getXMLTree_valid():
mock_resp = mock.Mock()
mock_resp.url = 'http:///example.org/?service=WFS&request=GetCapabilities&version=2.0.0'
mock_resp.content = b'<?xml version="1.0" encoding="UTF-8"?>\n<WFS_Capabilities><ServiceIdentification>' \
b'<Title>Example</Title></ServiceIdentification></WFS_Capabilities>'
mock_resp.headers = {'Content-Type': 'text/xml; charset=UTF-8'}
resp_wrap = ResponseWrapper(mock_resp)
et = getXMLTree(resp_wrap)
assert et.find('.//Title').text == "Example"
def test_getXMLTree_non_xml_mime_type():
mock_resp = mock.Mock()
mock_resp.url = 'http:///example.org/?service=WFS&request=GetCapabilities&version=2.0.0'
mock_resp.content = b'<?xml version="1.0" encoding="UTF-8"?>\n<WFS_Capabilities><ServiceIdentification>' \
b'<Title>Example</Title></ServiceIdentification></WFS_Capabilities>'
# test with a non-XML mime type, but the response starts with <?xml
mock_resp.headers = {'Content-Type': 'application/octet-stream'}
resp_wrap = ResponseWrapper(mock_resp)
et = getXMLTree(resp_wrap)
assert et.find('.//Title').text == "Example"
def test_getXMLTree_valid_missing_content_type():
mock_resp = mock.Mock()
mock_resp.url = 'http:///example.org/?service=WFS&request=GetCapabilities&version=2.0.0'
mock_resp.content = b'<?xml version="1.0" encoding="UTF-8"?>\n<WFS_Capabilities><ServiceIdentification>' \
b'<Title>Example</Title></ServiceIdentification></WFS_Capabilities>'
mock_resp.headers = {}
resp_wrap = ResponseWrapper(mock_resp)
et = getXMLTree(resp_wrap)
assert et.find('.//Title').text == "Example"
def test_getXMLTree_invalid():
mock_resp = mock.Mock()
mock_resp.url = 'http:///example.org/?service=WFS&request=GetCapabilities&version=2.0.0'
mock_resp.content = b'<HTML><HEAD></HEAD><BODY BGCOLOR="#FFFFFF">\nmsCGILoadMap(): Web application error. ' \
b'CGI variable "map" is not set.\n</BODY></HTML>'
mock_resp.headers = {'Content-Type': 'text/html'}
resp_wrap = ResponseWrapper(mock_resp)
with pytest.raises(ValueError) as ex:
getXMLTree(resp_wrap)
assert str(ex.value) == 'http:///example.org/?service=WFS&request=GetCapabilities&version=2.0.0 responded with Content-Type \'text/html\'' \
': \'msCGILoadMap(): Web application error. CGI variable \"map\" is not set.\''
def test_time_zone_utc():
now = datetime.utcnow()
as_utc = now.replace(tzinfo=timezone.utc)
assert as_utc.isoformat()[-6:] == "+00:00"
def test_extract_time():
definite_sample = "<beginPosition>2006-07-27T21:10:00Z</beginPosition>"
indefinite_sample = "<endPosition indeterminatePosition=\"now\"></endPosition>"
start = extract_time(etree.fromstring(definite_sample))
assert start.isoformat()[-6:] == "+00:00"
stop = extract_time(etree.fromstring(indefinite_sample))
assert stop.isoformat()[-6:] == "+00:00"
def test_str2bool():
assert str2bool('1')
assert not str2bool('0')
assert int(str2bool('true')) == 1
assert int(str2bool('false')) == 0
|