Whitebox Tests

This commit is contained in:
2024-06-03 11:51:05 +02:00
parent 9fa7cfe867
commit 2027397e03
5 changed files with 70 additions and 15 deletions

View File

@ -57,7 +57,10 @@ async def getKurs(token: int, cookie: str):
response = await s.get(url=f"{url}?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N{token},-N000307,", response = await s.get(url=f"{url}?APPNAME=CampusNet&PRGNAME=COURSERESULTS&ARGUMENTS=-N{token},-N000307,",
headers=headers) headers=headers)
html = BeautifulSoup(response.text, 'lxml') html = BeautifulSoup(response.text, 'lxml')
link = html.body.find('a', attrs={'id': "Popup_details0001"})['href'] try:
link = html.body.find('a', attrs={'id': "Popup_details0001"})['href']
except TypeError:
return 0
response = await s.get(url=f"{url}{link[21:]}", headers=headers) response = await s.get(url=f"{url}{link[21:]}", headers=headers)
html = BeautifulSoup(response.text, 'lxml') html = BeautifulSoup(response.text, 'lxml')
content = html.body.find('td', attrs={'class': 'level02'}).text content = html.body.find('td', attrs={'class': 'level02'}).text

View File

@ -1,4 +1,5 @@
import urllib.error import urllib.error
from datetime import datetime, timedelta
from dateutil.parser import * from dateutil.parser import *
@ -6,6 +7,7 @@ import asyncio
import httpx import httpx
import icalendar import icalendar
from dateutil.relativedelta import relativedelta
from icalendar import Calendar, Event from icalendar import Calendar, Event
import json import json
@ -29,6 +31,7 @@ def writeToFile(filename, data):
:param data: :param data:
""" """
with open(filename, 'w+') as file: with open(filename, 'w+') as file:
assert "BEGIN:VCALENDAR" in data.text
file.write(data.text) file.write(data.text)
file.close() file.close()
@ -51,7 +54,7 @@ def parseRaplaURL(url: str):
Konvertiert werden: http, www.; page=calendar \n Konvertiert werden: http, www.; page=calendar \n
In: https; page=ical In: https; page=ical
:param url: :param url:
:return str: :return [Status: int, URL: str]:
""" """
rapla = url.find("rapla.") rapla = url.find("rapla.")
if rapla == -1: if rapla == -1:
@ -75,31 +78,44 @@ def parseRaplaURL(url: str):
return 0, 0 return 0, 0
async def getNewRapla(url: str): async def getNewRapla(url: str, testing=None):
""" """
Speichert den iCal eines Raplas auf dem Server. \n Speichert den iCal eines Raplas auf dem Server. \n
Gibt Namen der Datei zurück. \n Gibt Namen der Datei zurück. \n
TODO: Standort zu Dateibezeichner hinzufügen, um Konflikte zu vermeiden. TODO: Standort zu Dateibezeichner hinzufügen, um Konflikte zu vermeiden.
:param url: :param url:
:param opt. testing:
:return str: :return str:
""" """
parsed = parseRaplaURL(url) parsed = parseRaplaURL(url)
if testing:
assert "https" in parsed[1]
try:
assert "ical" in parsed[1]
except AssertionError:
assert "key" in parsed[1]
if parsed[0] == 0: if parsed[0] == 0:
return 0 return 0
elif parsed[0] == 1: elif parsed[0] == 1:
url = parsed[1] url = parsed[1]
elif parsed[0] == 2: elif parsed[0] == 2:
return await buildICALfromKey(parsed[1], onlyUpdate=False) return await buildICALfromKey(parsed[1], onlyUpdate=False, testing=True)
fileInURL = url.find("file=") fileInURL = url.find("file=")
kurs = url[fileInURL + 5:].upper() kurs = url[fileInURL + 5:].upper()
if url[-5:] != ".ical": if url[-5:] != ".ical":
try: try:
async with httpx.AsyncClient() as s: async with httpx.AsyncClient() as s:
response = await fetchPlan(s, url) response = await fetchPlan(s, url)
if testing:
assert "Vollmer" in response.text
writeToFile(f"calendars/rapla{kurs}.ical", response) writeToFile(f"calendars/rapla{kurs}.ical", response)
except urllib.error.URLError: except urllib.error.URLError:
return -1 return -1
writeKursToDB(kurs, url) writeKursToDB(kurs, url)
if testing:
assert "TINF22B3" in Rapla.query.filter(Rapla.name == "TINF22B3").first().file
return f"rapla{kurs}.ical" return f"rapla{kurs}.ical"
else: else:
return url return url
@ -159,11 +175,12 @@ def raplaSchedule():
asyncio.run(refreshRapla()) asyncio.run(refreshRapla())
async def buildICALfromKey(url, onlyUpdate): async def buildICALfromKey(url, onlyUpdate, testing=True):
""" """
Baut eine .ical-Datei aus der mitgegebenen URL, die ein Key-Parameter enthalten muss. Baut eine .ical-Datei aus der mitgegebenen URL, die ein Key-Parameter enthalten muss.
:param url: :param url:
:param onlyUpdate: :param onlyUpdate:
:param opt. testing:
:return Dateinamen: :return Dateinamen:
""" """
async with httpx.AsyncClient() as s: async with httpx.AsyncClient() as s:
@ -179,14 +196,18 @@ async def buildICALfromKey(url, onlyUpdate):
return 200 return 200
else: else:
kursname = page.text[page.text.find("<title>") + 7:page.text.find("</title>")] kursname = page.text[page.text.find("<title>") + 7:page.text.find("</title>")]
if testing:
assert "TMT22B1" in kursname
if len(kursname) > 15: if len(kursname) > 15:
return 0 return 0
start = "2024-08-01" start = f'{(datetime.now() - relativedelta(days=183)):%Y-%m-%d}'
end = "2024-12-31" end = f'{(datetime.now() + relativedelta(days=183)):%Y-%m-%d}'
payload = {"url": url, "start": start, "end": end} payload = {"url": url, "start": start, "end": end}
req = await s.post(url="https://dh-api.paulmartin.cloud/rapla", data=payload, req = await s.post(url="https://dh-api.paulmartin.cloud/rapla", data=payload,
headers={'Content-Type': 'application/x-www-form-urlencoded'}, timeout=10) headers={'Content-Type': 'application/x-www-form-urlencoded'}, timeout=15)
jsonresp = json.loads(req.text) jsonresp = json.loads(req.text)
if testing:
assert len(jsonresp) > 0
cal = Calendar() cal = Calendar()
cal.add('prodid', '-//Rapla//iCal Plugin//EN') cal.add('prodid', '-//Rapla//iCal Plugin//EN')
cal.add('version', '2.0') cal.add('version', '2.0')
@ -211,6 +232,8 @@ async def buildICALfromKey(url, onlyUpdate):
f.close() f.close()
if not onlyUpdate: if not onlyUpdate:
writeKursToDB(kursname, url) writeKursToDB(kursname, url)
if testing:
assert "TMT22B1" in Rapla.query.filter(Rapla.name == "TMT22B1").first().file
return f"rapla{kursname}.ical" return f"rapla{kursname}.ical"
else: else:
return 200 return 200

View File

@ -19,4 +19,6 @@ pymysql
APScheduler APScheduler
cryptography cryptography
python-dateutil~=2.9.0.post0 python-dateutil~=2.9.0.post0
requests~=2.31.0 requests~=2.31.0
pytest
pytest-asyncio

View File

@ -101,7 +101,7 @@ def initRoutes(app: Flask):
s="p", praxis="hidden") s="p", praxis="hidden")
@app.route("/plan/<string:kurs>") @app.route("/plan/<string:kurs>")
async def displayPlan(kurs): async def displayPlan(kurs: str):
""" """
Zeigt den Stundenplan ohne Login an. \n Zeigt den Stundenplan ohne Login an. \n
Präferenzen werden nicht berücksichtigt. Präferenzen werden nicht berücksichtigt.

View File

@ -1,6 +1,7 @@
import pytest import pytest
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
import fetchRAPLA
import routing import routing
import init import init
from tests_examples import login_data from tests_examples import login_data
@ -45,7 +46,7 @@ def login(client):
return False return False
def test_login(client): def test_login_blackbox(client):
""" """
Testet die Login-Funktion Testet die Login-Funktion
:param client: :param client:
@ -63,7 +64,7 @@ def test_login(client):
assert len(cookie.value) == 32 # CNSC-Länge: 32 → Wenn der Cookie so lang ist, ist man erfolgreich eingeloggt. assert len(cookie.value) == 32 # CNSC-Länge: 32 → Wenn der Cookie so lang ist, ist man erfolgreich eingeloggt.
def test_kurssetup(client): def test_kurssetup_blackbox(client):
""" """
Testet die Konfiguration eines Kurses Testet die Konfiguration eines Kurses
:param client: :param client:
@ -86,7 +87,7 @@ def test_kurssetup(client):
assert False assert False
def test_semestersetup(client): def test_semestersetup_blackbox(client):
""" """
Testet die Konfiguration eines Semesters Testet die Konfiguration eines Semesters
:param client: :param client:
@ -106,7 +107,7 @@ def test_semestersetup(client):
assert False assert False
def test_noten(client): def test_noten_blackbox(client):
""" """
Testet das Abrufen der Noten aus zwei verschiedenen Semestern Testet das Abrufen der Noten aus zwei verschiedenen Semestern
:param client: :param client:
@ -134,7 +135,7 @@ def test_noten(client):
assert False assert False
def test_logout(client): def test_logout_blackbox(client):
""" """
Testet die Logout-Funktion Testet die Logout-Funktion
:param client: :param client:
@ -147,3 +148,29 @@ def test_logout(client):
assert len(cookie.value) != 32 # CNSC-Länge: 32 → CNSC darf ausgeloggt nicht gesetzt sein assert len(cookie.value) != 32 # CNSC-Länge: 32 → CNSC darf ausgeloggt nicht gesetzt sein
else: else:
assert False assert False
@pytest.mark.asyncio()
async def test_url_anweisung_whitebox(app):
"""
Testet einen Pfad des URL-Imports
:param app:
"""
with app.app_context():
rapla = await fetchRAPLA.getNewRapla("http://www.rapla.dhbw-karlsruhe.de/rapla?page=calendar&user=vollmer"
"&file=tinf22b3", True)
assert "TINF22B3" in rapla
@pytest.mark.asyncio()
async def test_url_entscheidung_whitebox(app):
"""
Testet alle Pfade des URL-Imports, die mit einer fehlerfreien Datei enden
:param app:
"""
with app.app_context():
await test_url_anweisung_whitebox(app)
rapla = await fetchRAPLA.getNewRapla("http://www.rapla.dhbw-karlsruhe.de/rapla?key=ah9tAVphi"
"caj4FqCtMVJchAs9fh0Dt89jA8Td4kEi21V0i2mlUEpycpIVw5jSY5T",
True)
assert "TMT22B1" in rapla