"""
InaSAFE Disaster risk assessment tool developed by AusAid and World Bank
- **GUI Test Cases.**
Contact : ole.moller.nielsen@gmail.com
.. note:: 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.
"""
__author__ = 'tim@linfiniti.com'
__date__ = '21/02/2011'
__copyright__ = ('Copyright 2012, Australia Indonesia Facility for '
'Disaster Reduction')
import unittest
import sys
import os
import shutil
from safe.engine.core import unique_filename
# Add PARENT directory to path to make test aware of other modules
pardir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
sys.path.append(pardir)
from PyQt4 import QtGui, QtCore
from PyQt4.QtTest import QTest
from qgis.core import (QgsRasterLayer,
QgsVectorLayer,
QgsMapLayerRegistry)
from third_party.odict import OrderedDict
from safe_qgis.utilities_test import (getQgisTestApp,
unitTestDataPath)
from safe_qgis.safe_interface import readKeywordsFromFile
from safe_qgis.keywords_dialog import KeywordsDialog
from safe_qgis.exceptions import KeywordNotFoundException
from safe_qgis.utilities import getDefaults
# For testing and demoing
from safe.common.testing import HAZDATA, TESTDATA
# Get QGis app handle
QGISAPP, CANVAS, IFACE, PARENT = getQgisTestApp()
[docs]def makePadangLayer():
"""Helper function that returns a single predefined layer"""
myFile = 'Shakemap_Padang_2009.asc'
myPath = os.path.join(HAZDATA, myFile)
myTitle = readKeywordsFromFile(myPath, 'title')
# myTitle = 'An earthquake in Padang like in 2009'
myLayer = QgsRasterLayer(myPath, myTitle)
QgsMapLayerRegistry.instance().addMapLayer(myLayer)
return myLayer
[docs]def makePadangLayerClone():
"""Helper function that copies padang keyword for testing and return it."""
mySourceFileName = 'Shakemap_Padang_2009'
myExts = ['.asc', '.asc.aux.xml', '.keywords',
'.lic', '.prj', '.qml', '.sld']
myFileName = unique_filename()
# copy to temp file
for ext in myExts:
mySourcePath = os.path.join(HAZDATA, mySourceFileName + ext)
myDestPath = os.path.join(HAZDATA, myFileName + ext)
shutil.copy2(mySourcePath, myDestPath)
# return a single predefined layer
myFile = myFileName + '.asc'
myPath = os.path.join(HAZDATA, myFile)
myTitle = readKeywordsFromFile(myPath, 'title')
myLayer = QgsRasterLayer(myPath, myTitle)
QgsMapLayerRegistry.instance().addMapLayer(myLayer)
return myLayer, myFileName
[docs]def makePolygonLayer():
"""Helper function that returns a single predefined layer"""
myFile = 'kabupaten_jakarta_singlepart_3_good_attr.shp'
myPath = os.path.join(TESTDATA, myFile)
try:
myTitle = readKeywordsFromFile(myPath, 'title')
except KeywordNotFoundException:
myTitle = 'kabupaten_jakarta_singlepart_3_good_attr'
myLayer = QgsVectorLayer(myPath, myTitle, 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(myLayer)
return myLayer
[docs]def makePointLayer():
"""Helper function that returns a single predefined layer"""
myFile = 'test_buildings.shp'
myPath = os.path.join(TESTDATA, myFile)
try:
myTitle = readKeywordsFromFile(myPath, 'title')
except KeywordNotFoundException:
myTitle = 'kabupaten_jakarta_singlepart_3_good_attr'
myLayer = QgsVectorLayer(myPath, myTitle, 'ogr')
QgsMapLayerRegistry.instance().addMapLayer(myLayer)
return myLayer
[docs]def removeTempFile(myFileName='temp_Shakemap_Padang_2009'):
"""Helper function that removes temp file that created during test"""
#myFileName = 'temp_Shakemap_Padang_2009'
myExts = ['.asc', '.asc.aux.xml', '.keywords',
'.lic', '.prj', '.qml', '.sld']
for ext in myExts:
os.remove(os.path.join(HAZDATA, myFileName + ext))
[docs]def makeKeywordlessLayer():
"""Helper function that returns a single predefined keywordless layer"""
myFile = 'keywordless_layer.tif'
myBasePath = unitTestDataPath('hazard')
myPath = os.path.abspath(os.path.join(myBasePath, myFile))
myTitle = 'Keywordless Layer'
myLayer = QgsRasterLayer(myPath, myTitle)
QgsMapLayerRegistry.instance().addMapLayer(myLayer)
return myLayer
[docs]def clearLayers():
"""Clear all the loaded layers"""
for myLayer in QgsMapLayerRegistry.instance().mapLayers():
QgsMapLayerRegistry.instance().removeMapLayer(myLayer)
[docs]class KeywordsDialogTest(unittest.TestCase):
"""Test the InaSAFE keywords GUI"""
[docs] def setUp(self):
"""Create fresh dialog for each test"""
pass
[docs] def tearDown(self):
"""Destroy the dialog after each test"""
clearLayers()
[docs] def test_showHelp(self):
"""Test that help button works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myButton = myDialog.buttonBox.button(QtGui.QDialogButtonBox.Help)
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myMessage = 'Help dialog was not created when help button pressed'
assert myDialog.helpDialog is not None, myMessage
[docs] def test_on_pbnAdvanced_toggled(self):
"""Test advanced button toggle behaviour works"""
makePadangLayer()
myDialog = KeywordsDialog(PARENT, IFACE)
myButton = myDialog.pbnAdvanced
myButton.setChecked(False)
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myState = myDialog.grpAdvanced.isHidden()
myExpectedState = False
myMessage = ('Advanced options did not become visible when'
' the advanced button was clicked\nGot'
'%s\nExpected\%s\n' % (myState, myExpectedState))
assert myState == myExpectedState, myMessage
# Now hide advanced again and test...
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myState = myDialog.grpAdvanced.isHidden()
myExpectedState = True
myMessage = ('Advanced options did not become hidden when'
' the advanced button was clicked again\nGot'
'%s\nExpected\%s\n' % (myState, myExpectedState))
assert not myDialog.grpAdvanced.isVisible(), myMessage
[docs] def test_on_radHazard_toggled(self):
"""Test hazard radio button toggle behaviour works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myButton = myDialog.radHazard
myButton.setChecked(False)
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myMessage = ('Toggling the hazard radio did not add a category '
'to the keywords list.')
assert myDialog.getValueForKey('category') == 'hazard', myMessage
[docs] def test_on_radPostprocessing_toggled(self):
"""Test hazard radio button toggle behaviour works"""
myLayer = makePolygonLayer()
myDefaults = getDefaults()
myDialog = KeywordsDialog(PARENT, IFACE, theLayer=myLayer)
myButton = myDialog.radPostprocessing
myButton.setChecked(False)
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myMessage = ('Toggling the postprocessing radio did not add a '
'category to the keywords list.')
assert myDialog.getValueForKey(
'category') == 'postprocessing', myMessage
myMessage = ('Toggling the postprocessing radio did not add an '
'aggregation attribute to the keywords list.')
assert myDialog.getValueForKey(
myDefaults['AGGR_ATTR_KEY']) == 'KAB_NAME', myMessage
myMessage = ('Toggling the postprocessing radio did not add a '
'female ratio attribute to the keywords list.')
assert myDialog.getValueForKey(
myDefaults['FEM_RATIO_ATTR_KEY']) == \
myDialog.tr('Use default'), myMessage
myMessage = ('Toggling the postprocessing radio did not add a '
'female ratio default value to the keywords list.')
assert float(myDialog.getValueForKey(
myDefaults['FEM_RATIO_KEY'])) == \
myDefaults['FEM_RATIO'], myMessage
[docs] def test_on_dsbFemaleRatioDefault_valueChanged(self):
"""Test hazard radio button toggle behaviour works"""
myLayer = makePolygonLayer()
myDefaults = getDefaults()
myDialog = KeywordsDialog(PARENT, IFACE, theLayer=myLayer)
myButton = myDialog.radPostprocessing
myButton.setChecked(False)
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myFemaleRatioAttrBox = myDialog.cboFemaleRatioAttribute
#set to Don't use
myIndex = myFemaleRatioAttrBox.findText(
myDialog.tr('Don\'t use'))
myMessage = (myDialog.tr('Don\'t use') + ' not found')
assert (myIndex != -1), myMessage
myFemaleRatioAttrBox.setCurrentIndex(myIndex)
myMessage = ('Toggling the female ratio attribute combo to'
' "Don\'t use" did not add it to the keywords list.')
assert myDialog.getValueForKey(
myDefaults['FEM_RATIO_ATTR_KEY']) ==\
myDialog.tr('Don\'t use'), myMessage
myMessage = ('Toggling the female ratio attribute combo to'
' "Don\'t use" did not disable dsbFemaleRatioDefault.')
myIsEnabled = myDialog.dsbFemaleRatioDefault.isEnabled()
assert not myIsEnabled, myMessage
myMessage = ('Toggling the female ratio attribute combo to'
' "Don\'t use" did not remove the keyword.')
assert (myDialog.getValueForKey(myDefaults['FEM_RATIO']) is
None), myMessage
#set to TEST_REAL
myIndex = myFemaleRatioAttrBox.findText('TEST_REAL')
myMessage = ('TEST_REAL not found')
assert (myIndex != -1), myMessage
myFemaleRatioAttrBox.setCurrentIndex(myIndex)
myMessage = ('Toggling the female ratio attribute combo to "TEST_REAL"'
' did not add it to the keywords list.')
assert myDialog.getValueForKey(
myDefaults['FEM_RATIO_ATTR_KEY']) == 'TEST_REAL', myMessage
myMessage = ('Toggling the female ratio attribute combo to "TEST_REAL"'
' did not disable dsbFemaleRatioDefault.')
myIsEnabled = myDialog.dsbFemaleRatioDefault.isEnabled()
assert not myIsEnabled, myMessage
myMessage = ('Toggling the female ratio attribute combo to "TEST_REAL"'
' did not remove the keyword.')
assert (myDialog.getValueForKey(myDefaults['FEM_RATIO']) is
None), myMessage
[docs] def Xtest_on_radExposure_toggled(self):
"""Test exposure radio button toggle behaviour works"""
# Cannot get this test to work, but it works fine in the safe_qgis
myDialog = KeywordsDialog(PARENT, IFACE)
myButton = myDialog.radExposure
myButton.setChecked(False)
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myMessage = ('Toggling the exposure radio did not add a category '
'to the keywords list.')
assert myDialog.getValueForKey('category') == 'exposure', myMessage
[docs] def test_on_cboSubcategory_currentIndexChanged(self):
"""Test subcategory combo change event works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myButton = myDialog.radHazard
myButton.setChecked(True)
myButton = myDialog.radExposure
QTest.mouseClick(myButton, QtCore.Qt.LeftButton)
myCombo = myDialog.cboSubcategory
QTest.mouseClick(myCombo, QtCore.Qt.LeftButton)
QTest.keyClick(myCombo, QtCore.Qt.Key_Up)
QTest.keyClick(myCombo, QtCore.Qt.Key_Enter)
myMessage = ('Changing the subcategory did not add '
'to the keywords list for %s' %
myCombo.currentText())
myKey = myDialog.getValueForKey('subcategory')
assert myKey is not None, myMessage
assert myKey in str(myCombo.currentText()), myMessage
[docs] def test_setSubcategoryList(self):
"""Test set subcategory list works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myList = OrderedDict([('population [density]',
'population [density]'),
('population [count]',
'population [count]'),
('building',
'building'),
('building [osm]',
'building [osm]'),
('building [sigab]',
'building [sigab]'),
('roads',
'roads')])
mySelectedItem = 'building'
myDialog.setSubcategoryList(myList, mySelectedItem)
myResult = str(myDialog.cboSubcategory.currentText())
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, mySelectedItem))
assert myResult == mySelectedItem, myMessage
[docs] def test_on_pbnAddToList1_clicked(self):
"""Test adding an item to the list using predefined form works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myDialog.radPredefined.setChecked(True)
myDialog.cboKeyword.setCurrentIndex(2)
myExpectedResult = 'foo'
myDialog.lePredefinedValue.setText(myExpectedResult)
# Work around for commented out line below
myDialog.on_pbnAddToList1_clicked()
#QTest.mouseClick(myDialog.pbnAddToList1, QtCore.Qt.LeftButton)
myResult = myDialog.getValueForKey('datatype')
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
assert myResult == myExpectedResult, myMessage
[docs] def test_on_pbnAddToList2_clicked(self):
"""Test adding an item to the list using user defened form works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myDialog.radUserDefined.setChecked(True)
myDialog.leKey.setText('foo')
myDialog.leValue.setText('bar')
myExpectedResult = 'bar'
myDialog.lePredefinedValue.setText(myExpectedResult)
# Work around for commented out line below
myDialog.on_pbnAddToList2_clicked()
#QTest.mouseClick(myDialog.pbnAddToList2, QtCore.Qt.LeftButton)
myResult = myDialog.getValueForKey('foo')
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
[docs] def test_on_pbnRemove_clicked(self):
"""Test pressing remove works on key list"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myResult = myDialog.lstKeywords.count()
myExpectedResult = 0
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
myDialog.addListEntry('bar', 'foo')
myResult = myDialog.lstKeywords.count()
myExpectedResult = 1
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
[docs] def test_addListEntry(self):
"""Test add entry to list works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myDialog.addListEntry('bar', 'foo')
myResult = myDialog.getValueForKey('bar')
myExpectedResult = 'foo'
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
[docs] def test_addWarningsForColons(self):
"""Test add entry to list works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myDialog.addListEntry('bar', 'fo:o')
myResult = myDialog.getValueForKey('bar')
myExpectedResult = 'fo.o'
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
#
# Check the user gets a message if they put colons in the value
#
myExpectedResult = 'Colons are not allowed, replaced with "."'
myResult = str(myDialog.lblMessage.text())
myMessage = ('lblMessage error \nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
#
# Check the user gets a message if they put colons in the key
#
myDialog.addListEntry('ba:r', 'foo')
myExpectedResult = 'Colons are not allowed, replaced with "."'
myResult = str(myDialog.lblMessage.text())
myMessage = ('lblMessage error \nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
[docs] def test_setCategory(self):
"""Test set category works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myDialog.setCategory('hazard')
myExpectedResult = 'hazard'
myResult = myDialog.getValueForKey('category')
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
[docs] def test_reset(self):
"""Test form reset works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.leTitle.setText('Foo')
myDialog.reset(False)
myExpectedResult = ''
myResult = myDialog.leTitle.text()
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
assert myResult == myExpectedResult, myMessage
[docs] def test_removeItemByKey(self):
"""Test remove item by its key works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.reset(False)
myDialog.addListEntry('bar', 'foo')
myDialog.removeItemByKey('bar')
myResult = myDialog.lstKeywords.count()
myExpectedResult = 0
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myResult, myExpectedResult))
#print 'Dict', myDialog.getKeywords()
assert myResult == myExpectedResult, myMessage
[docs] def test_removeItemByValue(self):
"""Test remove item by its value works"""
makePadangLayer()
myDialog = KeywordsDialog(PARENT, IFACE)
myDialog.removeItemByValue('hazard')
myKeywords = myDialog.getKeywords()
myExpectedKeywords = {'source': 'USGS',
'title': 'An earthquake in Padang like in 2009',
'subcategory': 'earthquake',
'unit': 'MMI'}
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myKeywords, myExpectedKeywords))
assert myKeywords == myExpectedKeywords, myMessage
[docs] def test_getValueForKey(self):
"""Test get value for key works"""
makePadangLayer()
myDialog = KeywordsDialog(PARENT, IFACE)
myExpectedValue = 'hazard'
myValue = myDialog.getValueForKey('category')
myMessage = ('\nExpected key value of %s\nGot %s' %
(myExpectedValue, myValue))
assert myValue == myExpectedValue, myMessage
[docs] def test_loadStateFromKeywords(self):
"""Test load state from keywords works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myLayer = makePadangLayer()
myDialog.layer = myLayer
myDialog.loadStateFromKeywords()
myKeywords = myDialog.getKeywords()
myExpectedKeywords = {'title': 'An earthquake in Padang like in 2009',
'category': 'hazard',
'source': 'USGS',
'subcategory': 'earthquake',
'unit': 'MMI'}
myMessage = ('\nGot:\n%s\nExpected:\n%s\n' %
(myKeywords, myExpectedKeywords))
assert myKeywords == myExpectedKeywords, myMessage
[docs] def test_checkStateWhenKeywordsAbsent(self):
"""Test load state from keywords works"""
myDialog = KeywordsDialog(PARENT, IFACE)
myLayer = makeKeywordlessLayer()
myDialog.layer = myLayer
myDialog.loadStateFromKeywords()
myKeywords = myDialog.getKeywords()
#check that a default title is given (see
#https://github.com/AIFDR/inasafe/issues/111)
myExpectedKeywords = {'category': 'exposure',
'title': 'Keywordless Layer'}
myMessage = ('\nGot: %s\nExpected: %s\n' %
(myKeywords, myExpectedKeywords))
assert myKeywords == myExpectedKeywords, myMessage
if __name__ == '__main__':
suite = unittest.makeSuite(KeywordsDialogTest, 'test')
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)