def testElectorateHasMeshblocks(self): """ Test checking whether an electorate has meshblocks assigned """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='c', electorate_type='GN', scenario_id=1)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='d', electorate_type='GN', scenario_id=1)) self.assertFalse( reg.electorate_has_meshblocks(electorate_id='a', electorate_type='GN', scenario_id=1)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='z', electorate_type='GS', scenario_id=1)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='zz', electorate_type='GS', scenario_id=1)) self.assertFalse( reg.electorate_has_meshblocks(electorate_id='x', electorate_type='GS', scenario_id=1)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='a', electorate_type='GN', scenario_id=2)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='b', electorate_type='GN', scenario_id=2)) self.assertFalse( reg.electorate_has_meshblocks(electorate_id='c', electorate_type='GN', scenario_id=2)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='x', electorate_type='GS', scenario_id=2)) self.assertTrue( reg.electorate_has_meshblocks(electorate_id='y', electorate_type='GS', scenario_id=2)) self.assertFalse( reg.electorate_has_meshblocks(electorate_id='z', electorate_type='GS', scenario_id=2))
def testFilter(self): """ Test filtering inside the dialog """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() registry = ScenarioRegistry( source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) dlg = ScenarioSelectionDialog(scenario_registry=registry) self.assertEqual( [dlg.list.item(r).text() for r in range(dlg.list.count())], ['Scenario 1', 'scenario 3', 'scenario B']) dlg.search.setText('eee') # connection not fired on first change? dlg.search.setText('3') self.assertEqual([ dlg.list.item(r).text() for r in range(dlg.list.count()) if not dlg.list.item(r).isHidden() ], ['scenario 3']) dlg.search.setText('B') self.assertEqual([ dlg.list.item(r).text() for r in range(dlg.list.count()) if not dlg.list.item(r).isHidden() ], ['scenario B']) # case insensitive! dlg.search.setText('b') self.assertEqual([ dlg.list.item(r).text() for r in range(dlg.list.count()) if not dlg.list.item(r).isHidden() ], ['scenario B'])
def testBranch(self): """ Test branching scenario """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) # dupe name res, error = reg.branch_scenario(1, 'Scenario 1') self.assertFalse(res) self.assertIn('already exists', error) # missing source scenario res, error = reg.branch_scenario(5, 'Scenario 5') self.assertFalse(res) self.assertIn('does not exist', error) # good res, error = reg.branch_scenario(1, 'Scenario 5') self.assertFalse(error) self.assertEqual(res, 4) f = [f for f in layer.getFeatures()][-1] self.assertEqual(f[0], res) self.assertEqual(f[1], 'Scenario 5') self.assertEqual(f[2].date(), QDateTime.currentDateTime().date()) self.assertEqual(f[3], QgsApplication.userFullName()) f = [f.attributes() for f in mb_electorate_layer.getFeatures()] self.assertEqual( f, [[3, 4, 0, 'c', 'z'], [4, 4, 1, 'd', 'zz'], [1, 2, 0, 'a', 'x'], [2, 2, 1, 'b', 'y'], [3, 1, 0, 'c', 'z'], [4, 1, 1, 'd', 'zz']]) res, error = reg.branch_scenario(2, 'Scenario 6') self.assertFalse(error) self.assertEqual(res, 5) f = [f for f in layer.getFeatures()][-1] self.assertEqual(f[0], res) self.assertEqual(f[1], 'Scenario 6') self.assertEqual(f[2].date(), QDateTime.currentDateTime().date()) self.assertEqual(f[3], QgsApplication.userFullName()) f = [f.attributes() for f in mb_electorate_layer.getFeatures()] self.assertEqual( f, [[3, 4, 0, 'c', 'z'], [4, 4, 1, 'd', 'zz'], [1, 5, 0, 'a', 'x'], [2, 5, 1, 'b', 'y'], [1, 2, 0, 'a', 'x'], [2, 2, 1, 'b', 'y'], [3, 1, 0, 'c', 'z'], [4, 1, 1, 'd', 'zz']])
def testConstruct(self): """ Test constructing dock """ scenario_layer = make_scenario_layer() scenario_registry = ScenarioRegistry(source_layer=scenario_layer, id_field='id', name_field='name', meshblock_electorate_layer=None) context = LinzRedistrictingContext(scenario_registry=scenario_registry) widget = LinzRedistrictingDockWidget(context=context, iface=IFACE) self.assertIsNotNone(widget)
def testGetScenarioList(self): """ Test retrieving scenario list """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertEqual(reg.scenario_list(), [1, 2, 3])
def testConstruct(self): """ Test creating dialog """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() registry = ScenarioRegistry( source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertIsNotNone( ScenarioSelectionDialog(scenario_registry=registry))
def testScenarioNameExists(self): """ Test scenario name exists """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertFalse(reg.scenario_name_exists('bbbb')) self.assertTrue(reg.scenario_name_exists('Scenario 1')) self.assertTrue(reg.scenario_name_exists('scenario 3'))
def testGetScenarioName(self): """ Test retrieving scenario name """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertEqual(reg.get_scenario_name(1), "Scenario 1") self.assertEqual(reg.get_scenario_name(2), "scenario B") self.assertEqual(reg.get_scenario_name(3), "scenario 3")
def testAccept(self): """ Test that accepting dialog """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() registry = ScenarioRegistry( source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) dlg = ScenarioSelectionDialog(scenario_registry=registry) dlg.set_selected_scenario('d4') dlg.accept()
def testScenarioExists(self): """ Test scenario exists """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertFalse(reg.scenario_exists(-1)) self.assertTrue(reg.scenario_exists(1)) self.assertTrue(reg.scenario_exists(3)) self.assertFalse(reg.scenario_exists(5))
def testGetScenarioTitles(self): """ Test retrieving scenario titles """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertEqual( reg.scenario_titles(), OrderedDict([('Scenario 1', 1), ('scenario 3', 3), ('scenario B', 2)]))
def testScenarioRegistry(self): """ Test a LinzDistrictRegistry """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) self.assertEqual(reg.source_layer, layer) self.assertEqual(reg.id_field, 'id') self.assertEqual(reg.id_field_index, 0) self.assertEqual(reg.name_field, 'name') self.assertEqual(reg.name_field_index, 1)
def testNameForCurrentTask(self): """ Test retrieving friendly name for currenttask """ scenario_layer = make_scenario_layer() scenario_registry = ScenarioRegistry(source_layer=scenario_layer, id_field='id', name_field='name', meshblock_electorate_layer=None) context = LinzRedistrictingContext(scenario_registry=scenario_registry) context.task = LinzRedistrictingContext.TASK_GN self.assertEqual(context.get_name_for_current_task(), 'General (North Island)') context.task = LinzRedistrictingContext.TASK_GS self.assertEqual(context.get_name_for_current_task(), 'General (South Island)') context.task = LinzRedistrictingContext.TASK_M self.assertEqual(context.get_name_for_current_task(), 'Māori')
def testPopulation(self): """ Test that dialog is correctly populated from registry """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() registry = ScenarioRegistry( source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) dlg = ScenarioSelectionDialog(scenario_registry=registry) self.assertEqual( [dlg.list.item(r).text() for r in range(dlg.list.count())], ['Scenario 1', 'scenario 3', 'scenario B']) # initial selection must be final scenario self.assertEqual(dlg.selected_scenario(), 2)
def testBasic(self): """ Test getters/settings """ scenario_layer = make_scenario_layer() scenario_registry = ScenarioRegistry(source_layer=scenario_layer, id_field='id', name_field='name', meshblock_electorate_layer=None) context = LinzRedistrictingContext(scenario_registry=scenario_registry) self.assertIn(context.task, (LinzRedistrictingContext.TASK_GN, LinzRedistrictingContext.TASK_GS, LinzRedistrictingContext.TASK_M)) context.task = LinzRedistrictingContext.TASK_GS self.assertEqual(context.task, LinzRedistrictingContext.TASK_GS) self.assertIsNotNone(context.scenario) context.scenario = 10 self.assertEqual(context.scenario, 10) context.set_scenario(3) self.assertEqual(context.scenario, 3)
def testGetScenario(self): """ Test retrieving scenario feature """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) f = reg.get_scenario(1) self.assertEqual( f.attributes(), [1, 'Scenario 1', QDateTime(2018, 6, 4, 12, 13, 14), 'user 1']) f = reg.get_scenario(2) self.assertEqual( f.attributes(), [2, 'scenario B', QDateTime(2018, 7, 5, 12, 13, 14), 'user 2'])
def testTitle(self): """ Test title updates """ scenario_layer = make_scenario_layer() scenario_registry = ScenarioRegistry(source_layer=scenario_layer, id_field='id', name_field='name', meshblock_electorate_layer=None) context = LinzRedistrictingContext(scenario_registry=scenario_registry) context.task = LinzRedistrictingContext.TASK_GS context.scenario = 1 widget = LinzRedistrictingDockWidget(context=context, iface=IFACE) self.assertEqual( widget.windowTitle(), 'Redistricting - General (South Island) - Scenario 1') context.task = LinzRedistrictingContext.TASK_GN context.scenario = 3 widget.update_dock_title(context=context) self.assertEqual( widget.windowTitle(), 'Redistricting - General (North Island) - scenario 3')
def testSelection(self): """ Test setting/getting selected scenario """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() registry = ScenarioRegistry( source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) dlg = ScenarioSelectionDialog(scenario_registry=registry) dlg.set_selected_scenario(1) self.assertEqual(dlg.selected_scenario(), 1) dlg.set_selected_scenario(2) self.assertEqual(dlg.selected_scenario(), 2) dlg.set_selected_scenario(3) self.assertEqual(dlg.selected_scenario(), 3) # nothing at all selected dlg.list.clearSelection() self.assertIsNone(dlg.selected_scenario())
def testElectorateMeshblocks(self): """ Test retrieving meshblocks belong to an electorate for a scenario """ layer = make_scenario_layer() mb_electorate_layer = make_meshblock_electorate_layer() reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='c', electorate_type='GN', scenario_id=1) ] self.assertEqual(res, [0]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='d', electorate_type='GN', scenario_id=1) ] self.assertEqual(res, [1]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='a', electorate_type='GN', scenario_id=1) ] self.assertEqual(res, []) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='z', electorate_type='GS', scenario_id=1) ] self.assertEqual(res, [0]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='zz', electorate_type='GS', scenario_id=1) ] self.assertEqual(res, [1]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='x', electorate_type='GS', scenario_id=1) ] self.assertEqual(res, []) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='a', electorate_type='GN', scenario_id=2) ] self.assertEqual(res, [0]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='b', electorate_type='GN', scenario_id=2) ] self.assertEqual(res, [1]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='c', electorate_type='GN', scenario_id=2) ] self.assertEqual(res, []) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='x', electorate_type='GS', scenario_id=2) ] self.assertEqual(res, [0]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='y', electorate_type='GS', scenario_id=2) ] self.assertEqual(res, [1]) res = [ f['meshblock_number'] for f in reg.electorate_meshblocks( electorate_id='z', electorate_type='GS', scenario_id=2) ] self.assertEqual(res, [])
def testDialog(self): """ Test dialog functionality """ scenario_layer = make_scenario_layer() scenario_registry = ScenarioRegistry(source_layer=scenario_layer, id_field='id', name_field='name', meshblock_electorate_layer=None) layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=fld1:string&field=code:string&field=type:string&field=estimated_pop:int&field=deprecated:int&field=stats_nz_pop:int&field=stats_nz_var_20:int&field=stats_nz_var_23:int&field=scenario_id:int", "source", "memory") f = QgsFeature() f.setAttributes(["test4", "xtest1", 'GN']) f2 = QgsFeature() f2.setAttributes(["test2", "xtest3", 'GS']) f3 = QgsFeature() f3.setAttributes(["test3", "xtest3", 'M']) layer.dataProvider().addFeatures([f, f2, f3]) quota_layer = make_quota_layer() reg = LinzElectoralDistrictRegistry(source_layer=layer, quota_layer=quota_layer, electorate_type='', source_field='fld1', title_field='fld1') context = LinzRedistrictingContext(scenario_registry=scenario_registry) dlg = CreateElectorateDialog(registry=reg, context=context) self.assertIsNotNone(dlg) self.assertFalse( dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) dlg.name_line_edit.setText('new district') dlg.code_line_edit.setText('new code') self.assertEqual(dlg.name(), 'new district') self.assertEqual(dlg.code(), 'new code') # dupe name dlg.name_line_edit.setText('test4') self.assertFalse( dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) self.assertIn('already exists', dlg.feedback_label.text()) dlg.name_line_edit.setText('test99') self.assertTrue(dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) self.assertFalse(dlg.feedback_label.text()) dlg.name_line_edit.setText('') self.assertFalse( dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) self.assertIn('must be entered', dlg.feedback_label.text()) dlg.name_line_edit.setText('test99') self.assertTrue(dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) self.assertFalse(dlg.feedback_label.text()) # dupe code dlg.code_line_edit.setText('xtest1') self.assertFalse( dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) self.assertIn('already exists', dlg.feedback_label.text()) dlg.code_line_edit.setText('test99') self.assertTrue(dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) self.assertFalse(dlg.feedback_label.text()) dlg.code_line_edit.setText('') self.assertIn('must be entered', dlg.feedback_label.text()) self.assertFalse( dlg.button_box.button(QDialogButtonBox.Ok).isEnabled()) dlg.code_line_edit.setText('test99') self.assertFalse(dlg.feedback_label.text())
def testValidationTask(self): # pylint: disable=too-many-locals, too-many-statements """ Test validation task """ layer = make_scenario_layer() mb_electorate_layer = QgsVectorLayer( "NoGeometry?field=id:int&field=scenario_id:int&field=meshblock_number:int&field=gn_id:int&field=gs_id:int&field=m_id:int", "source", "memory") f = QgsFeature() f.setAttributes([1, 1, 11, 1, 0, 7]) f2 = QgsFeature() f2.setAttributes([2, 1, 12, 2, 0, 0]) f3 = QgsFeature() f3.setAttributes([3, 1, 13, 2, 0, 0]) f4 = QgsFeature() f4.setAttributes([4, 1, 14, 3, 4, 0]) f5 = QgsFeature() f5.setAttributes([5, 1, 15, 3, 5, 0]) f6 = QgsFeature() f6.setAttributes([6, 1, 16, 2, 5, 0]) mb_electorate_layer.dataProvider().addFeatures([f, f2, f3, f4, f5, f6]) reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) electorate_layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=electorate_id:int&field=code:string&field=type:string&field=estimated_pop:int&field=scenario_id:int&field=deprecated:int&field=invalid:int&field=invalid_reason:string&field=name:string&field=stats_nz_pop:int&field=stats_nz_var_20:int&field=stats_nz_var_23:int&field=electorate_id_stats:string&field=expected_regions:int", "source", "memory") f = QgsFeature() f.setAttributes([ 1, "test1", 'GN', 1, 0, 0, 1, 'old invalid', NULL, NULL, NULL, NULL, NULL, 1 ]) f2 = QgsFeature() f2.setAttributes([ 2, "test2", 'GN', 1, 0, 0, 1, 'old invalid 2', NULL, NULL, NULL, NULL, NULL, 2 ]) f3 = QgsFeature() f3.setAttributes([ 3, "test3", 'GN', 1, 0, 0, 1, 'old invalid 3', NULL, NULL, NULL, NULL, NULL, 2 ]) f4 = QgsFeature() f4.setAttributes([ 4, "test4", 'GS', 1, 0, 0, 1, 'old invalid 4', NULL, NULL, NULL, NULL, NULL, 2 ]) f5 = QgsFeature() f5.setAttributes([ 5, "test5", 'GS', 1, 0, 0, 1, 'old invalid 5', NULL, NULL, NULL, NULL, NULL, 1 ]) f6 = QgsFeature() f6.setAttributes([ 6, "test6", 'GS', 1, 0, 0, 1, 'old invalid 6', NULL, NULL, NULL, NULL, NULL, 1 ]) f7 = QgsFeature() f7.setAttributes([ 7, "test7", 'M', 1, 0, 1, 1, 'old invalid 7', NULL, NULL, NULL, NULL, NULL, 1 ]) f8 = QgsFeature() # deprecated f8.setAttributes([ 8, "test8", 'M', 1, 0, 1, 1, 'old invalid 8', NULL, NULL, NULL, NULL, NULL, 1 ]) electorate_layer.dataProvider().addFeatures( [f, f2, f3, f4, f5, f6, f7, f8]) meshblock_layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=MeshblockNumber:string&field=offline_pop_m:int&field=offline_pop_gn:int&field=offline_pop_gs:int&field=staged_electorate:int&field=offshore:int", "source", "memory") f = QgsFeature() f.setAttributes(["11", 5, 58900, 0, NULL, 0]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2))) f2 = QgsFeature() f2.setAttributes(["12", 6, 57000, 0, NULL, 0]) f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 3))) f3 = QgsFeature() f3.setAttributes(["13", 7, 2000, 0, NULL, 0]) f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(4, 5))) f4 = QgsFeature() f4.setAttributes(["14", 8, 0, 20, NULL, 0]) f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(6, 7))) f5 = QgsFeature() f5.setAttributes(["15", 9, 0, 30, NULL, 0]) f5.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(8, 9))) f6 = QgsFeature() f6.setAttributes(["16", 10, 0, 40, NULL, 1]) f6.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 11))) meshblock_layer.dataProvider().addFeatures([f, f2, f3, f4, f5, f6]) quota_layer = make_quota_layer() electorate_registry = LinzElectoralDistrictRegistry( source_layer=electorate_layer, source_field='electorate_id', title_field='code', electorate_type='GN', quota_layer=quota_layer) task = ValidationTask(task_name='', electorate_registry=electorate_registry, meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1, task='GN') self.assertEqual( [f.attributes()[:9] for f in electorate_layer.getFeatures()], [[1, 'test1', 'GN', 1, 0, 0, NULL, NULL, NULL], [2, 'test2', 'GN', 1, 0, 0, NULL, NULL, NULL], [3, 'test3', 'GN', 1, 0, 0, NULL, NULL, NULL], [4, 'test4', 'GS', 1, 0, 0, 1, 'old invalid 4', NULL], [5, 'test5', 'GS', 1, 0, 0, 1, 'old invalid 5', NULL], [6, 'test6', 'GS', 1, 0, 0, 1, 'old invalid 6', NULL], [7, 'test7', 'M', 1, 0, 1, 1, 'old invalid 7', NULL], [8, 'test8', 'M', 1, 0, 1, 1, 'old invalid 8', NULL]]) self.assertTrue(task.run()) self.assertEqual(len(task.results), 5) self.assertEqual(task.results[0][ValidationTask.ELECTORATE_ID], 2) self.assertEqual(task.results[0][ValidationTask.ELECTORATE_NAME], 'test2') self.assertEqual(task.results[0][ValidationTask.ERROR], 'Electorate is non-contiguous') self.assertEqual( task.results[0][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'MultiPoint ((2 3),(4 5),(10 11))') self.assertEqual(task.results[1][ValidationTask.ELECTORATE_ID], 2) self.assertEqual(task.results[1][ValidationTask.ELECTORATE_NAME], 'test2') self.assertEqual(task.results[1][ValidationTask.ERROR], 'Contiguous part 1') self.assertEqual( task.results[1][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'Point (2 3)') self.assertEqual(task.results[2][ValidationTask.ELECTORATE_ID], 2) self.assertEqual(task.results[2][ValidationTask.ELECTORATE_NAME], 'test2') self.assertEqual(task.results[2][ValidationTask.ERROR], 'Contiguous part 2') self.assertEqual( task.results[2][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'Point (4 5)') self.assertEqual(task.results[3][ValidationTask.ELECTORATE_ID], 2) self.assertEqual(task.results[3][ValidationTask.ELECTORATE_NAME], 'test2') self.assertEqual(task.results[3][ValidationTask.ERROR], 'Contiguous part 3') self.assertEqual( task.results[3][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'Point (10 11)') self.assertEqual(task.results[4][ValidationTask.ELECTORATE_ID], 3) self.assertEqual(task.results[4][ValidationTask.ELECTORATE_NAME], 'test3') self.assertEqual(task.results[4][ValidationTask.ERROR], 'Outside quota tolerance') self.assertEqual( [f.attributes()[:9] for f in electorate_layer.getFeatures()], [[1, 'test1', 'GN', 58900, 1, 0, 0, NULL, NULL], [ 2, 'test2', 'GN', 1, 0, 0, 1, 'Electorate is non-contiguous', NULL ], [ 3, 'test3', 'GN', 1, 0, 0, 1, 'Outside quota tolerance', NULL ], [4, 'test4', 'GS', 1, 0, 0, 1, 'old invalid 4', NULL], [5, 'test5', 'GS', 1, 0, 0, 1, 'old invalid 5', NULL], [6, 'test6', 'GS', 1, 0, 0, 1, 'old invalid 6', NULL], [7, 'test7', 'M', 1, 0, 1, 1, 'old invalid 7', NULL], [8, 'test8', 'M', 1, 0, 1, 1, 'old invalid 8', NULL]]) electorate_registry = LinzElectoralDistrictRegistry( source_layer=electorate_layer, source_field='electorate_id', title_field='code', electorate_type='GN', quota_layer=quota_layer) task = ValidationTask(task_name='', electorate_registry=electorate_registry, meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1, task='GS') self.assertTrue(task.run()) self.assertEqual(len(task.results), 7) self.assertEqual(task.results[0][ValidationTask.ELECTORATE_ID], 4) self.assertEqual(task.results[0][ValidationTask.ELECTORATE_NAME], 'test4') self.assertEqual(task.results[0][ValidationTask.ERROR], 'Outside quota tolerance') self.assertEqual(task.results[1][ValidationTask.ELECTORATE_ID], 4) self.assertEqual(task.results[1][ValidationTask.ELECTORATE_NAME], 'test4') self.assertEqual(task.results[1][ValidationTask.ERROR], 'Electorate has less parts than expected') self.assertEqual(task.results[2][ValidationTask.ELECTORATE_ID], 5) self.assertEqual(task.results[2][ValidationTask.ELECTORATE_NAME], 'test5') self.assertEqual(task.results[2][ValidationTask.ERROR], 'Outside quota tolerance') self.assertEqual(task.results[3][ValidationTask.ELECTORATE_ID], 5) self.assertEqual(task.results[3][ValidationTask.ELECTORATE_NAME], 'test5') self.assertEqual(task.results[3][ValidationTask.ERROR], 'Electorate is non-contiguous') self.assertEqual( task.results[3][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'MultiPoint ((8 9),(10 11))') self.assertEqual(task.results[4][ValidationTask.ELECTORATE_ID], 5) self.assertEqual(task.results[4][ValidationTask.ELECTORATE_NAME], 'test5') self.assertEqual(task.results[4][ValidationTask.ERROR], 'Contiguous part 1') self.assertEqual( task.results[4][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'Point (8 9)') self.assertEqual(task.results[5][ValidationTask.ELECTORATE_ID], 5) self.assertEqual(task.results[5][ValidationTask.ELECTORATE_NAME], 'test5') self.assertEqual(task.results[5][ValidationTask.ERROR], 'Contiguous part 2') self.assertEqual( task.results[5][ValidationTask.ELECTORATE_GEOMETRY].asWkt(0), 'Point (10 11)') self.assertEqual(task.results[6][ValidationTask.ELECTORATE_ID], 6) self.assertEqual(task.results[6][ValidationTask.ELECTORATE_NAME], 'test6') self.assertEqual(task.results[6][ValidationTask.ERROR], 'Outside quota tolerance') self.assertEqual([ f.attributes()[:9] for f in electorate_layer.getFeatures() ], [[1, 'test1', 'GN', 58900, 1, 0, 0, NULL, NULL], [ 2, 'test2', 'GN', 1, 0, 0, 1, 'Electorate is non-contiguous', NULL ], [3, 'test3', 'GN', 1, 0, 0, 1, 'Outside quota tolerance', NULL], [ 4, 'test4', 'GS', 1, 0, 0, 1, 'Electorate has less parts than expected', NULL ], [ 5, 'test5', 'GS', 1, 0, 0, 1, 'Electorate is non-contiguous', NULL ], [6, 'test6', 'GS', 1, 0, 0, 1, 'Outside quota tolerance', NULL], [7, 'test7', 'M', 1, 0, 1, 1, 'old invalid 7', NULL], [8, 'test8', 'M', 1, 0, 1, 1, 'old invalid 8', NULL]]) electorate_registry = LinzElectoralDistrictRegistry( source_layer=electorate_layer, source_field='electorate_id', title_field='code', electorate_type='M', quota_layer=quota_layer) task = ValidationTask(task_name='', electorate_registry=electorate_registry, meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1, task='M') self.assertTrue(task.run()) self.assertEqual(len(task.results), 1) self.assertEqual(task.results[0][ValidationTask.ELECTORATE_ID], 7) self.assertEqual(task.results[0][ValidationTask.ELECTORATE_NAME], 'test7') self.assertEqual(task.results[0][ValidationTask.ERROR], 'Deprecated electorate has meshblocks assigned') self.assertEqual([ f.attributes()[:9] for f in electorate_layer.getFeatures() ], [[1, 'test1', 'GN', 58900, 1, 0, 0, NULL, NULL], [ 2, 'test2', 'GN', 1, 0, 0, 1, 'Electorate is non-contiguous', NULL ], [3, 'test3', 'GN', 1, 0, 0, 1, 'Outside quota tolerance', NULL], [ 4, 'test4', 'GS', 1, 0, 0, 1, 'Electorate has less parts than expected', NULL ], [ 5, 'test5', 'GS', 1, 0, 0, 1, 'Electorate is non-contiguous', NULL ], [6, 'test6', 'GS', 1, 0, 0, 1, 'Outside quota tolerance', NULL], [ 7, 'test7', 'M', 1, 0, 1, 1, 'Deprecated electorate has meshblocks assigned', NULL ], [8, 'test8', 'M', 0, 1, 1, 0, NULL, NULL]])
def testSwitchTask(self): # pylint: disable=too-many-locals, too-many-statements """ Test scenario switch task """ layer = make_scenario_layer() mb_electorate_layer = QgsVectorLayer( "NoGeometry?field=id:int&field=scenario_id:int&field=meshblock_number:int&field=gn_id:int&field=gs_id:int&field=m_id:int", "source", "memory") f = QgsFeature() f.setAttributes([1, 1, 11, 1, 0, 7]) f2 = QgsFeature() f2.setAttributes([2, 1, 12, 2, 0, 7]) f3 = QgsFeature() f3.setAttributes([3, 1, 13, 2, 0, 7]) f4 = QgsFeature() f4.setAttributes([4, 1, 14, 0, 4, 8]) f5 = QgsFeature() f5.setAttributes([5, 1, 15, 0, 5, 8]) f6 = QgsFeature() f6.setAttributes([6, 1, 16, 0, 5, 8]) f7 = QgsFeature() f7.setAttributes([7, 2, 11, 2, 0, 7]) f8 = QgsFeature() f8.setAttributes([8, 2, 12, 2, 0, 8]) f9 = QgsFeature() f9.setAttributes([9, 2, 13, 3, 0, 7]) f10 = QgsFeature() f10.setAttributes([10, 2, 14, 0, 5, 8]) f11 = QgsFeature() f11.setAttributes([11, 2, 15, 0, 4, 7]) f12 = QgsFeature() f12.setAttributes([12, 2, 16, 0, 4, 8]) mb_electorate_layer.dataProvider().addFeatures( [f, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12]) reg = ScenarioRegistry(source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer) electorate_layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=electorate_id:int&field=code:string&field=type:string&field=estimated_pop:int&field=scenario_id:int&field=invalid:int&field=invalid_reason:string&field=name:string&field=stats_nz_pop:int&field=stats_nz_var_20:int&field=stats_nz_var_23:int", "source", "memory") f = QgsFeature() f.setAttributes( [1, "test1", 'GN', -1, 0, 1, 'old invalid', NULL, 1111, 11, -11]) f2 = QgsFeature() f2.setAttributes( [2, "test2", 'GN', -1, 0, 1, 'old invalid 2', NULL, 1112, 12, -12]) f3 = QgsFeature() f3.setAttributes( [3, "test3", 'GN', -1, 0, 1, 'old invalid 3', NULL, 1113, 13, -13]) f4 = QgsFeature() f4.setAttributes( [4, "test4", 'GS', -1, 0, 1, 'old invalid 4', NULL, 1114, 14, -14]) f5 = QgsFeature() f5.setAttributes( [5, "test5", 'GS', -1, 0, 1, 'old invalid 5', NULL, 1115, 15, -15]) f6 = QgsFeature() f6.setAttributes( [6, "test6", 'GS', -1, 0, 1, 'old invalid 6', NULL, 1116, 16, -16]) f7 = QgsFeature() f7.setAttributes( [7, "test7", 'M', -1, 0, 1, 'old invalid 7', NULL, 1117, 17, -17]) f8 = QgsFeature() f8.setAttributes( [8, "test8", 'M', -1, 0, 1, 'old invalid 8', NULL, 1118, 18, -18]) electorate_layer.dataProvider().addFeatures( [f, f2, f3, f4, f5, f6, f7, f8]) meshblock_layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=MeshblockNumber:string&field=offline_pop_m:int&field=offline_pop_gn:int&field=offline_pop_gs:int&field=staged_electorate:int&field=offshore:int", "source", "memory") f = QgsFeature() f.setAttributes(["11", 5, 11, 0]) f.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(1, 2))) f2 = QgsFeature() f2.setAttributes(["12", 6, 12, 0]) f2.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(2, 3))) f3 = QgsFeature() f3.setAttributes(["13", 7, 13, 0]) f3.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(4, 5))) f4 = QgsFeature() f4.setAttributes(["14", 8, 0, 20]) f4.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(6, 7))) f5 = QgsFeature() f5.setAttributes(["15", 9, 0, 30]) f5.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(8, 9))) f6 = QgsFeature() f6.setAttributes(["16", 10, 0, 40]) f6.setGeometry(QgsGeometry.fromPointXY(QgsPointXY(10, 11))) meshblock_layer.dataProvider().addFeatures([f, f2, f3, f4, f5, f6]) task = ScenarioSwitchTask( task_name='', electorate_layer=electorate_layer, meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1) self.assertTrue(task.run()) self.assertEqual( [f.attributes() for f in electorate_layer.getFeatures()], [[1, 'test1', 'GN', 11, 1, NULL, None, NULL, NULL, NULL, NULL], [2, 'test2', 'GN', 25, 1, NULL, None, NULL, NULL, NULL, NULL], [3, 'test3', 'GN', 0, 1, NULL, None, NULL, NULL, NULL, NULL], [4, 'test4', 'GS', 20, 1, NULL, None, NULL, NULL, NULL, NULL], [5, 'test5', 'GS', 70, 1, NULL, None, NULL, NULL, NULL, NULL], [6, 'test6', 'GS', 0, 1, NULL, None, NULL, NULL, NULL, NULL], [7, 'test7', 'M', 18, 1, NULL, None, NULL, NULL, NULL, NULL], [8, 'test8', 'M', 27, 1, NULL, None, NULL, NULL, NULL, NULL]]) self.assertEqual( [f.geometry().asWkt() for f in electorate_layer.getFeatures()], [ 'Point (1 2)', 'MultiPoint ((2 3),(4 5))', 'GeometryCollection ()', 'Point (6 7)', 'MultiPoint ((8 9),(10 11))', 'GeometryCollection ()', 'MultiPoint ((1 2),(2 3),(4 5))', 'MultiPoint ((6 7),(8 9),(10 11))' ]) task = UpdateStagedElectoratesTask( task_name='', meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1, task='GN') self.assertTrue(task.run()) self.assertEqual( [f['staged_electorate'] for f in meshblock_layer.getFeatures()], [1, 2, 2, 0, 0, 0]) task = UpdateStagedElectoratesTask( task_name='', meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1, task='M') self.assertTrue(task.run()) self.assertEqual( [f['staged_electorate'] for f in meshblock_layer.getFeatures()], [7, 7, 7, 8, 8, 8]) task = ScenarioSwitchTask( task_name='', electorate_layer=electorate_layer, meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=2) self.assertTrue(task.run()) self.assertEqual( [f.attributes() for f in electorate_layer.getFeatures()], [[1, 'test1', 'GN', 0, 2, NULL, None, NULL, NULL, NULL, NULL], [2, 'test2', 'GN', 23, 2, NULL, None, NULL, NULL, NULL, NULL], [3, 'test3', 'GN', 13, 2, NULL, None, NULL, NULL, NULL, NULL], [4, 'test4', 'GS', 70, 2, NULL, None, NULL, NULL, NULL, NULL], [5, 'test5', 'GS', 20, 2, NULL, None, NULL, NULL, NULL, NULL], [6, 'test6', 'GS', 0, 2, NULL, None, NULL, NULL, NULL, NULL], [7, 'test7', 'M', 21, 2, NULL, None, NULL, NULL, NULL, NULL], [8, 'test8', 'M', 24, 2, NULL, None, NULL, NULL, NULL, NULL]]) self.assertEqual( [f.geometry().asWkt() for f in electorate_layer.getFeatures()], [ 'GeometryCollection ()', 'MultiPoint ((1 2),(2 3))', 'Point (4 5)', 'MultiPoint ((8 9),(10 11))', 'Point (6 7)', 'GeometryCollection ()', 'MultiPoint ((1 2),(4 5),(8 9))', 'MultiPoint ((2 3),(6 7),(10 11))' ]) task = UpdateStagedElectoratesTask( task_name='', meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=2, task='GN') self.assertTrue(task.run()) self.assertEqual( [f['staged_electorate'] for f in meshblock_layer.getFeatures()], [2, 2, 3, 0, 0, 0]) task = UpdateStagedElectoratesTask( task_name='', meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=2, task='M') self.assertTrue(task.run()) self.assertEqual( [f['staged_electorate'] for f in meshblock_layer.getFeatures()], [7, 8, 7, 8, 7, 8])
def testExportTask(self): # pylint: disable=too-many-locals, too-many-statements """ Test export task """ layer = make_scenario_layer() mb_electorate_layer = QgsVectorLayer( "NoGeometry?field=id:int&field=scenario_id:int&field=meshblock_number:int&field=gn_id:int&field=gs_id:int&field=m_id:int", "source", "memory") f = QgsFeature() f.setAttributes([1, 1, 11, 1, 0, 7]) f2 = QgsFeature() f2.setAttributes([2, 1, 12, 2, 0, 7]) f3 = QgsFeature() f3.setAttributes([3, 1, 13, 2, 0, 7]) f4 = QgsFeature() f4.setAttributes([4, 1, 14, 3, 4, 8]) f5 = QgsFeature() f5.setAttributes([5, 1, 15, 0, 5, 8]) f6 = QgsFeature() f6.setAttributes([6, 1, 16, 0, 5, 8]) mb_electorate_layer.dataProvider().addFeatures([f, f2, f3, f4, f5, f6]) reg = ScenarioRegistry( source_layer=layer, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer ) electorate_layer = QgsVectorLayer( "Point?crs=EPSG:4326&field=electorate_id:int&field=code:string&field=type:string&field=estimated_pop:int&field=scenario_id:int&field=deprecated:int&field=invalid:int&field=invalid_reason:string&field=name:string&field=stats_nz_pop:int&field=stats_nz_var_20:int&field=stats_nz_var_23:int", "source", "memory") f = QgsFeature() f.setAttributes([1, "test1", 'GN', 1, 0, 0, 1, 'old invalid']) f2 = QgsFeature() f2.setAttributes([2, "test2", 'GN', 1, 0, 0, 1, 'old invalid 2']) f3 = QgsFeature() f3.setAttributes([3, "test3", 'GN', 1, 0, 0, 1, 'old invalid 3']) f4 = QgsFeature() f4.setAttributes([4, "test4", 'GS', 1, 0, 0, 1, 'old invalid 4']) f5 = QgsFeature() f5.setAttributes([5, "test5", 'GS', 1, 0, 0, 1, 'old invalid 5']) f6 = QgsFeature() f6.setAttributes([6, "test6", 'GS', 1, 0, 0, 1, 'old invalid 6']) f7 = QgsFeature() f7.setAttributes([7, "test7", 'M', 1, 0, 0, 1, 'old invalid 7']) f8 = QgsFeature() f8.setAttributes([8, "test8", 'M', 1, 0, 0, 1, 'old invalid 8']) electorate_layer.dataProvider().addFeatures([f, f2, f3, f4, f5, f6, f7, f8]) meshblock_layer = QgsVectorLayer( "Polygon?crs=EPSG:4326&field=MeshblockNumber:string&field=offline_pop_m:int&field=offline_pop_gn:int&field=offline_pop_gs:int&field=staged_electorate:int&field=offshore:int", "source", "memory") f = QgsFeature() f.setAttributes(["11", 5, 58900, 0]) f.setGeometry(QgsGeometry.fromWkt('Polygon((1 1, 2 1, 2 2, 1 2, 1 1))')) f2 = QgsFeature() f2.setAttributes(["12", 6, 57000, 0]) f2.setGeometry(QgsGeometry.fromWkt('Polygon((1 1, 2 1, 2 2, 1 2, 1 1))')) f3 = QgsFeature() f3.setAttributes(["13", 7, 2000, 0]) f3.setGeometry(QgsGeometry.fromWkt('Polygon((1 1, 2 1, 2 2, 1 2, 1 1))')) f4 = QgsFeature() f4.setAttributes(["14", 8, 0, 20]) f4.setGeometry(QgsGeometry.fromWkt('Polygon((1 1, 2 1, 2 2, 1 2, 1 1))')) f5 = QgsFeature() f5.setAttributes(["15", 9, 0, 30]) f5.setGeometry(QgsGeometry.fromWkt('Polygon((1 1, 2 1, 2 2, 1 2, 1 1))')) f6 = QgsFeature() f6.setAttributes(["16", 10, 0, 40]) f6.setGeometry(QgsGeometry.fromWkt('Polygon((1 1, 2 1, 2 2, 1 2, 1 1))')) self.assertTrue(meshblock_layer.dataProvider().addFeatures([f, f2, f3, f4, f5, f6])) quota_layer = make_quota_layer() user_log_layer = make_user_log_layer() f = QgsFeature() f.setAttributes([1, NULL, 'user', 'v1', 1, '11', 'GN', 1, 2]) user_log_layer.dataProvider().addFeature(f) electorate_registry = LinzElectoralDistrictRegistry(source_layer=electorate_layer, source_field='electorate_id', title_field='code', electorate_type='GN', quota_layer=quota_layer) out_file = '/tmp/test.gpkg' task = ExportTask(task_name='', dest_file=out_file, electorate_registry=electorate_registry, meshblock_layer=meshblock_layer, meshblock_number_field_name='MeshblockNumber', scenario_registry=reg, scenario=1, user_log_layer=user_log_layer) self.assertTrue(task.run(), task.message) out_electorate_layer = QgsVectorLayer('{}|layername=electorates'.format(out_file), 'electorates', 'ogr') self.assertTrue(out_electorate_layer.isValid()) self.assertEqual([f.attributes() for f in out_electorate_layer.getFeatures()], [[1, 'GN', 'test1', NULL], [2, 'GN', 'test2', NULL], [3, 'GN', 'test3', NULL], [4, 'GS', 'test4', NULL], [5, 'GS', 'test5', NULL], [6, 'M', 'test7', NULL], [7, 'M', 'test8', NULL]]) self.assertEqual([f.geometry().asWkt() for f in out_electorate_layer.getFeatures()], ['Polygon ((1 1, 2 1, 2 2, 1 2, 1 1))', 'Polygon ((2 1, 1 1, 1 2, 2 2, 2 1))', 'Polygon ((1 1, 2 1, 2 2, 1 2, 1 1))', 'Polygon ((1 1, 2 1, 2 2, 1 2, 1 1))', 'Polygon ((2 1, 1 1, 1 2, 2 2, 2 1))', 'Polygon ((2 1, 1 1, 1 2, 2 2, 2 1))', 'Polygon ((2 1, 1 1, 1 2, 2 2, 2 1))']) out_mb_layer = QgsVectorLayer('{}|layername=meshblocks'.format(out_file), 'electorates', 'ogr') self.assertTrue(out_mb_layer.isValid()) self.assertEqual([f.attributes() for f in out_mb_layer.getFeatures()], [[1, 11, 'test1', NULL, 'test7'], [2, 12, 'test2', NULL, 'test7'], [3, 13, 'test2', NULL, 'test7'], [4, 14, 'test3', 'test4', 'test8'], [5, 15, NULL, 'test5', 'test8'], [6, 16, NULL, 'test5', 'test8']]) out_log_layer = QgsVectorLayer('{}|layername=user_log'.format(out_file), 'electorates', 'ogr') self.assertTrue(out_log_layer.isValid()) self.assertEqual([f.attributes() for f in out_log_layer.getFeatures()], [[1, 1, NULL, 'user', 'v1', 1, '11', 'GN', 1, 2]])
def testCopyScenarios(self): """ Test copying scenarios between registries """ layer1 = make_scenario_layer() mb_electorate_layer1 = make_meshblock_electorate_layer() reg1 = ScenarioRegistry( source_layer=layer1, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer1) layer2 = make_scenario_layer() layer2.dataProvider().truncate() mb_electorate_layer2 = make_meshblock_electorate_layer() mb_electorate_layer2.dataProvider().truncate() reg2 = ScenarioRegistry( source_layer=layer2, id_field='id', name_field='name', meshblock_electorate_layer=mb_electorate_layer2) self.assertEqual(layer2.featureCount(), 0) self.assertEqual(mb_electorate_layer2.featureCount(), 0) res, error = reg2.import_scenario_from_other_registry( source_registry=reg1, source_scenario_id=-1, new_scenario_name='copied scenario') self.assertFalse(res) self.assertIn('does not exist ', error) # good params res, error = reg2.import_scenario_from_other_registry( source_registry=reg1, source_scenario_id=1, new_scenario_name='copied scenario') self.assertTrue(res) self.assertFalse(error) self.assertEqual(layer2.featureCount(), 1) self.assertEqual(mb_electorate_layer2.featureCount(), 2) f = [f for f in layer2.getFeatures()][-1] self.assertEqual(f[0], res) self.assertEqual(f[1], 'copied scenario') self.assertEqual(f[2].date(), QDate(2018, 6, 4)) self.assertEqual(f[3], 'user 1') f = [f.attributes() for f in mb_electorate_layer2.getFeatures()] self.assertEqual(f, [[3, res, 0, 'c', 'z'], [4, res, 1, 'd', 'zz']]) res2, error = reg2.import_scenario_from_other_registry( source_registry=reg1, source_scenario_id=2, new_scenario_name='copied scenario 2') self.assertTrue(res2) self.assertFalse(error) self.assertEqual(layer2.featureCount(), 2) self.assertEqual(mb_electorate_layer2.featureCount(), 4) f = [f for f in layer2.getFeatures()][-1] self.assertEqual(f[0], res2) self.assertEqual(f[1], 'copied scenario 2') self.assertEqual(f[2].date(), QDate(2018, 7, 5)) self.assertEqual(f[3], 'user 2') f = [f.attributes() for f in mb_electorate_layer2.getFeatures()] self.assertEqual(f, [[3, res, 0, 'c', 'z'], [4, res, 1, 'd', 'zz'], [1, res2, 0, 'a', 'x'], [2, res2, 1, 'b', 'y']]) # dupe name res, error = reg2.import_scenario_from_other_registry( source_registry=reg1, source_scenario_id=-1, new_scenario_name='copied scenario') self.assertFalse(res) self.assertIn('already exists', error)