Whitebox Tests
This commit is contained in:
@ -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,",
|
||||
headers=headers)
|
||||
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)
|
||||
html = BeautifulSoup(response.text, 'lxml')
|
||||
content = html.body.find('td', attrs={'class': 'level02'}).text
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import urllib.error
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from dateutil.parser import *
|
||||
|
||||
@ -6,6 +7,7 @@ import asyncio
|
||||
|
||||
import httpx
|
||||
import icalendar
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from icalendar import Calendar, Event
|
||||
import json
|
||||
|
||||
@ -29,6 +31,7 @@ def writeToFile(filename, data):
|
||||
:param data:
|
||||
"""
|
||||
with open(filename, 'w+') as file:
|
||||
assert "BEGIN:VCALENDAR" in data.text
|
||||
file.write(data.text)
|
||||
file.close()
|
||||
|
||||
@ -51,7 +54,7 @@ def parseRaplaURL(url: str):
|
||||
Konvertiert werden: http, www.; page=calendar \n
|
||||
In: https; page=ical
|
||||
:param url:
|
||||
:return str:
|
||||
:return [Status: int, URL: str]:
|
||||
"""
|
||||
rapla = url.find("rapla.")
|
||||
if rapla == -1:
|
||||
@ -75,31 +78,44 @@ def parseRaplaURL(url: str):
|
||||
return 0, 0
|
||||
|
||||
|
||||
async def getNewRapla(url: str):
|
||||
async def getNewRapla(url: str, testing=None):
|
||||
"""
|
||||
Speichert den iCal eines Raplas auf dem Server. \n
|
||||
Gibt Namen der Datei zurück. \n
|
||||
TODO: Standort zu Dateibezeichner hinzufügen, um Konflikte zu vermeiden.
|
||||
:param url:
|
||||
:param opt. testing:
|
||||
:return str:
|
||||
"""
|
||||
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:
|
||||
return 0
|
||||
elif parsed[0] == 1:
|
||||
url = parsed[1]
|
||||
elif parsed[0] == 2:
|
||||
return await buildICALfromKey(parsed[1], onlyUpdate=False)
|
||||
return await buildICALfromKey(parsed[1], onlyUpdate=False, testing=True)
|
||||
fileInURL = url.find("file=")
|
||||
kurs = url[fileInURL + 5:].upper()
|
||||
if url[-5:] != ".ical":
|
||||
try:
|
||||
async with httpx.AsyncClient() as s:
|
||||
response = await fetchPlan(s, url)
|
||||
if testing:
|
||||
assert "Vollmer" in response.text
|
||||
writeToFile(f"calendars/rapla{kurs}.ical", response)
|
||||
except urllib.error.URLError:
|
||||
return -1
|
||||
writeKursToDB(kurs, url)
|
||||
if testing:
|
||||
assert "TINF22B3" in Rapla.query.filter(Rapla.name == "TINF22B3").first().file
|
||||
return f"rapla{kurs}.ical"
|
||||
else:
|
||||
return url
|
||||
@ -159,11 +175,12 @@ def raplaSchedule():
|
||||
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.
|
||||
:param url:
|
||||
:param onlyUpdate:
|
||||
:param opt. testing:
|
||||
:return Dateinamen:
|
||||
"""
|
||||
async with httpx.AsyncClient() as s:
|
||||
@ -179,14 +196,18 @@ async def buildICALfromKey(url, onlyUpdate):
|
||||
return 200
|
||||
else:
|
||||
kursname = page.text[page.text.find("<title>") + 7:page.text.find("</title>")]
|
||||
if testing:
|
||||
assert "TMT22B1" in kursname
|
||||
if len(kursname) > 15:
|
||||
return 0
|
||||
start = "2024-08-01"
|
||||
end = "2024-12-31"
|
||||
start = f'{(datetime.now() - relativedelta(days=183)):%Y-%m-%d}'
|
||||
end = f'{(datetime.now() + relativedelta(days=183)):%Y-%m-%d}'
|
||||
payload = {"url": url, "start": start, "end": end}
|
||||
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)
|
||||
if testing:
|
||||
assert len(jsonresp) > 0
|
||||
cal = Calendar()
|
||||
cal.add('prodid', '-//Rapla//iCal Plugin//EN')
|
||||
cal.add('version', '2.0')
|
||||
@ -211,6 +232,8 @@ async def buildICALfromKey(url, onlyUpdate):
|
||||
f.close()
|
||||
if not onlyUpdate:
|
||||
writeKursToDB(kursname, url)
|
||||
if testing:
|
||||
assert "TMT22B1" in Rapla.query.filter(Rapla.name == "TMT22B1").first().file
|
||||
return f"rapla{kursname}.ical"
|
||||
else:
|
||||
return 200
|
||||
|
||||
@ -20,3 +20,5 @@ APScheduler
|
||||
cryptography
|
||||
python-dateutil~=2.9.0.post0
|
||||
requests~=2.31.0
|
||||
pytest
|
||||
pytest-asyncio
|
||||
@ -101,7 +101,7 @@ def initRoutes(app: Flask):
|
||||
s="p", praxis="hidden")
|
||||
|
||||
@app.route("/plan/<string:kurs>")
|
||||
async def displayPlan(kurs):
|
||||
async def displayPlan(kurs: str):
|
||||
"""
|
||||
Zeigt den Stundenplan ohne Login an. \n
|
||||
Präferenzen werden nicht berücksichtigt.
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import pytest
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
import fetchRAPLA
|
||||
import routing
|
||||
import init
|
||||
from tests_examples import login_data
|
||||
@ -45,7 +46,7 @@ def login(client):
|
||||
return False
|
||||
|
||||
|
||||
def test_login(client):
|
||||
def test_login_blackbox(client):
|
||||
"""
|
||||
Testet die Login-Funktion
|
||||
: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.
|
||||
|
||||
|
||||
def test_kurssetup(client):
|
||||
def test_kurssetup_blackbox(client):
|
||||
"""
|
||||
Testet die Konfiguration eines Kurses
|
||||
:param client:
|
||||
@ -86,7 +87,7 @@ def test_kurssetup(client):
|
||||
assert False
|
||||
|
||||
|
||||
def test_semestersetup(client):
|
||||
def test_semestersetup_blackbox(client):
|
||||
"""
|
||||
Testet die Konfiguration eines Semesters
|
||||
:param client:
|
||||
@ -106,7 +107,7 @@ def test_semestersetup(client):
|
||||
assert False
|
||||
|
||||
|
||||
def test_noten(client):
|
||||
def test_noten_blackbox(client):
|
||||
"""
|
||||
Testet das Abrufen der Noten aus zwei verschiedenen Semestern
|
||||
:param client:
|
||||
@ -134,7 +135,7 @@ def test_noten(client):
|
||||
assert False
|
||||
|
||||
|
||||
def test_logout(client):
|
||||
def test_logout_blackbox(client):
|
||||
"""
|
||||
Testet die Logout-Funktion
|
||||
: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
|
||||
else:
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user