From b771aae70bcc9ac8ff6f742e49dce497e75e72de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Thor=C3=A9n?= Date: Sat, 4 Jan 2020 16:32:14 +0100 Subject: [PATCH 1/5] Refactor of DAK data handling Updated module dakdata to be more pylint compatible. Added unit test for DAK report. --- .vscode/settings.json | 4 +- dakdata.py | 116 +++++++++++++-------------- excelreport.py | 32 ++++---- ireport.py | 10 +-- jsonreport.py | 63 ++------------- start.py | 30 +++---- templates/dak.xml | 50 ++++++------ tests/__init__.py | 6 ++ tests/dak_test.py | 144 ++++++++++++++++++++++++++++++++++ tests/expected/dak_export.xml | 117 +++++++++++++++++++++++++++ 10 files changed, 393 insertions(+), 179 deletions(-) create mode 100644 tests/__init__.py create mode 100644 tests/dak_test.py create mode 100644 tests/expected/dak_export.xml diff --git a/.vscode/settings.json b/.vscode/settings.json index 9452402..1eadde3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -12,9 +12,9 @@ "python.testing.unittestArgs": [ "-v", "-s", - ".", + "./tests", "-p", - "*test.py" + "*_test.py" ], "python.testing.pytestEnabled": false, "python.testing.nosetestsEnabled": false, diff --git a/dakdata.py b/dakdata.py index 594aa90..4488c77 100644 --- a/dakdata.py +++ b/dakdata.py @@ -1,93 +1,87 @@ # -*- coding: utf-8 -*- -import datetime - -# http://www.sverigesforeningssystem.se/dak-formatet/vad-ar-dak/ - - -class Deltagare: - def __init__(self, id, Foernamn, Efternamn, Personnummer, ledare, epost="", mobilNr="", postnummer=""): - self.id = id - self.Foernamn = Foernamn - self.Efternamn = Efternamn - self.Personnummer = Personnummer - self.Ledare = ledare - self.Epost = epost - self.MobilNr = mobilNr - self.Postnummer = postnummer +""" +Module for exporting data according to DAC format. - def IsFemale(self): - return False if int(self.Personnummer[-2])&1 == 1 else True +http://www.sverigesforeningssystem.se/dak-formatet/vad-ar-dak/ +""" +import datetime - def AgeThisSemester(self, semester): - return int(self.Personnummer[0:4]) - semester.year +class Deltagare(object): # pylint: disable=wrong-import-position + def __init__(self, uid, foernamn, efternamn, personnummer, ledare, epost="", mobil_nr="", postnummer=""): + self.uid = uid + self.foernamn = foernamn + self.efternamn = efternamn + self.personnummer = personnummer + self.ledare = ledare + self.epost = epost + self.mobil_nr = mobil_nr + self.postnummer = postnummer + + def is_female(self): + "Return True if the person is female" + return False if int(self.personnummer[-2])&1 == 1 else True + + def age_this_semester(self, semester): + "Is the person aget this semester" + return int(self.personnummer[0:4]) - semester.year def __eq__(self, other): - return self.Personnummer == other.Personnummer + return self.personnummer == other.personnummer def __hash__(self): - return hash(self.Personnummer) + return hash(self.personnummer) -class Sammankomst: - kod = "" - datum = None - duration = 90 - Aktivitet = "Moete" # OBS en av: Traening, Match, Moete, Oevrigt - deltagare = [] - ledare = [] +class Sammankomst(object): - def __init__(self, kod, datum, duration, Aktivitet): + def __init__(self, kod, datum, duration, aktivitet): self.kod = kod self.datum = datum self.duration = duration - self.Aktivitet = Aktivitet + self.aktivitet = aktivitet # OBS en av: Traening, Match, Moete, Oevrigt self.deltagare = [] self.ledare = [] - def GetDateString(self, formatString='%Y-%m-%d'): - return self.datum.strftime(formatString) + def get_date_string(self, format_string='%Y-%m-%d'): + return self.datum.strftime(format_string) - def GetStartTimeString(self, formatString='%H:%M:%S'): - return self.datum.strftime(formatString) + def get_start_time_string(self, format_string='%H:%M:%S'): + return self.datum.strftime(format_string) - def GetStopTimeString(self, formatString='%H:%M:%S'): - maxEndTime = self.datum.replace(hour=23,minute=59,second=59) + def get_stop_time_string(self, format_string='%H:%M:%S'): + max_end_time = self.datum.replace(hour=23, minute=59, second=59) endtime = self.datum + datetime.timedelta(minutes=self.duration) - if endtime > maxEndTime: - endtime = maxEndTime # limit to the current day (to keep Stop time after Start time) - return endtime.strftime(formatString) + if endtime > max_end_time: + endtime = max_end_time # limit to the current day (to keep Stop time after Start time) + return endtime.strftime(format_string) - def GetAllPersons(self): + def get_all_persons(self): return self.ledare + self.deltagare - def IsPersonAttending(self, person): - for p in self.GetAllPersons(): - if p.Personnummer == person.Personnummer: - return p.Attending + def is_person_attending(self, person): + for person in self.get_all_persons(): + if person.Personnummer == person.Personnummer: + return person.Attending return False -class Narvarokort: - NaervarokortNummer="" - Sammankomster = [] - Aktivitet="Moete" - Lokal="Scouthuset" - NamnPaaKort="" - deltagare = [] - ledare = [] - +class Narvarokort(object): def __init__(self): self.deltagare = [] self.ledare = [] - self.Sammankomster = [] - + # json export do not like the name sammankomster. + self.Sammankomster = [] # pylint: disable=invalid-name + self.naervarokort_nummer = "" + self.lokal = "Scouthuset" + self.namn_paa_kort = "" + self.aktivitet = "" # OBS en av: Traening, Match, Moete, Oevrigt -class DakData: - kommunID = "" - foreningsID = "" - foereningsNamn=u"" - organisationsnummer="" - kort = None +class DakData(object): + "Main container for DAK data" def __init__(self): self.kort = Narvarokort() + self.kommun_id = "" + self.forenings_id = "" + self.foerenings_namn = "" + self.organisationsnummer = "" diff --git a/excelreport.py b/excelreport.py index 72c2e86..4cc2703 100644 --- a/excelreport.py +++ b/excelreport.py @@ -13,11 +13,11 @@ def getFilledInExcelSpreadsheet(self): numPersonRows = 64 startRowPersons = 13 ws = workbook.worksheets[0] - ws['E1'] = self.dak.kort.NaervarokortNummer + ws['E1'] = self.dak.kort.naervarokort_nummer ws['I1'] = self.semester.year - ws['D2'] = self.dak.kort.NamnPaaKort + ws['D2'] = self.dak.kort.namn_paa_kort ws['D3'] = "Scouting" - ws['D4'] = self.dak.kort.Lokal + ws['D4'] = self.dak.kort.lokal if self.semester.ht: ws['C7'] = 'X' else: @@ -29,11 +29,11 @@ def getFilledInExcelSpreadsheet(self): for index, sammankomst in enumerate(self.dak.kort.Sammankomster): aktivitetColumn = 11+index - ws.cell(row=2, column=aktivitetColumn).value = sammankomst.Aktivitet - ws.cell(row=7, column=aktivitetColumn).value = sammankomst.GetStartTimeString('%H') - ws.cell(row=9, column=aktivitetColumn).value = sammankomst.GetStopTimeString('%H') - ws.cell(row=10, column=aktivitetColumn).value = sammankomst.GetDateString('%m') - ws.cell(row=11, column=aktivitetColumn).value = sammankomst.GetDateString('%d') + ws.cell(row=2, column=aktivitetColumn).value = sammankomst.aktivitet + ws.cell(row=7, column=aktivitetColumn).value = sammankomst.get_start_time_string('%H') + ws.cell(row=9, column=aktivitetColumn).value = sammankomst.get_stop_time_string('%H') + ws.cell(row=10, column=aktivitetColumn).value = sammankomst.get_date_string('%m') + ws.cell(row=11, column=aktivitetColumn).value = sammankomst.get_date_string('%d') for deltagareindex, deltagaren in enumerate(self.dak.kort.deltagare): if deltagaren in sammankomst.deltagare: ws.cell(row=startRowPersons+deltagareindex, column=aktivitetColumn).value = 1 @@ -44,18 +44,18 @@ def getFilledInExcelSpreadsheet(self): for index, deltagaren in enumerate(self.dak.kort.deltagare): deltagarenRow = startRowPersons+index - ws.cell(row=deltagarenRow, column=2).value = deltagaren.Foernamn + " " + deltagaren.Efternamn - ws.cell(row=deltagarenRow, column=8).value = 'K' if deltagaren.IsFemale() else 'M' - ws.cell(row=deltagarenRow, column=9).value = deltagaren.Postnummer - ws.cell(row=deltagarenRow, column=10).value = deltagaren.Personnummer[0:8] + ws.cell(row=deltagarenRow, column=2).value = deltagaren.foernamn + " " + deltagaren.efternamn + ws.cell(row=deltagarenRow, column=8).value = 'K' if deltagaren.is_female() else 'M' + ws.cell(row=deltagarenRow, column=9).value = deltagaren.postnummer + ws.cell(row=deltagarenRow, column=10).value = deltagaren.personnummer[0:8] for index, ledaren in enumerate(self.dak.kort.ledare): ledarenRow = startRowPersons+index+deltagareCount ws.cell(row=ledarenRow, column=2).value = "Ledare:" - ws.cell(row=ledarenRow, column=3).value = ledaren.Foernamn + " " + ledaren.Efternamn - ws.cell(row=ledarenRow, column=8).value = 'K' if ledaren.IsFemale() else 'M' - ws.cell(row=ledarenRow, column=9).value = ledaren.Postnummer - ws.cell(row=ledarenRow, column=10).value = ledaren.Personnummer[0:8] + ws.cell(row=ledarenRow, column=3).value = ledaren.foernamn + " " + ledaren.efternamn + ws.cell(row=ledarenRow, column=8).value = 'K' if ledaren.is_female() else 'M' + ws.cell(row=ledarenRow, column=9).value = ledaren.postnummer + ws.cell(row=ledarenRow, column=10).value = ledaren.personnummer[0:8] bytesIO = io.BytesIO() workbook.save(bytesIO) diff --git a/ireport.py b/ireport.py index 3ddf7af..5773802 100644 --- a/ireport.py +++ b/ireport.py @@ -1,20 +1,20 @@ -class IReport: +class IReport(object): """Interface for attendence reports""" def __init__(self, dak, semester): pass - def getUrlName(self): + def get_url_anme(self): """Short name that can be used as a url parameter""" pass - def getMimeType(self): + def get_mime_type(self): """Mime type for this data format.""" pass - def getFilename(self): + def get_filename(self): """Returns a filename for this report.""" pass - def getReportString(self): + def get_report_string(self): """File content data from export.""" pass diff --git a/jsonreport.py b/jsonreport.py index 29d0f83..8f45eaf 100644 --- a/jsonreport.py +++ b/jsonreport.py @@ -1,71 +1,24 @@ # -*- coding: utf-8 -*- - -if __name__ == '__main__': - import sys - sys.path.append('lib') # add lib to path for unit-testing - import json - import jsonpickle -import unittest -import datetime -from dakdata import DakData, Deltagare, Sammankomst from ireport import IReport - class JsonReport(IReport): def __init__(self, dak, semester): + super(JsonReport, self).__init__(dak, semester) self.dak = dak self.semester = semester - def getUrlName(self): + def get_url_anme(self): return "json" - def getMimeType(self): + def get_mime_type(self): return "text/json" - def getReportString(self): - return self.getJson() + def get_report_string(self): + return self.get_json() - def getFilename(self): - return str(self.dak.kort.NamnPaaKort) + '-' + self.semester.getname() + '.json' + def get_filename(self): + return str(self.dak.kort.namn_paa_kort) + '-' + self.semester.getname() + '.json' - def getJson(self): + def get_json(self): return jsonpickle.encode(self.dak) - - -class TestJsonReport(unittest.TestCase): - def createDakData(self): - dak = DakData() - dak.foereningsNamn = u"Test Scoutkår" - dak.foreningsID = "1111" - dak.organisationsnummer = "556677-8899" - dak.kommunID = "0" - dak.kort.NamnPaaKort = "Testavdelning" - dak.kort.NaervarokortNummer = "1" - # - dak.kort.ledare.append(Deltagare("1234", "Adam", "Adamsson", "200501011234", True, "adam@test.com", "12345678", u"Göteborg")) - dak.kort.deltagare.append(Deltagare("1235", "Bertil", "Bertilsson", "198501011234", False, "bertil@test.com", "12345678", u"Göteborg")) - sammankomst = Sammankomst(u"123", datetime.date(2019, 1, 1), 180, u"Möte") - sammankomst.ledare.append(dak.kort.ledare[0]) - sammankomst.deltagare.append(dak.kort.deltagare[0]) - dak.kort.Sammankomster.append(sammankomst) - return dak - - def test_dakexport(self): - dak = self.createDakData() - #semester = Semester(2019, false) # 2019, vt - semester = None - json_report = JsonReport(dak, semester) - stream = json_report.getReportString() - #print(stream) - data = json.loads(stream) - - self.assertEqual(data[u'foereningsNamn'], u"Test Scoutkår") - self.assertEqual(data[u'foreningsID'], u"1111") - self.assertEqual(data[u'kort'][u'NamnPaaKort'], "Testavdelning") - self.assertEqual(data[u'kort'][u'Sammankomster'][0]['deltagare'][0]['id'], "1235") - self.assertEqual(data[u'kort'][u'Sammankomster'][0]['ledare'][0]['id'], "1234") - - -if __name__ == '__main__': - unittest.main() diff --git a/start.py b/start.py index 43777c6..caca5ac 100644 --- a/start.py +++ b/start.py @@ -427,17 +427,17 @@ def show(sgroup_url=None, troop_url=None, key_url=None): if key_url == "dak" or key_url == "excel" or key_url == "json": dak = DakData() - dak.foereningsNamn = scoutgroup.getname() - dak.foreningsID = scoutgroup.foreningsID + dak.foerenings_namn = scoutgroup.getname() + dak.forenings_id = scoutgroup.foreningsID dak.organisationsnummer = scoutgroup.organisationsnummer - dak.kommunID = scoutgroup.kommunID - dak.kort.NamnPaaKort = troop.getname() + dak.kommun_id = scoutgroup.kommunID + dak.kort.namn_paa_kort = troop.getname() # hack generate an "unique" id, if there is none if troop.rapportID == None or troop.rapportID == 0: troop.rapportID = random.randint(1000, 1000000) troop.put() - dak.kort.NaervarokortNummer = str(troop.rapportID) + dak.kort.naervarokort_nummer = str(troop.rapportID) for tp in trooppersons: p = personsDict[tp.person] @@ -447,36 +447,36 @@ def show(sgroup_url=None, troop_url=None, key_url=None): dak.kort.deltagare.append(Deltagare(p.getReportID(), p.firstname, p.lastname, p.getpersonnr(), False, p.email, p.mobile, p.zip_code)) for m in meetings: - sammankomst = Sammankomst(str(m.key.id()[:50]), m.datetime, m.duration, m.getname()) + sammankomsten = Sammankomst(str(m.key.id()[:50]), m.datetime, m.duration, m.getname()) for tp in trooppersons: isAttending = tp.person in m.attendingPersons if isAttending: p = personsDict[tp.person] if tp.leader: - sammankomst.ledare.append(Deltagare(p.getReportID(), p.firstname, p.lastname, p.getpersonnr(), True, p.email, p.mobile, p.zip_code)) + sammankomsten.ledare.append(Deltagare(p.getReportID(), p.firstname, p.lastname, p.getpersonnr(), True, p.email, p.mobile, p.zip_code)) else: - sammankomst.deltagare.append(Deltagare(p.getReportID(), p.firstname, p.lastname, p.getpersonnr(), False, p.email, p.mobile, p.zip_code)) + sammankomsten.deltagare.append(Deltagare(p.getReportID(), p.firstname, p.lastname, p.getpersonnr(), False, p.email, p.mobile, p.zip_code)) - dak.kort.Sammankomster.append(sammankomst) + dak.kort.Sammankomster.append(sammankomsten) if key_url == "excel": excelReport = ExcelReport(dak, semester) resultbytes = excelReport.getFilledInExcelSpreadsheet() response = make_response(resultbytes) response.headers['Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - response.headers['Content-Disposition'] = 'attachment; filename=' + urllib.quote(str(dak.kort.NamnPaaKort), safe='') + '-' + semester.getname() + '.xlsx;' + response.headers['Content-Disposition'] = 'attachment; filename=' + urllib.quote(str(dak.kort.namn_paa_kort), safe='') + '-' + semester.getname() + '.xlsx;' return response elif key_url == "json": - jsonReport = JsonReport(dak, semester) - resultbytes = jsonReport.getReportString() + jReport = JsonReport(dak, semester) + resultbytes = jReport.get_report_string() response = make_response(resultbytes) - response.headers['Content-Type'] = jsonReport.getMimeType() - response.headers['Content-Disposition'] = 'attachment; filename=' + urllib.quote(jsonReport.getFilename(), safe='') + ';' + response.headers['Content-Type'] = jReport.get_mime_type() + response.headers['Content-Disposition'] = 'attachment; filename=' + urllib.quote(jReport.get_filename(), safe='') + ';' return response else: result = render_template('dak.xml', dak=dak) response = make_response(result) response.headers['Content-Type'] = 'application/xml' - response.headers['Content-Disposition'] = 'attachment; filename=' + urllib.quote(str(dak.kort.NamnPaaKort), safe='') + '-' + semester.getname() + '.xml;' + response.headers['Content-Disposition'] = 'attachment; filename=' + urllib.quote(str(dak.kort.namn_paa_kort), safe='') + '-' + semester.getname() + '.xml;' return response elif key_url == "sensus": leaders = [] diff --git a/templates/dak.xml b/templates/dak.xml index 793a7b9..2139eb0 100644 --- a/templates/dak.xml +++ b/templates/dak.xml @@ -1,23 +1,23 @@ - - - - {{dak.kort.Aktivitet}} - {{dak.kort.Lokal}} - {{dak.kort.NamnPaaKort}} + + + + {{dak.kort.aktivitet}} + {{dak.kort.lokal}} + {{dak.kort.namn_paa_kort}} {% for sammankomst in dak.kort.Sammankomster %} - - {{sammankomst.GetStartTimeString()}} - {{sammankomst.GetStopTimeString()}} - {{sammankomst.Aktivitet}} - {{dak.kort.Lokal}} - {{dak.kort.Aktivitet}} + + {{sammankomst.get_start_time_string()}} + {{sammankomst.get_stop_time_string()}} + {{sammankomst.aktivitet}} + {{dak.kort.lokal}} + {{dak.kort.aktivitet}} Add {% for deltagare in sammankomst.deltagare %} - + false true @@ -25,12 +25,12 @@ {% for deltagare in sammankomst.ledare %} - + false true {% endfor %} - + {% endfor%} @@ -39,21 +39,21 @@ {% for deltagare in dak.kort.deltagare %} - - {{deltagare.Foernamn}} - {{deltagare.Efternamn}} - {{deltagare.Personnummer}} + + {{deltagare.foernamn}} + {{deltagare.efternamn}} + {{deltagare.personnummer}} {% endfor %} {% for deltagare in dak.kort.ledare %} - - {{deltagare.Foernamn}} - {{deltagare.Efternamn}} - {{deltagare.Personnummer}} - {{deltagare.Epost}} - {{deltagare.MobilNr}} + + {{deltagare.foernamn}} + {{deltagare.efternamn}} + {{deltagare.personnummer}} + {{deltagare.epost}} + {{deltagare.mobil_nr}} {% endfor %} diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..21d63d5 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,6 @@ +import unittest + +def my_test_suite(): + testLoader = unittest.TestLoader() + testSuite = testLoader.discover('.', pattern='*_test.py') + return testSuite diff --git a/tests/dak_test.py b/tests/dak_test.py new file mode 100644 index 0000000..b394986 --- /dev/null +++ b/tests/dak_test.py @@ -0,0 +1,144 @@ +# -*- coding: utf-8 -*- +""" +Tests of DAK handling. +""" +import sys +import shutil +import time +import os +import json +import unittest +import datetime +import xmlschema +from flask import Flask, render_template +sys.path.append('../lib') # add lib to path for unit-testing +sys.path.append('..') # add lib to path for unit-testing +from jsonreport import JsonReport # pylint: disable=wrong-import-position +from dakdata import DakData, Deltagare, Sammankomst # pylint: disable=wrong-import-position + +class XmlValidator(object): + "XML validation" + def __init__(self, xsdPath): + self.xmlschema = xmlschema.XMLSchema(xsdPath) + + def validate(self, xml): + "Run the validator" + self.xmlschema.validate(xml) + +def create_dak_data(): + "Creates test DAK data" + dak = DakData() + dak.foerenings_namn = u"Test Scoutkår" + dak.forenings_id = "1111" + dak.organisationsnummer = "556677-8899" + dak.kommun_id = "0" + dak.kort.namn_paa_kort = "Testavdelning" + dak.kort.naervarokort_nummer = "1" + dak.kort.aktivitet = u'Moete' + # + dak.kort.ledare.append(Deltagare("1234", "Adam", "Adamsson", u"200501011234", True, "adam@test.com", "12345678", u"Göteborg")) + dak.kort.deltagare.append(Deltagare("1235", "Bertil", "Bertilsson", u"198501011234", False, "bertil@test.com", "12345678", u"Göteborg")) + dak.kort.deltagare.append(Deltagare("1236", "Ada", "Adasson", u"198601011234", False, "ada@test.com", "12345679", u"Göteborg")) + dak.kort.deltagare.append(Deltagare("1237", "Ceda", "Cedasson", u"198701011234", False, "ada@test.com", "12345679", u"Göteborg")) + + sammankomst1 = Sammankomst(u"123", datetime.datetime(2019, 1, 1, 18, 30), 90, u"Möte") + sammankomst1.ledare.append(dak.kort.ledare[0]) + sammankomst1.deltagare.append(dak.kort.deltagare[0]) + sammankomst1.deltagare.append(dak.kort.deltagare[1]) + sammankomst1.deltagare.append(dak.kort.deltagare[2]) + dak.kort.Sammankomster.append(sammankomst1) + + sammankomst2 = Sammankomst(u"123", datetime.datetime(2019, 1, 7, 18, 30), 90, u"Möte") + sammankomst2.ledare.append(dak.kort.ledare[0]) + sammankomst2.deltagare.append(dak.kort.deltagare[0]) + sammankomst2.deltagare.append(dak.kort.deltagare[1]) + sammankomst2.deltagare.append(dak.kort.deltagare[2]) + dak.kort.Sammankomster.append(sammankomst2) + return dak + +def create_flask_app(cfg=None): + "Creates small app for the unit test" + template_path = os.path.join(os.path.dirname(__file__), '..', 'templates') + app = Flask(cfg, template_folder=template_path) + # app.config['DEBUG'] = True + # app.config['SERVER_NAME'] = 'localhost' + return app + +class TestJsonReport(unittest.TestCase): + "DAK handling tests" + + outputDir = 'derived' + expectedDir = 'expected' + + @classmethod + def setUpClass(cls): + output_dir_full = os.path.join(os.path.dirname(__file__), cls.outputDir) + if not os.path.exists(output_dir_full): + os.makedirs(output_dir_full) + time.sleep(0.05) + + @classmethod + def tearDownClass(cls): + output_dir_full = os.path.join(os.path.dirname(__file__), cls.outputDir) + os.rmdir(output_dir_full) + + def save_and_check(self, generated_data, expected_file, generated_file, force=False): + "Save the data and read it back and check with expected file" + expected_path = os.path.join(os.path.dirname(__file__), TestJsonReport.expectedDir, expected_file) + generated_path = os.path.join(os.path.dirname(__file__), TestJsonReport.outputDir, generated_file) + + with open(generated_path, "w") as filep: + filep.write(generated_data) + + self.validate.validate(generated_path) + + if force: + shutil.copyfile(generated_path, expected_path) + + with open(expected_path, "r") as filep: + expected_text = filep.read() + + with open(generated_path, "r") as filep: + generated_text = filep.read() + + self.assertEqual(expected_text, generated_text) + + os.remove(generated_path) + + def setUp(self): + xsd_path = os.path.join(os.path.dirname(__file__), '..', 'templates', 'importSchema.xsd') + self.validate = XmlValidator(xsd_path) + self.dak = create_dak_data() + self.app = create_flask_app('mytest') + # self.app_context = self.app.app_context() + # self.app_context.push() + self.client = self.app.test_client() + + @self.app.route("/") + def hello(): # pylint: disable=unused-variable + return render_template('dak.xml', dak=self.dak) + + def test_dak_json_export(self): + "Test json report of DAK data" + dak = create_dak_data() + #semester = Semester(2019, false) # 2019, vt + semester = None + jsonreport = JsonReport(dak, semester) + stream = jsonreport.get_report_string() + data = json.loads(stream) + + self.assertEqual(data[u'foerenings_namn'], u"Test Scoutkår") + self.assertEqual(data[u'forenings_id'], u"1111") + self.assertEqual(data[u'kort'][u'namn_paa_kort'], "Testavdelning") + self.assertEqual(data[u'kort'][u'Sammankomster'][0]['deltagare'][0]['uid'], "1235") + self.assertEqual(data[u'kort'][u'Sammankomster'][0]['deltagare'][1]['uid'], "1236") + self.assertEqual(data[u'kort'][u'Sammankomster'][0]['ledare'][0]['uid'], "1234") + self.assertEqual(data[u'kort'][u'naervarokort_nummer'], "1") + + def test_dak_xml_export(self): + "Test XML report of DAK data" + response = self.client.get('/') + self.save_and_check(response.data, 'dak_export.xml', 'dak_export.xml', force=True) + +if __name__ == '__main__': + unittest.main() diff --git a/tests/expected/dak_export.xml b/tests/expected/dak_export.xml new file mode 100644 index 0000000..d20abc5 --- /dev/null +++ b/tests/expected/dak_export.xml @@ -0,0 +1,117 @@ + + + + + + Moete + Scouthuset + Testavdelning + + + + 18:30:00 + 20:00:00 + Möte + Scouthuset + Moete + Add + + + + false + true + + + + false + true + + + + false + true + + + + + + + false + true + + + + + + + 18:30:00 + 20:00:00 + Möte + Scouthuset + Moete + Add + + + + false + true + + + + false + true + + + + false + true + + + + + + + false + true + + + + + + + + + + + + + Bertil + Bertilsson + 198501011234 + + + + Ada + Adasson + 198601011234 + + + + Ceda + Cedasson + 198701011234 + + + + + + + Adam + Adamsson + 200501011234 + adam@test.com + 12345678 + + + + \ No newline at end of file From 0723fde5f94e6feb251aa136756a0656a6ada319 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Thor=C3=A9n?= Date: Sat, 4 Jan 2020 20:00:58 +0100 Subject: [PATCH 2/5] Updated DAK tests Modified DakData to follow pylint. Added JSON file test. Added report excel test. --- dakdata.py | 5 +- excelreport.py | 2 +- jsonreport.py | 4 +- start.py | 2 +- templates/dak.xml | 118 +++++------ tests/dak_test.py | 130 ++++++++++-- tests/expected/dak_json_export.json | 198 ++++++++++++++++++ tests/expected/dak_json_pickable_export.json | 160 ++++++++++++++ .../{dak_export.xml => dak_xml_export.xml} | 42 +++- 9 files changed, 569 insertions(+), 92 deletions(-) create mode 100644 tests/expected/dak_json_export.json create mode 100644 tests/expected/dak_json_pickable_export.json rename tests/expected/{dak_export.xml => dak_xml_export.xml} (76%) diff --git a/dakdata.py b/dakdata.py index 4488c77..4c0800e 100644 --- a/dakdata.py +++ b/dakdata.py @@ -6,7 +6,7 @@ """ import datetime -class Deltagare(object): # pylint: disable=wrong-import-position +class Deltagare(object): def __init__(self, uid, foernamn, efternamn, personnummer, ledare, epost="", mobil_nr="", postnummer=""): self.uid = uid self.foernamn = foernamn @@ -69,8 +69,7 @@ class Narvarokort(object): def __init__(self): self.deltagare = [] self.ledare = [] - # json export do not like the name sammankomster. - self.Sammankomster = [] # pylint: disable=invalid-name + self.sammankomster = [] self.naervarokort_nummer = "" self.lokal = "Scouthuset" self.namn_paa_kort = "" diff --git a/excelreport.py b/excelreport.py index 4cc2703..912ed99 100644 --- a/excelreport.py +++ b/excelreport.py @@ -27,7 +27,7 @@ def getFilledInExcelSpreadsheet(self): ledareCount = len(self.dak.kort.ledare) totalPersons = deltagareCount + ledareCount - for index, sammankomst in enumerate(self.dak.kort.Sammankomster): + for index, sammankomst in enumerate(self.dak.kort.sammankomster): aktivitetColumn = 11+index ws.cell(row=2, column=aktivitetColumn).value = sammankomst.aktivitet ws.cell(row=7, column=aktivitetColumn).value = sammankomst.get_start_time_string('%H') diff --git a/jsonreport.py b/jsonreport.py index 8f45eaf..d0656a5 100644 --- a/jsonreport.py +++ b/jsonreport.py @@ -20,5 +20,5 @@ def get_report_string(self): def get_filename(self): return str(self.dak.kort.namn_paa_kort) + '-' + self.semester.getname() + '.json' - def get_json(self): - return jsonpickle.encode(self.dak) + def get_json(self, unpicklable=True, warn=False): + return jsonpickle.encode(self.dak, unpicklable=unpicklable, warn=warn) diff --git a/start.py b/start.py index caca5ac..40abc96 100644 --- a/start.py +++ b/start.py @@ -457,7 +457,7 @@ def show(sgroup_url=None, troop_url=None, key_url=None): else: sammankomsten.deltagare.append(Deltagare(p.getReportID(), p.firstname, p.lastname, p.getpersonnr(), False, p.email, p.mobile, p.zip_code)) - dak.kort.Sammankomster.append(sammankomsten) + dak.kort.sammankomster.append(sammankomsten) if key_url == "excel": excelReport = ExcelReport(dak, semester) resultbytes = excelReport.getFilledInExcelSpreadsheet() diff --git a/templates/dak.xml b/templates/dak.xml index 2139eb0..e6d4e92 100644 --- a/templates/dak.xml +++ b/templates/dak.xml @@ -1,60 +1,60 @@ - - - - - - {{dak.kort.aktivitet}} - {{dak.kort.lokal}} - {{dak.kort.namn_paa_kort}} - - {% for sammankomst in dak.kort.Sammankomster %} - - {{sammankomst.get_start_time_string()}} - {{sammankomst.get_stop_time_string()}} - {{sammankomst.aktivitet}} - {{dak.kort.lokal}} - {{dak.kort.aktivitet}} - Add - - {% for deltagare in sammankomst.deltagare %} - - false - true - - {% endfor %} - - - {% for deltagare in sammankomst.ledare %} - - false - true - - {% endfor %} - - - {% endfor%} - - - - - - {% for deltagare in dak.kort.deltagare %} - - {{deltagare.foernamn}} - {{deltagare.efternamn}} - {{deltagare.personnummer}} - - {% endfor %} - - - {% for deltagare in dak.kort.ledare %} - - {{deltagare.foernamn}} - {{deltagare.efternamn}} - {{deltagare.personnummer}} - {{deltagare.epost}} - {{deltagare.mobil_nr}} - - {% endfor %} - + + + + + + {{dak.kort.aktivitet}} + {{dak.kort.lokal}} + {{dak.kort.namn_paa_kort}} + + {% for sammankomst in dak.kort.sammankomster %} + + {{sammankomst.get_start_time_string()}} + {{sammankomst.get_stop_time_string()}} + {{sammankomst.aktivitet}} + {{dak.kort.lokal}} + {{dak.kort.aktivitet}} + Add + + {% for deltagare in sammankomst.deltagare %} + + false + true + + {% endfor %} + + + {% for deltagare in sammankomst.ledare %} + + false + true + + {% endfor %} + + + {% endfor%} + + + + + + {% for deltagare in dak.kort.deltagare %} + + {{deltagare.foernamn}} + {{deltagare.efternamn}} + {{deltagare.personnummer}} + + {% endfor %} + + + {% for deltagare in dak.kort.ledare %} + + {{deltagare.foernamn}} + {{deltagare.efternamn}} + {{deltagare.personnummer}} + {{deltagare.epost}} + {{deltagare.mobil_nr}} + + {% endfor %} + \ No newline at end of file diff --git a/tests/dak_test.py b/tests/dak_test.py index b394986..c965215 100644 --- a/tests/dak_test.py +++ b/tests/dak_test.py @@ -5,16 +5,29 @@ import sys import shutil import time +import platform import os import json import unittest import datetime import xmlschema +import jsonpickle +from openpyxl import load_workbook from flask import Flask, render_template sys.path.append('../lib') # add lib to path for unit-testing sys.path.append('..') # add lib to path for unit-testing from jsonreport import JsonReport # pylint: disable=wrong-import-position from dakdata import DakData, Deltagare, Sammankomst # pylint: disable=wrong-import-position +if platform.system() == 'Windows': + # Add app engine paths on windows. + sys.path.append("C:/Program Files (x86)/Google/google_appengine") + sys.path.append("C:/Program Files (x86)/Google/google_appengine/lib") + sys.path.append("c:/Program Files (x86)/Google/google_appengine/google/appengine/api") + sys.path.append("c:/Program Files (x86)/Google/google_appengine/google/appengine") +from google.appengine.ext import ndb # pylint: disable=wrong-import-position +from google.appengine.ext import testbed # pylint: disable=wrong-import-position +from excelreport import ExcelReport # pylint: disable=wrong-import-position +from data import Semester # pylint: disable=wrong-import-position class XmlValidator(object): "XML validation" @@ -36,24 +49,31 @@ def create_dak_data(): dak.kort.naervarokort_nummer = "1" dak.kort.aktivitet = u'Moete' # - dak.kort.ledare.append(Deltagare("1234", "Adam", "Adamsson", u"200501011234", True, "adam@test.com", "12345678", u"Göteborg")) - dak.kort.deltagare.append(Deltagare("1235", "Bertil", "Bertilsson", u"198501011234", False, "bertil@test.com", "12345678", u"Göteborg")) - dak.kort.deltagare.append(Deltagare("1236", "Ada", "Adasson", u"198601011234", False, "ada@test.com", "12345679", u"Göteborg")) - dak.kort.deltagare.append(Deltagare("1237", "Ceda", "Cedasson", u"198701011234", False, "ada@test.com", "12345679", u"Göteborg")) + dak.kort.ledare.append(Deltagare("1234", "Adam", "Adamsson", u"198501011234", True, "adam@test.com", "12345678", u"Göteborg")) + dak.kort.deltagare.append(Deltagare("1235", "Bertil", "Bertilsson", u"200501011234", False, "bertil@test.com", "12345678", u"Göteborg")) + dak.kort.deltagare.append(Deltagare("1236", "Ada", "Adasson", u"200601011244", False, "ada@test.com", "12345679", u"Göteborg")) + dak.kort.deltagare.append(Deltagare("1237", "Ceda", "Cedasson", u"200701011244", False, "ada@test.com", "12345679", u"Göteborg")) sammankomst1 = Sammankomst(u"123", datetime.datetime(2019, 1, 1, 18, 30), 90, u"Möte") sammankomst1.ledare.append(dak.kort.ledare[0]) sammankomst1.deltagare.append(dak.kort.deltagare[0]) sammankomst1.deltagare.append(dak.kort.deltagare[1]) sammankomst1.deltagare.append(dak.kort.deltagare[2]) - dak.kort.Sammankomster.append(sammankomst1) + dak.kort.sammankomster.append(sammankomst1) sammankomst2 = Sammankomst(u"123", datetime.datetime(2019, 1, 7, 18, 30), 90, u"Möte") sammankomst2.ledare.append(dak.kort.ledare[0]) sammankomst2.deltagare.append(dak.kort.deltagare[0]) sammankomst2.deltagare.append(dak.kort.deltagare[1]) sammankomst2.deltagare.append(dak.kort.deltagare[2]) - dak.kort.Sammankomster.append(sammankomst2) + dak.kort.sammankomster.append(sammankomst2) + + sammankomst3 = Sammankomst(u"123", datetime.datetime(2019, 1, 14, 18, 30), 90, u"Möte") + sammankomst3.ledare.append(dak.kort.ledare[0]) + sammankomst3.deltagare.append(dak.kort.deltagare[0]) + sammankomst3.deltagare.append(dak.kort.deltagare[2]) + dak.kort.sammankomster.append(sammankomst3) + return dak def create_flask_app(cfg=None): @@ -82,23 +102,24 @@ def tearDownClass(cls): output_dir_full = os.path.join(os.path.dirname(__file__), cls.outputDir) os.rmdir(output_dir_full) - def save_and_check(self, generated_data, expected_file, generated_file, force=False): + def save_and_check(self, generated_data, expected_file, generated_file, check_xsd=False, force=False): "Save the data and read it back and check with expected file" expected_path = os.path.join(os.path.dirname(__file__), TestJsonReport.expectedDir, expected_file) generated_path = os.path.join(os.path.dirname(__file__), TestJsonReport.outputDir, generated_file) - with open(generated_path, "w") as filep: + with open(generated_path, "wb") as filep: filep.write(generated_data) - self.validate.validate(generated_path) + if check_xsd: + self.validate.validate(generated_path) if force: shutil.copyfile(generated_path, expected_path) - with open(expected_path, "r") as filep: + with open(expected_path, "rb") as filep: expected_text = filep.read() - with open(generated_path, "r") as filep: + with open(generated_path, "rb") as filep: generated_text = filep.read() self.assertEqual(expected_text, generated_text) @@ -106,6 +127,21 @@ def save_and_check(self, generated_data, expected_file, generated_file, force=Fa os.remove(generated_path) def setUp(self): + # Google app engine testbed setup. + # First, create an instance of the Testbed class. + self.testbed = testbed.Testbed() + # Then activate the testbed, which prepares the service stubs for use. + self.testbed.activate() + # Next, declare which service stubs you want to use. + self.testbed.init_datastore_v3_stub() + self.testbed.init_memcache_stub() + # Clear ndb's in-context cache between tests. + # This prevents data from leaking between tests. + # Alternatively, you could disable caching by + # using ndb.get_context().set_cache_policy(False) + ndb.get_context().clear_cache() + + # Flask app test setup. xsd_path = os.path.join(os.path.dirname(__file__), '..', 'templates', 'importSchema.xsd') self.validate = XmlValidator(xsd_path) self.dak = create_dak_data() @@ -118,27 +154,81 @@ def setUp(self): def hello(): # pylint: disable=unused-variable return render_template('dak.xml', dak=self.dak) + def tearDown(self): + self.testbed.deactivate() + def test_dak_json_export(self): "Test json report of DAK data" - dak = create_dak_data() - #semester = Semester(2019, false) # 2019, vt - semester = None - jsonreport = JsonReport(dak, semester) - stream = jsonreport.get_report_string() + semester = Semester.create(2019, False) # 2019, vt + jsonpickle.set_encoder_options('json', indent=4) + jsonreport = JsonReport(self.dak, semester) + stream = jsonreport.get_json(unpicklable=False, warn=True) data = json.loads(stream) self.assertEqual(data[u'foerenings_namn'], u"Test Scoutkår") self.assertEqual(data[u'forenings_id'], u"1111") self.assertEqual(data[u'kort'][u'namn_paa_kort'], "Testavdelning") - self.assertEqual(data[u'kort'][u'Sammankomster'][0]['deltagare'][0]['uid'], "1235") - self.assertEqual(data[u'kort'][u'Sammankomster'][0]['deltagare'][1]['uid'], "1236") - self.assertEqual(data[u'kort'][u'Sammankomster'][0]['ledare'][0]['uid'], "1234") + self.assertEqual(data[u'kort'][u'sammankomster'][0]['deltagare'][0]['uid'], "1235") + self.assertEqual(data[u'kort'][u'sammankomster'][0]['deltagare'][1]['uid'], "1236") + self.assertEqual(data[u'kort'][u'sammankomster'][0]['ledare'][0]['uid'], "1234") self.assertEqual(data[u'kort'][u'naervarokort_nummer'], "1") + self.save_and_check(stream, 'dak_json_export.json', 'dak_json_export.json') + + stream = jsonreport.get_report_string() + data = jsonpickle.decode(stream) + + self.assertEqual(data.foerenings_namn, u"Test Scoutkår") + self.assertEqual(data.forenings_id, u"1111") + self.assertEqual(data.kort.namn_paa_kort, "Testavdelning") + self.assertEqual(data.kort.sammankomster[0].deltagare[0].uid, "1235") + self.assertEqual(data.kort.sammankomster[0].deltagare[1].uid, "1236") + self.assertEqual(data.kort.sammankomster[0].ledare[0].uid, "1234") + self.assertEqual(data.kort.naervarokort_nummer, "1") + self.save_and_check(stream, 'dak_json_pickable_export.json', 'dak_json_pickable_export.json', force=True) def test_dak_xml_export(self): "Test XML report of DAK data" response = self.client.get('/') - self.save_and_check(response.data, 'dak_export.xml', 'dak_export.xml', force=True) + self.save_and_check(response.data, 'dak_xml_export.xml', 'dak_xml_export.xml', check_xsd=True) + + def test_dak_excel_export(self): + "Test excel report of DAK data" + current_semester = Semester.create(2019, False) # 2019, vt + excel_report = ExcelReport(self.dak, current_semester) + result_bytes = excel_report.getFilledInExcelSpreadsheet() + + generated_path = os.path.join(os.path.dirname(__file__), TestJsonReport.outputDir, 'dak_excel_export.xlsx') + + with open(generated_path, "wb") as filep: + filep.write(result_bytes) + + workbook = load_workbook(generated_path) + worksheets = workbook.worksheets[0] + self.assertEqual(self.dak.kort.naervarokort_nummer, worksheets['E1'].value) + self.assertEqual(current_semester.year, worksheets['I1'].value) + self.assertEqual(self.dak.kort.namn_paa_kort, worksheets['D2'].value) + self.assertEqual("Scouting", worksheets['D3'].value) + self.assertEqual(self.dak.kort.lokal, worksheets['D4'].value) + if current_semester.ht: + self.assertEqual(worksheets['C6'].value, None) + self.assertEqual(worksheets['C7'].value, 'X') + else: + self.assertEqual(worksheets['C6'].value, 'X') + self.assertEqual(worksheets['C7'].value, None) + + row = 13 + for deltagaren in self.dak.kort.deltagare: + self.assertEqual(deltagaren.foernamn + " " + deltagaren.efternamn, worksheets['B' + str(row)].value) + self.assertEqual('K' if deltagaren.is_female() else 'M', worksheets['H' + str(row)].value) + self.assertEqual(deltagaren.personnummer[0:8], worksheets['J' + str(row)].value) + self.assertEqual(1, worksheets['K' + str(row)].value) + self.assertEqual(1, worksheets['L' + str(row)].value) + row += 1 + self.assertEqual(1, worksheets['M13'].value) + self.assertEqual(None, worksheets['M14'].value) + self.assertEqual(1, worksheets['M15'].value) + + os.remove(generated_path) if __name__ == '__main__': unittest.main() diff --git a/tests/expected/dak_json_export.json b/tests/expected/dak_json_export.json new file mode 100644 index 0000000..e4dd8e2 --- /dev/null +++ b/tests/expected/dak_json_export.json @@ -0,0 +1,198 @@ +{ + "kort": { + "deltagare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "200501011234", + "uid": "1235", + "ledare": false, + "mobil_nr": "12345678", + "foernamn": "Bertil", + "efternamn": "Bertilsson", + "epost": "bertil@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200601011244", + "uid": "1236", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ada", + "efternamn": "Adasson", + "epost": "ada@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200701011244", + "uid": "1237", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ceda", + "efternamn": "Cedasson", + "epost": "ada@test.com" + } + ], + "ledare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "198501011234", + "uid": "1234", + "ledare": true, + "mobil_nr": "12345678", + "foernamn": "Adam", + "efternamn": "Adamsson", + "epost": "adam@test.com" + } + ], + "namn_paa_kort": "Testavdelning", + "naervarokort_nummer": "1", + "lokal": "Scouthuset", + "sammankomster": [ + { + "deltagare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "200501011234", + "uid": "1235", + "ledare": false, + "mobil_nr": "12345678", + "foernamn": "Bertil", + "efternamn": "Bertilsson", + "epost": "bertil@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200601011244", + "uid": "1236", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ada", + "efternamn": "Adasson", + "epost": "ada@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200701011244", + "uid": "1237", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ceda", + "efternamn": "Cedasson", + "epost": "ada@test.com" + } + ], + "ledare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "198501011234", + "uid": "1234", + "ledare": true, + "mobil_nr": "12345678", + "foernamn": "Adam", + "efternamn": "Adamsson", + "epost": "adam@test.com" + } + ], + "datum": "2019-01-01 18:30:00", + "kod": "123", + "duration": 90, + "aktivitet": "M\u00f6te" + }, + { + "deltagare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "200501011234", + "uid": "1235", + "ledare": false, + "mobil_nr": "12345678", + "foernamn": "Bertil", + "efternamn": "Bertilsson", + "epost": "bertil@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200601011244", + "uid": "1236", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ada", + "efternamn": "Adasson", + "epost": "ada@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200701011244", + "uid": "1237", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ceda", + "efternamn": "Cedasson", + "epost": "ada@test.com" + } + ], + "ledare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "198501011234", + "uid": "1234", + "ledare": true, + "mobil_nr": "12345678", + "foernamn": "Adam", + "efternamn": "Adamsson", + "epost": "adam@test.com" + } + ], + "datum": "2019-01-07 18:30:00", + "kod": "123", + "duration": 90, + "aktivitet": "M\u00f6te" + }, + { + "deltagare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "200501011234", + "uid": "1235", + "ledare": false, + "mobil_nr": "12345678", + "foernamn": "Bertil", + "efternamn": "Bertilsson", + "epost": "bertil@test.com" + }, + { + "postnummer": "G\u00f6teborg", + "personnummer": "200701011244", + "uid": "1237", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ceda", + "efternamn": "Cedasson", + "epost": "ada@test.com" + } + ], + "ledare": [ + { + "postnummer": "G\u00f6teborg", + "personnummer": "198501011234", + "uid": "1234", + "ledare": true, + "mobil_nr": "12345678", + "foernamn": "Adam", + "efternamn": "Adamsson", + "epost": "adam@test.com" + } + ], + "datum": "2019-01-14 18:30:00", + "kod": "123", + "duration": 90, + "aktivitet": "M\u00f6te" + } + ], + "aktivitet": "Moete" + }, + "forenings_id": "1111", + "kommun_id": "0", + "foerenings_namn": "Test Scoutk\u00e5r", + "organisationsnummer": "556677-8899" +} \ No newline at end of file diff --git a/tests/expected/dak_json_pickable_export.json b/tests/expected/dak_json_pickable_export.json new file mode 100644 index 0000000..aa46300 --- /dev/null +++ b/tests/expected/dak_json_pickable_export.json @@ -0,0 +1,160 @@ +{ + "py/object": "dakdata.DakData", + "foerenings_namn": "Test Scoutk\u00e5r", + "organisationsnummer": "556677-8899", + "forenings_id": "1111", + "kommun_id": "0", + "kort": { + "py/object": "dakdata.Narvarokort", + "deltagare": [ + { + "py/object": "dakdata.Deltagare", + "postnummer": "G\u00f6teborg", + "personnummer": "200501011234", + "uid": "1235", + "ledare": false, + "mobil_nr": "12345678", + "foernamn": "Bertil", + "efternamn": "Bertilsson", + "epost": "bertil@test.com" + }, + { + "py/object": "dakdata.Deltagare", + "postnummer": "G\u00f6teborg", + "personnummer": "200601011244", + "uid": "1236", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ada", + "efternamn": "Adasson", + "epost": "ada@test.com" + }, + { + "py/object": "dakdata.Deltagare", + "postnummer": "G\u00f6teborg", + "personnummer": "200701011244", + "uid": "1237", + "ledare": false, + "mobil_nr": "12345679", + "foernamn": "Ceda", + "efternamn": "Cedasson", + "epost": "ada@test.com" + } + ], + "ledare": [ + { + "py/object": "dakdata.Deltagare", + "postnummer": "G\u00f6teborg", + "personnummer": "198501011234", + "uid": "1234", + "ledare": true, + "mobil_nr": "12345678", + "foernamn": "Adam", + "efternamn": "Adamsson", + "epost": "adam@test.com" + } + ], + "namn_paa_kort": "Testavdelning", + "naervarokort_nummer": "1", + "lokal": "Scouthuset", + "sammankomster": [ + { + "py/object": "dakdata.Sammankomst", + "deltagare": [ + { + "py/id": 3 + }, + { + "py/id": 4 + }, + { + "py/id": 5 + } + ], + "ledare": [ + { + "py/id": 7 + } + ], + "datum": { + "py/object": "datetime.datetime", + "__reduce__": [ + { + "py/type": "datetime.datetime" + }, + [ + "B+MBARIeAAAAAA==" + ] + ] + }, + "kod": "123", + "duration": 90, + "aktivitet": "M\u00f6te" + }, + { + "py/object": "dakdata.Sammankomst", + "deltagare": [ + { + "py/id": 3 + }, + { + "py/id": 4 + }, + { + "py/id": 5 + } + ], + "ledare": [ + { + "py/id": 7 + } + ], + "datum": { + "py/object": "datetime.datetime", + "__reduce__": [ + { + "py/type": "datetime.datetime" + }, + [ + "B+MBBxIeAAAAAA==" + ] + ] + }, + "kod": "123", + "duration": 90, + "aktivitet": "M\u00f6te" + }, + { + "py/object": "dakdata.Sammankomst", + "deltagare": [ + { + "py/id": 3 + }, + { + "py/id": 5 + } + ], + "ledare": [ + { + "py/id": 7 + } + ], + "datum": { + "py/object": "datetime.datetime", + "__reduce__": [ + { + "py/type": "datetime.datetime" + }, + [ + "B+MBDhIeAAAAAA==" + ] + ] + }, + "kod": "123", + "duration": 90, + "aktivitet": "M\u00f6te" + } + ], + "aktivitet": "Moete" + } +} \ No newline at end of file diff --git a/tests/expected/dak_export.xml b/tests/expected/dak_xml_export.xml similarity index 76% rename from tests/expected/dak_export.xml rename to tests/expected/dak_xml_export.xml index d20abc5..3518bca 100644 --- a/tests/expected/dak_export.xml +++ b/tests/expected/dak_xml_export.xml @@ -33,7 +33,7 @@ - + false @@ -68,7 +68,37 @@ - + + + + false + true + + + + + + + 18:30:00 + 20:00:00 + Möte + Scouthuset + Moete + Add + + + + false + true + + + + false + true + + + + false @@ -87,19 +117,19 @@ Bertil Bertilsson - 198501011234 + 200501011234 Ada Adasson - 198601011234 + 200601011244 Ceda Cedasson - 198701011234 + 200701011244 @@ -108,7 +138,7 @@ Adam Adamsson - 200501011234 + 198501011234 adam@test.com 12345678 From 53583f9a26d3b344209323af4d755a7d858f0157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Thor=C3=A9n?= Date: Sat, 4 Jan 2020 21:25:29 +0100 Subject: [PATCH 3/5] Configured endline settings. Make sure that json and xml files are always in LF format. --- .gitattributes | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1d63ce6 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +* text=auto +*.txt text +*.json text eol=lf +*.xml text eol=lf +.gitattributes text eol=lf From bcab9ae1fa0275999a6116a1cbaa975e87701310 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbjo=CC=88rn=20Einarsson?= Date: Sun, 5 Jan 2020 13:25:34 +0100 Subject: [PATCH 4/5] Added paths for MacOS and made general pylint import disabling --- tests/README.md | 11 +++++++++++ tests/dak_test.py | 29 +++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 8 deletions(-) create mode 100644 tests/README.md diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..6d7eaf8 --- /dev/null +++ b/tests/README.md @@ -0,0 +1,11 @@ +# Unit tests + +Run from parent directory as + + python2 tests/dak_test.py + +Alternatively from this directory as + + python2 dak_test.py + +Has been tested with Windows and MacOS. diff --git a/tests/dak_test.py b/tests/dak_test.py index c965215..766b6c9 100644 --- a/tests/dak_test.py +++ b/tests/dak_test.py @@ -10,24 +10,37 @@ import json import unittest import datetime + +# Disable all import warnings since the imports are pretty hacky +#pylint: disable=import-error,wrong-import-order,wrong-import-position +sys.path.append('../lib') # add lib to path for unit-testing +sys.path.append('..') # add parent to path for unit-testing +sys.path.append('./lib') # add lib to path for unit-testing +sys.path.append('.') # add current dir to path for unit-testing import xmlschema import jsonpickle from openpyxl import load_workbook from flask import Flask, render_template -sys.path.append('../lib') # add lib to path for unit-testing -sys.path.append('..') # add lib to path for unit-testing -from jsonreport import JsonReport # pylint: disable=wrong-import-position -from dakdata import DakData, Deltagare, Sammankomst # pylint: disable=wrong-import-position +from jsonreport import JsonReport +from dakdata import DakData, Deltagare, Sammankomst if platform.system() == 'Windows': # Add app engine paths on windows. sys.path.append("C:/Program Files (x86)/Google/google_appengine") sys.path.append("C:/Program Files (x86)/Google/google_appengine/lib") sys.path.append("c:/Program Files (x86)/Google/google_appengine/google/appengine/api") sys.path.append("c:/Program Files (x86)/Google/google_appengine/google/appengine") -from google.appengine.ext import ndb # pylint: disable=wrong-import-position -from google.appengine.ext import testbed # pylint: disable=wrong-import-position -from excelreport import ExcelReport # pylint: disable=wrong-import-position -from data import Semester # pylint: disable=wrong-import-position +elif platform.system() == 'Darwin': # i.e. MacOS + BASE = "/usr/local/Caskroom/google-cloud-sdk/latest/google-cloud-sdk/" + sys.path.append(BASE + "platform/google_appengine/lib/fancy_urllib") + sys.path.append(BASE + "platform/google_appengine/lib") + sys.path.append(BASE + "platform/google_appengine/api") + sys.path.append(BASE + "platform/google_appengine") + sys.path.append(BASE + "lib/third_party") + +from google.appengine.ext import ndb +from google.appengine.ext import testbed +from excelreport import ExcelReport +from data import Semester class XmlValidator(object): "XML validation" From 8fe40631ac4aeff35693e8c2cba1b20d3a0daf60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Torbjo=CC=88rn=20Einarsson?= Date: Sun, 5 Jan 2020 13:49:14 +0100 Subject: [PATCH 5/5] Very minor cleanup. --- tests/dak_test.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/dak_test.py b/tests/dak_test.py index 766b6c9..04c42bf 100644 --- a/tests/dak_test.py +++ b/tests/dak_test.py @@ -42,7 +42,8 @@ from excelreport import ExcelReport from data import Semester -class XmlValidator(object): + +class XmlValidator(): "XML validation" def __init__(self, xsdPath): self.xmlschema = xmlschema.XMLSchema(xsdPath) @@ -97,6 +98,7 @@ def create_flask_app(cfg=None): # app.config['SERVER_NAME'] = 'localhost' return app + class TestJsonReport(unittest.TestCase): "DAK handling tests" @@ -243,5 +245,6 @@ def test_dak_excel_export(self): os.remove(generated_path) + if __name__ == '__main__': unittest.main()