diff --git a/test/test_survey_publisher_legacy_excel.py b/test/test_survey_publisher_legacy_excel.py new file mode 100644 index 0000000000000000000000000000000000000000..57c936f21af553c6214a35defac709f61d0244b7 --- /dev/null +++ b/test/test_survey_publisher_legacy_excel.py @@ -0,0 +1,117 @@ +import os +import openpyxl + +from sqlalchemy import select, func +from compendium_v2 import db +from compendium_v2.db import presentation_models +from compendium_v2.publishers.survey_publisher_legacy_excel import _cli + + +def test_excel_publisher(app_with_survey_db, mocker, nren_services): + nren_services(app_with_survey_db) + EXCEL_FILE_ORGANISATION = openpyxl.load_workbook(os.path.join(os.path.dirname( + __file__), "data", "2021_Organisation_DataSeries.xlsx"), data_only=True, read_only=True) + EXCEL_FILE_USERS = openpyxl.load_workbook(os.path.join(os.path.dirname( + __file__), "data", "2022_Connected_Users_DataSeries.xlsx"), data_only=True, read_only=True) + EXCEL_FILE_NETWORKS = openpyxl.load_workbook(os.path.join(os.path.dirname( + __file__), "data", "2022_Networks_DataSeries.xlsx"), data_only=True, read_only=True) + EXCEL_FILE_NREN_SERVICES = openpyxl.load_workbook(os.path.join(os.path.dirname( + __file__), "data", "NREN-Services-prefills_2023_Recovered.xlsx"), data_only=True, read_only=True) + mocker.patch('compendium_v2.publishers.excel_parser.EXCEL_FILE_ORGANISATION', EXCEL_FILE_ORGANISATION) + mocker.patch('compendium_v2.publishers.excel_parser.EXCEL_FILE_USERS', EXCEL_FILE_USERS) + mocker.patch('compendium_v2.publishers.excel_parser.EXCEL_FILE_NETWORKS', EXCEL_FILE_NETWORKS) + mocker.patch('compendium_v2.publishers.excel_parser.EXCEL_FILE_NREN_SERVICES', EXCEL_FILE_NREN_SERVICES) + + with app_with_survey_db.app_context(): + nren_names = ['SURF', 'KIFU', 'University of Malta', 'ASNET-AM', 'SIKT', 'LAT', 'RASH', 'AzScienceNet', 'GRNET', + 'CSC', 'PSNC'] + db.session.add_all([presentation_models.NREN(name=nren_name, country='country') for nren_name in nren_names]) + db.session.commit() + + _cli(app_with_survey_db) + + with app_with_survey_db.app_context(): + budget_count = db.session.scalar(select(func.count(presentation_models.BudgetEntry.year))) + assert budget_count + funding_source_count = db.session.scalar(select(func.count(presentation_models.FundingSource.year))) + assert funding_source_count + charging_structure_count = db.session.scalar(select(func.count(presentation_models.ChargingStructure.year))) + assert charging_structure_count + staff_data = db.session.scalars(select(presentation_models.NrenStaff).order_by( + presentation_models.NrenStaff.year.asc()) + ).all() + + # data should only be saved for the NRENs we have saved in the database + staff_data_nrens = set([staff.nren.name for staff in staff_data]) + assert len(staff_data_nrens) == len(nren_names) - 1 # no UoM data + + kifu_data = [staff for staff in staff_data if staff.nren.name == 'KIFU'] + # check that the data is saved correctly for KIFU, it should be OK for the rest then.. + assert len(kifu_data) == 6 + + assert kifu_data[0].year == 2016 + assert kifu_data[0].permanent_fte == 100 + assert kifu_data[0].subcontracted_fte == 2 + assert kifu_data[0].technical_fte == 0 + assert kifu_data[0].non_technical_fte == 0 + + assert kifu_data[1].year == 2017 + assert kifu_data[1].permanent_fte == 80 + assert kifu_data[1].subcontracted_fte == 2 + assert kifu_data[1].technical_fte == 0 + assert kifu_data[1].non_technical_fte == 0 + + assert kifu_data[2].year == 2018 + assert kifu_data[2].permanent_fte == 80 + assert kifu_data[2].subcontracted_fte == 3 + assert kifu_data[2].technical_fte == 0 + assert kifu_data[2].non_technical_fte == 0 + + assert kifu_data[3].year == 2019 + assert kifu_data[3].permanent_fte == 148 + assert kifu_data[3].subcontracted_fte == 4 + assert kifu_data[3].technical_fte == 117 + assert kifu_data[3].non_technical_fte == 33 + + assert kifu_data[4].year == 2020 + assert kifu_data[4].permanent_fte == 190 + assert kifu_data[4].subcontracted_fte == 3 + assert kifu_data[4].technical_fte == 133 + assert kifu_data[4].non_technical_fte == 60 + + assert kifu_data[5].year == 2021 + assert kifu_data[5].permanent_fte == 178 + assert kifu_data[5].subcontracted_fte == 3 + assert kifu_data[5].technical_fte == 133 + assert kifu_data[5].non_technical_fte == 45 + + ecproject_data = db.session.scalars(select(presentation_models.ECProject)).all() + # test a couple of random entries + surf2017 = [x for x in ecproject_data if x.nren.name == 'SURF' and x.year == 2017] + assert len(surf2017) == 1 + assert surf2017[0].project == 'Asterics and Magic' + + asnetam2018 = [x for x in ecproject_data if x.nren.name == 'ASNET-AM' and x.year == 2018] + assert len(asnetam2018) == 1 + assert asnetam2018[0].project == 'EaPConnect' + + kifu2019 = [x for x in ecproject_data if x.nren.name == 'KIFU' and x.year == 2019] + assert len(kifu2019) == 4 + assert kifu2019[3].project == 'SuperHeroes for Science' + + parent_data = db.session.scalars(select(presentation_models.ParentOrganization)).all() + # test a random entry + asnet2021 = [x for x in parent_data if x.nren.name == 'ASNET-AM' and x.year == 2021] + assert len(asnet2021) == 1 + assert asnet2021[0].organization\ + == 'Institute for Informatics and Automation Problems of the National Academy of Sciences of Armenia' + + service_data = db.session.scalars(select(presentation_models.Service)).all() + assert len(service_data) > 70 + + nren_service_data = db.session.scalars(select(presentation_models.NRENService)).all() + # test a random entry + sikt2022 = [x for x in nren_service_data + if x.nren.name == 'SIKT' and x.year == 2022 and x.service.name == 'Journal access'] + assert len(sikt2022) == 1 + assert sikt2022[0].additional_information.startswith("Sikt negotiates license a") diff --git a/test/test_survey_publisher_old_db_2022.py b/test/test_survey_publisher_old_db_2022.py new file mode 100644 index 0000000000000000000000000000000000000000..ed5e2e5f5fb5c9c1bcff9484e3b49f9e56bc8d3d --- /dev/null +++ b/test/test_survey_publisher_old_db_2022.py @@ -0,0 +1,309 @@ +from sqlalchemy import select + +from compendium_v2.db import db, presentation_model_enums, presentation_models +from compendium_v2.publishers.survey_publisher_old_db_2022 import _cli, FundingSource, \ + StaffQuestion, OrgQuestion, ChargingStructure, ECQuestion + + +def org_data(question): + """ + This function defines test data for the org questions. + + The following data is defined for the appropriate questions as modeled in Compendium: + + nren1,CYNET-CSIRT,cert team + nren1,DFN-CERT,CERT + nren2,Educampus Services,MIS shared services for third level. + nren3,VilniusTech,Technical centre + nren3,KU,Technical centre + nren3,VDU,Technical centre + nren3,VU,Technical centre + nren3,org_data +org_data +org_data +org_data +org_dataKTU,"NOC, administrative authority" + """ + + if question == OrgQuestion.PARENT_ORG_NAME: + return [ + ('nren1', 'Org1'), + ('nren3', 'Org3'), + ] + + if str(question.name).endswith('1_NAME'): + return [ + ('nren1', 'CYNET-CSIRT'), + ('nren2', 'Educampus Services'), + ('nren3', 'VilniusTech'), + ] + + if str(question.name).endswith('2_NAME'): + return [ + ('nren1', 'DFN-CERT'), + ('nren3', 'KU'), + ] + + if str(question.name).endswith('3_NAME'): + return [ + ('nren3', 'VDU'), + ] + + if str(question.name).endswith('4_NAME'): + return [ + ('nren3', 'VU'), + ] + + if str(question.name).endswith('5_NAME'): + return [ + ('nren3', 'KTU'), + ] + + if str(question.name).endswith('1_CHOICE'): + return [ + ('nren1', 'other'), + ('nren2', 'other'), + ('nren3', 'Technical centre'), + ] + + if str(question.name).endswith('2_CHOICE'): + return [ + ('nren1', 'other'), + ('nren3', 'Technical centre'), + ] + + if str(question.name).endswith('3_CHOICE'): + return [ + ('nren3', 'Technical centre'), + ] + + if str(question.name).endswith('4_CHOICE'): + return [ + ('nren3', 'Technical centre'), + ] + + if str(question.name).endswith('5_CHOICE'): + return [ + ('nren3', 'other'), + ] + + if str(question.name).endswith('1_ROLE'): + return [ + ('nren1', 'cert team'), + ('nren2', 'MIS shared services for third level.') + ] + + if str(question.name).endswith('2_ROLE'): + return [ + ('nren1', 'CERT'), + ] + + if str(question.name).endswith('3_ROLE'): + return [] + + if str(question.name).endswith('4_ROLE'): + return [] + + if str(question.name).endswith('5_ROLE'): + return [ + ('nren3', 'NOC, administrative authority') + ] + + +def test_publisher(app_with_survey_db, mocker): + global org_data + + def get_rows_as_tuples(*args, **kwargs): + return [ + ('nren1', '100'), + ('nren2', '200'), + ('nren3', '300'), + ('nren4', 'abcd') + ] + + def funding_source_data(): + yield FundingSource.CLIENT_INSTITUTIONS, [ + ('nren1', '10'), + ('nren2', '80'), + ('nren3', '30'), + ] + yield FundingSource.EUROPEAN_FUNDING, [ + ('nren1', '50'), + ('nren2', '20'), + ('nren3', '30'), + ] + yield FundingSource.OTHER, [ + ('nren1', '40'), + ('nren2', 'abc'), + ('nren3', '30'), + ] + + def question_data(question): + if question == StaffQuestion.NON_TECHNICAL_FTE: + return [ + ('nren1', '10'), + ('nren2', '80'), + ('nren3', '30'), + ] + + if question == StaffQuestion.TECHNICAL_FTE: + return [ + ('nren1', '50'), + ('nren2', '20'), + ('nren3', '30'), + ] + + if question == StaffQuestion.PERMANENT_FTE: + return [ + ('nren1', '60'), + ('nren2', 'abc'), + ('nren3', '30'), + ] + + if question == StaffQuestion.SUBCONTRACTED_FTE: + return [ + ('nren1', '0'), + ('nren2', '0'), + ('nren3', '0'), + ] + if question in OrgQuestion: + return org_data(question) + + if question == ChargingStructure.charging_structure: + return [ + ('nren1', 'We do not charge them directly'), + ('nren2', 'We charge a usage-based fee'), + ('nren3', 'Other'), + ] + + if question in ECQuestion: + return [ + ('nren1', '[""'), + ('nren2', '["project1", "project2"]'), + ('nren3', '["project3"]'), + ] + + def question_id_data(question_id, year): + if question_id in [ + 16469, 16064, 15720, 15305, 14910, 16471, 16066, 15722, 15307, 14912, 16473, 16378, + 16475, 16068, 15724, 15309, 14914, 16477, 16070, 15726, 15311, 14916, 16479, 16072, 15728, 15575, + 16481, 16074, 15730, 15577, 16761]: + return [ + ('nren1', f'www.nren.com/somepolicy{year}.pdf'), + ('nren2', 'policyemail@nren.com'), + ('nren3', 'n.a. online'), + ] + + def institutions_urls_data(question_id): + if question_id == 16507: + return [ + (87483, 'ANA', 2013, "http://www.rash.al/index.php/network/points-of-presence-pop"), + (163286, 'ANA', 2014, "http://www.rash.al/index.php/network/points-of-presence-pop"), + ] + else: + return [] + + mocker.patch('compendium_v2.publishers.survey_publisher_old_db_2022.query_budget', get_rows_as_tuples) + mocker.patch('compendium_v2.publishers.survey_publisher_old_db_2022.query_funding_sources', funding_source_data) + mocker.patch('compendium_v2.publishers.survey_publisher_old_db_2022.query_question', question_data) + mocker.patch('compendium_v2.publishers.survey_publisher_old_db_2022.query_question_id', question_id_data) + mocker.patch('compendium_v2.publishers.survey_publisher_old_db_2022.recursive_query', institutions_urls_data) + + nren_names = ['Nren1', 'Nren2', 'Nren3', 'Nren4', 'SURF', 'KIFU', 'University of Malta', 'ASNET-AM', + 'SIKT', 'LAT', 'RASH', 'AzScienceNet', 'GRNET', 'CSC', 'PSNC'] + with app_with_survey_db.app_context(): + db.session.add_all([presentation_models.NREN(name=nren_name, country='country') for nren_name in nren_names]) + db.session.commit() + + _cli(app_with_survey_db) + + with app_with_survey_db.app_context(): + budgets = db.session.scalars( + select(presentation_models.BudgetEntry).order_by(presentation_models.BudgetEntry.nren_id.asc()) + ).all() + assert len(budgets) == 3 + assert budgets[0].nren.name.lower() == 'nren1' + assert budgets[0].budget == 100 + + funding_sources = db.session.scalars( + select(presentation_models.FundingSource).order_by(presentation_models.FundingSource.nren_id.asc()) + ).all() + assert len(funding_sources) == 2 + assert funding_sources[0].nren.name.lower() == 'nren1' + assert funding_sources[0].client_institutions == 10 + assert funding_sources[0].european_funding == 50 + assert funding_sources[0].other == 40 + + assert funding_sources[1].nren.name.lower() == 'nren2' + assert funding_sources[1].client_institutions == 80 + assert funding_sources[1].european_funding == 20 + assert funding_sources[1].other == 0 + + staff_data = db.session.scalars( + select(presentation_models.NrenStaff).order_by(presentation_models.NrenStaff.nren_id.asc()) + ).all() + + assert len(staff_data) == 1 + assert staff_data[0].nren.name.lower() == 'nren1' + assert staff_data[0].non_technical_fte == 10 + assert staff_data[0].technical_fte == 50 + assert staff_data[0].permanent_fte == 60 + assert staff_data[0].subcontracted_fte == 0 + + _org_data = db.session.scalars( + select(presentation_models.ParentOrganization).order_by( + presentation_models.ParentOrganization.nren_id.asc()) + ).all() + + assert len(_org_data) == 2 + assert _org_data[0].nren.name.lower() == 'nren1' + assert _org_data[0].organization == 'Org1' + + assert _org_data[1].nren.name.lower() == 'nren3' + assert _org_data[1].organization == 'Org3' + + charging_structures = db.session.scalars( + select(presentation_models.ChargingStructure).order_by(presentation_models.ChargingStructure.nren_id.asc()) + ).all() + assert len(charging_structures) == 3 + assert charging_structures[0].nren.name.lower() == 'nren1' + assert charging_structures[0].fee_type == presentation_model_enums.FeeType.no_charge + assert charging_structures[1].nren.name.lower() == 'nren2' + assert charging_structures[1].fee_type == presentation_model_enums.FeeType.usage_based_fee + assert charging_structures[2].nren.name.lower() == 'nren3' + assert charging_structures[2].fee_type == presentation_model_enums.FeeType.other + + _ec_data = db.session.scalars( + select(presentation_models.ECProject).order_by(presentation_models.ECProject.nren_id.asc()) + ).all() + + assert len(_ec_data) == 3 + assert _ec_data[0].nren.name.lower() == 'nren2' + assert _ec_data[0].project == 'project1' + + assert _ec_data[1].nren.name.lower() == 'nren2' + assert _ec_data[1].project == 'project2' + + assert _ec_data[2].nren.name.lower() == 'nren3' + assert _ec_data[2].project == 'project3' + + policy_data = db.session.scalars( + select(presentation_models.Policy).order_by(presentation_models.Policy.nren_id.asc()) + ).all() + policy_data_2020 = [p for p in policy_data if p.year == 2020] + policy_data_2022 = [p for p in policy_data if p.year == 2022] + assert len(policy_data_2020) == 2 + assert len(policy_data_2022) == 2 + assert policy_data_2020[0].strategic_plan == 'www.nren.com/somepolicy2020.pdf' + assert policy_data_2020[1].strategic_plan == 'policyemail@nren.com' + + _institution_urls_data = db.session.scalars( + select(presentation_models.InstitutionURLs).order_by(presentation_models.InstitutionURLs.nren_id.asc()) + ).all() + assert len(_institution_urls_data) == 2 + assert _institution_urls_data[0].nren.name.lower() == 'rash' + assert _institution_urls_data[0].year == 2013 + assert _institution_urls_data[0].urls == ["http://www.rash.al/index.php/network/points-of-presence-pop"] + assert _institution_urls_data[1].nren.name.lower() == 'rash' + assert _institution_urls_data[1].year == 2014 + assert _institution_urls_data[1].urls == ["http://www.rash.al/index.php/network/points-of-presence-pop"]