# -*- encoding: iso-8859-1 -*-
#
# Copyright (c) 2004 by Intevation GmbH
# Authors:
# Martin Schulze <joey@infodrom.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

"""
Test for WMSCapabilitiesParser from ../parser.py

"""

__version__ = "$Revision: 2786 $"
# $Source$
# $Id: test_parser.py 2786 2007-11-27 23:54:45Z bernhard $

import os
import unittest
import sys


# If run directly as a script, add Thuban's test directory to the path.
# Otherwise we assume that the importing code has already done it.
if __name__ == "__main__":
    sys.path.append(os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),
                                 "..", "..", "..", "test"))
import support
support.initthuban()

from Extensions.wms.parser import WMSCapabilitiesParser


class TestWMSCapabilitiesParser(unittest.TestCase, WMSCapabilitiesParser):
    """
    Defines a test environment for the class WMSCapabilities.
    """

    def compareLists(self, foo, bar):
        """
        Compare two lists
        - check same number of elements
        - check whether all elements in the first list are part of the second
        """

        # Check for same number of elements
        if len(foo) != len(bar):
            self.fail("Different number of elements");

        # Loop through all elements for existance
        for elm in foo:
            if elm not in bar:
                self.fail("%s not in second list" % elm);


    def compareDicts(self, foo, bar):
        """
        Compare two dictionaries (hashes)
        - check same number of keys
        - check whether all keys from the first list are part of the second
        """

        # Check for same number of elements
        if len(foo) != len(bar):
            self.fail("Different number of keys");

        # Loop through all elements for existance
        for key in foo.keys():
            if key not in bar:
                self.fail("%s not in second dictionary" % key);
            if foo[key] != bar[key]:
                self.fail("%s has different value in second dictionary" % key);


    def setUp(self):
        """
        Load the locally stored frida capabilities.
        http://frida.intevation.org/cgi-bin/frida_wms?
        """

        try:
            try:
                f = open("sample.xml", "r")
            except:
                f = open(os.path.dirname(__file__) + "/sample.xml", "r")
        except:
            print "Cannot open sample.xml for reading"
        else:
            xml = f.read();
            f.close()
            self.grok(xml)


    def test_compareLists(self):
        """
        Test the internal compareLists method.
        """

        # Equality of empty lists
        self.compareLists([], [])

        # Equality of equal lists
        self.compareLists([1,2], [1,2])

        # Equality of permuted lists
        self.compareLists([1,2], [2,1])

        # Equality of large permuted lists
        self.compareLists([1,2,3,4,5,6,7,8], [8,3,1,2,5,7,4,6])

        # Non-Equality of different lists
        self.assertRaises(AssertionError, self.compareLists, [1,2], [3,2])

        # Non-Equality of different lists
        self.assertRaises(AssertionError, self.compareLists, [1,2], [3,2,1])

        # Non-Equality of empty and non-empty list
        self.assertRaises(AssertionError, self.compareLists, [], [3,2,1])
        

    def test_compareDicts(self):
        """
        Test the internal compareDicts method.
        """

        # Equality of empty dictionaries
        self.compareDicts({}, {})

        # Equality of equal dictionaries
        # Python may represent the dictionaries differently
        self.compareDicts({10:20, 11:30}, {10:20, 11:30})
                        
        # Equality of permuted dictionaries
        # Python may represent the dictionaries similar anyway
        self.compareDicts({10:20, 11:30}, {11:30, 10:20})
                        
        # Non-equality of different dictionaries
        self.assertRaises(AssertionError, self.compareDicts, {10:20, 11:30},
                          {10:20, 11:30, 12:40})

        # Non-equality of empty and non-empty dictionaries
        self.assertRaises(AssertionError, self.compareDicts, {},
                          {10:20, 11:30, 12:40})


    def test_general(self):
        """
        Test general attributes extracted from Capabilities XML
        """

        self.assertEquals(self.getTitle().encode('latin-1'),
                          'Frida - Freie Vektor-Geodaten Osnabrück')
        self.assertEquals(self.getAbstract(), '')
        self.assertEquals(self.getFees(), '')
        self.assertEquals(self.getAccessConstraints(), '')
        formats = ['image/gif', 'image/png', 'image/jpeg', 'image/wbmp']
        self.compareLists(self.getFormats(), formats)
        layers = ['Osnabrueck', 'gruenflaechen', 'gewaesser',
                  'gewaesserpolyl','gewaesserlinien', 'strassen_all',
                  'strassenhinten', 'strassen', 'beschriftung',
                  'hauptbeschriftung', 'sehenswuerdigkeiten']
        self.compareLists(self.getLayers(), layers)
        self.compareLists(self.getSRS(), ['31493'])


    def test_LayerTitle(self):
        """
        Check if layer titles are recognised properly
        """

        # main layer
        self.assertEquals(self.getLayerTitle('Osnabrueck').encode('latin-1'),
                          'Frida - Freie Vektor-Geodaten Osnabrück')

        # first nested layer
        self.assertEquals(self.getLayerTitle(
                          'gruenflaechen').encode('latin-1'),
                          'Grünflächen')

        # first nested layer
        self.assertEquals(self.getLayerTitle('gewaesser').encode('latin-1'),
                          'Gewässer')

        # second nested layer
        self.assertEquals(self.getLayerTitle(
                          'gewaesserpolyl').encode('latin-1'),
                          'Gewässerflächen')


    def test_LayerSRS(self):
        """
        Check if the SRS are returned properly
        """

        # SRS of main layer
        self.compareLists(self.getLayerSRS('Osnabrueck'), ['31493'])

        # Single SRS of layer without inheritance
        self.compareLists(self.getLayerSRS('gruenflaechen'), ['31493'])

        # Multiple SRS of layer without inheritance, but overwriting
        self.compareLists(self.getLayerSRS('gewaesserpolyl'),
                          ['31493', '31494'])

        # Multiple SRS of layer with inheritance, one new locally
        self.compareLists(self.getLayerSRS('gewaesserlinien'),
                          ['31493', '31492'])

        # Multiple SRS with inheritance, two new locally
        self.compareLists(self.getLayerSRS('strassen'),
                          ['31493', '31494', '31495'])

        # Single SRS with inheritance but overwriting
        self.compareLists(self.getLayerSRS('beschriftung'),
                          ['31493', '31494', '31495'])

        # SRS of a layer with AUTO SRS ignored
        self.compareLists(self.getLayerSRS('sehenswuerdigkeiten'), ['31493'])


    def test_LatLonBoundingBoxes(self):
        """
        Check if the LatLonBoundingBoxes are returned properly
        """

        # main LatLonBoundingBox
        bbox = {'minx': "7.92881", 'miny': "52.2131",
                'maxx': "8.18349", 'maxy': "52.341"}
        self.compareDicts(self.getLayerLatLonBBox('Osnabrueck'), bbox)

        # inherited LatLonBoundingBox
        bbox = {'minx': "7.92881", 'miny': "52.2131",
                'maxx': "8.18349", 'maxy': "52.341"}
        self.compareDicts(self.getLayerLatLonBBox('gewaesser'), bbox)

        # third layer non-inherited LatLonBoundingBox
        bbox = {'minx': "7.93531", 'miny': "52.2328",
                'maxx': "8.17739", 'maxy': "52.3353"}
        self.compareDicts(self.getLayerLatLonBBox('gewaesserpolyl'), bbox)


    def test_BoundingBoxes(self):
        """
        Check if the BoundingBoxes are returned properly
        """

        # main BoundingBox
        bbox = {'minx': "3.427e+06",  'miny': "5.787e+06",
                'maxx': "3.4442e+06", 'maxy': "5.801e+06"}
        self.compareDicts(self.getLayerBBox('Osnabrueck', '31493'), bbox)

        # inherited BoundingBox
        self.compareDicts(self.getLayerBBox('gewaesser', '31493'), bbox)

        # overwritten BoundingBox
        bbox = {'minx': "3.427e+06",   'miny': "5.78901e+06",
                'maxx': "3.44173e+06", 'maxy': "5.79952e+06"}
        self.compareDicts(self.getLayerBBox('gewaesserlinien', '31492'), bbox)

        # multiple BoundingBoxes
        bbox = {'minx': "3.42743e+06", 'miny': "5.78919e+06",
                'maxx': "3.44381e+06", 'maxy': "5.80038e+06"}
        self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31493'), bbox)
        bbox = {'minx': "3.42742e+06", 'miny': "5.78918e+06",
                'maxx': "3.44380e+06", 'maxy': "5.80037e+06"}
        self.compareDicts(self.getLayerBBox('gewaesserpolyl', '31494'), bbox)

        # Non-existing BoundingBox
        self.assertEquals(self.getLayerBBox('beschriftung', '31490'), None)


    def test_LatLonBoundingBoxes_as_bboxes(self):
        """
        Check if the LatLonBoundingBoxes are returned properly
        """

        # main LatLonBoundingBox
        bbox = {'minx': "7.92881", 'miny': "52.2131",
                'maxx': "8.18349", 'maxy': "52.341"}
        self.compareDicts(self.getLayerBBox('Osnabrueck', '4326'), bbox)

        # inherited LatLonBoundingBox
        bbox = {'minx': "7.92881", 'miny': "52.2131",
                'maxx': "8.18349", 'maxy': "52.341"}
        self.compareDicts(self.getLayerBBox('gewaesser', '4326'), bbox)

        # third layer non-inherited LatLonBoundingBox
        bbox = {'minx': "7.93531", 'miny': "52.2328",
                'maxx': "8.17739", 'maxy': "52.3353"}
        self.compareDicts(self.getLayerBBox('gewaesserpolyl', '4326'), bbox)


    def test_queryable(self):
        """
        Check if layers are properly classified queryable or not
        """

        # implicit setting in main layer
        self.assertEquals(self.isQueryable('Osnabrueck'), 0)

        # explicit setting in second layer
        self.assertEquals(self.isQueryable('gruenflaechen'), 0)
        
        # inherited setting in second layer
        self.assertEquals(self.isQueryable('gewaesser'), 0)
        
        # explicit setting in second layer
        self.assertEquals(self.isQueryable('sehenswuerdigkeiten'), 1)
        
        # explicit setting in third layer
        self.assertEquals(self.isQueryable('strassen'), 1)


if __name__ == "__main__":
    unittest.main()
