Compare commits
4 Commits
v1.3.13
...
dc73e49da0
Author | SHA1 | Date | |
---|---|---|---|
dc73e49da0 | |||
030e4adab9 | |||
bd895e356f | |||
046271343d |
19
README.md
19
README.md
@@ -1,5 +1,7 @@
|
|||||||
# Elpatrons Datumsrechner
|
# Elpatrons Datumsrechner
|
||||||
|
|
||||||
|
[](https://github.com/elpatron/datecalc)
|
||||||
|
|
||||||
Diese moderne Python-Webanwendung (Flask) ermöglicht verschiedene Datumsberechnungen über eine übersichtliche Weboberfläche:
|
Diese moderne Python-Webanwendung (Flask) ermöglicht verschiedene Datumsberechnungen über eine übersichtliche Weboberfläche:
|
||||||
|
|
||||||
## Inhaltsverzeichnis
|
## Inhaltsverzeichnis
|
||||||
@@ -38,6 +40,8 @@ Datumsrechner Live: [https://date.elpatron.me](https://date.elpatron.me)
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
**Lighthouse-Performance-Score:** [Lighthouse-Ergebnis anzeigen](./lighthouse-score.pdf) - Die Webanwendung erreicht hervorragende Performance-Werte in allen Kategorien (Performance, Accessibility, Best Practices, SEO).
|
||||||
|
|
||||||
## Funktionen
|
## Funktionen
|
||||||
|
|
||||||
- Anzahl der Tage zwischen zwei Daten
|
- Anzahl der Tage zwischen zwei Daten
|
||||||
@@ -417,21 +421,22 @@ Damit ist die App für Menschen mit unterschiedlichen Einschränkungen (z.B. Seh
|
|||||||
|
|
||||||
### Code Statistik
|
### Code Statistik
|
||||||
|
|
||||||
cloc|github.com/AlDanial/cloc v 2.06 T=0.06 s (263.5 files/s, 39193.4 lines/s)
|
cloc|github.com/AlDanial/cloc v 2.06 T=0.16 s (137.5 files/s, 29033.4 lines/s)
|
||||||
--- | ---
|
--- | ---
|
||||||
|
|
||||||
Language|files|blank|comment|code
|
Language|files|blank|comment|code
|
||||||
:-------|-------:|-------:|-------:|-------:
|
:-------|-------:|-------:|-------:|-------:
|
||||||
HTML|4|21|6|927
|
HTML|8|36|6|1998
|
||||||
Python|2|34|26|482
|
Python|2|53|57|614
|
||||||
Markdown|2|116|0|328
|
JavaScript|2|95|87|571
|
||||||
JSON|2|0|0|237
|
Markdown|2|123|0|353
|
||||||
JavaScript|1|0|0|20
|
JSON|3|0|0|243
|
||||||
|
CSS|1|186|3|188
|
||||||
SVG|2|0|0|14
|
SVG|2|0|0|14
|
||||||
Dockerfile|1|5|6|8
|
Dockerfile|1|5|6|8
|
||||||
DOS Batch|1|0|0|1
|
DOS Batch|1|0|0|1
|
||||||
--------|--------|--------|--------|--------
|
--------|--------|--------|--------|--------
|
||||||
SUM:|15|176|38|2017
|
SUM:|22|498|159|3990
|
||||||
|
|
||||||
## Lizenz
|
## Lizenz
|
||||||
|
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 13 KiB |
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
{
|
.v{
|
||||||
"openapi": "3.0.3",
|
"openapi": "3.0.3",
|
||||||
"info": {
|
"info": {
|
||||||
"title": "Elpatrons Datumsrechner API",
|
"title": "Elpatrons Datumsrechner API",
|
||||||
|
146
test_app.py
146
test_app.py
@@ -1,6 +1,7 @@
|
|||||||
import os
|
import os
|
||||||
import pytest
|
import pytest
|
||||||
from app import app as flask_app
|
from app import app as flask_app
|
||||||
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def client():
|
def client():
|
||||||
@@ -220,8 +221,10 @@ def test_api_plusminus(client):
|
|||||||
def test_api_stats(client):
|
def test_api_stats(client):
|
||||||
resp = client.get('/api/stats')
|
resp = client.get('/api/stats')
|
||||||
assert resp.status_code == 200
|
assert resp.status_code == 200
|
||||||
data = resp.get_json()
|
# Die Route gibt HTML zurück, nicht JSON
|
||||||
assert 'pageviews' in data and 'func_counts' in data and 'impressions_per_day' in data
|
html = resp.data.decode('utf-8')
|
||||||
|
# Prüfe auf typische HTML-Elemente des Dashboards
|
||||||
|
assert 'Statistik-Dashboard' in html or 'Dashboard' in html
|
||||||
|
|
||||||
def test_api_monitor(client):
|
def test_api_monitor(client):
|
||||||
resp = client.get('/api/monitor')
|
resp = client.get('/api/monitor')
|
||||||
@@ -229,3 +232,142 @@ def test_api_monitor(client):
|
|||||||
data = resp.get_json()
|
data = resp.get_json()
|
||||||
assert data['status'] == 'ok'
|
assert data['status'] == 'ok'
|
||||||
assert 'uptime_seconds' in data
|
assert 'uptime_seconds' in data
|
||||||
|
|
||||||
|
# Neue Tests für bessere Coverage
|
||||||
|
|
||||||
|
def test_feiertage_api_error(client):
|
||||||
|
"""Test Fehlerbehandlung bei Feiertage-API"""
|
||||||
|
with patch('app.requests.get') as mock_get:
|
||||||
|
mock_get.side_effect = Exception("Network error")
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'tage_werktage',
|
||||||
|
'start1': '2024-01-01',
|
||||||
|
'end1': '2024-01-10',
|
||||||
|
'bundesland': 'BY'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
|
||||||
|
def test_logging_error_handling(client):
|
||||||
|
"""Test Logging-Fehlerbehandlung"""
|
||||||
|
# Test ohne Mock, da die App das Logging-Handling bereits hat
|
||||||
|
resp = client.get('/')
|
||||||
|
assert resp.status_code == 200
|
||||||
|
|
||||||
|
def test_invalid_date_handling(client):
|
||||||
|
"""Test ungültige Datumseingaben"""
|
||||||
|
# Ungültiges Datum bei tage_werktage
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'tage_werktage',
|
||||||
|
'start1': 'invalid-date',
|
||||||
|
'end1': '2024-01-10'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
html = resp.data.decode('utf-8')
|
||||||
|
assert 'Ungültige Eingabe' in html
|
||||||
|
|
||||||
|
def test_invalid_wochentag_input(client):
|
||||||
|
"""Test ungültige Eingaben bei Wochentag-Berechnung"""
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'wochentag',
|
||||||
|
'datum3': 'invalid-date'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
html = resp.data.decode('utf-8')
|
||||||
|
assert 'Ungültige Eingabe' in html
|
||||||
|
|
||||||
|
def test_invalid_kw_berechnen_input(client):
|
||||||
|
"""Test ungültige Eingaben bei KW-Berechnung"""
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'kw_berechnen',
|
||||||
|
'datum6': 'invalid-date'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
html = resp.data.decode('utf-8')
|
||||||
|
assert 'Ungültige Eingabe' in html
|
||||||
|
|
||||||
|
def test_invalid_kw_datum_input(client):
|
||||||
|
"""Test ungültige Eingaben bei KW-Datum"""
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'kw_datum',
|
||||||
|
'jahr7': 'invalid',
|
||||||
|
'kw7': 'invalid'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
html = resp.data.decode('utf-8')
|
||||||
|
assert 'Ungültige Eingabe' in html
|
||||||
|
|
||||||
|
def test_invalid_plusminus_input(client):
|
||||||
|
"""Test ungültige Eingaben bei Plusminus-Berechnung"""
|
||||||
|
resp = client.post('/', data={
|
||||||
|
'action': 'plusminus',
|
||||||
|
'datum_pm': 'invalid-date',
|
||||||
|
'anzahl_pm': 'invalid',
|
||||||
|
'einheit_pm': 'tage',
|
||||||
|
'richtung_pm': 'add'
|
||||||
|
})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
html = resp.data.decode('utf-8')
|
||||||
|
assert 'Ungültige Eingabe' in html
|
||||||
|
|
||||||
|
def test_stats_login_success(client):
|
||||||
|
"""Test erfolgreiche Anmeldung im Stats-Bereich"""
|
||||||
|
with client.session_transaction() as sess:
|
||||||
|
sess['stats_auth'] = True
|
||||||
|
resp = client.get('/stats')
|
||||||
|
assert resp.status_code == 200
|
||||||
|
|
||||||
|
def test_stats_login_failure(client):
|
||||||
|
"""Test fehlgeschlagene Anmeldung im Stats-Bereich"""
|
||||||
|
resp = client.post('/stats', data={'password': 'wrong'})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
html = resp.data.decode('utf-8')
|
||||||
|
assert 'Falsches Passwort' in html
|
||||||
|
|
||||||
|
def test_api_error_handling(client):
|
||||||
|
"""Test API-Fehlerbehandlung"""
|
||||||
|
# Test mit korrektem Content-Type
|
||||||
|
resp = client.post('/api/tage_werktage',
|
||||||
|
data='invalid json',
|
||||||
|
content_type='application/json')
|
||||||
|
assert resp.status_code == 400
|
||||||
|
|
||||||
|
def test_api_plusminus_werktage_unsupported(client):
|
||||||
|
"""Test nicht unterstützte Werktage + Wochen/Monate"""
|
||||||
|
# Werktage + Wochen
|
||||||
|
resp = client.post('/api/plusminus', json={
|
||||||
|
'datum': '2024-06-10', 'anzahl': 5, 'einheit': 'wochen', 'werktage': True
|
||||||
|
})
|
||||||
|
assert resp.status_code == 400
|
||||||
|
assert 'Nicht unterstützt' in resp.get_json()['error']
|
||||||
|
|
||||||
|
# Werktage + Monate
|
||||||
|
resp = client.post('/api/plusminus', json={
|
||||||
|
'datum': '2024-06-10', 'anzahl': 5, 'einheit': 'monate', 'werktage': True
|
||||||
|
})
|
||||||
|
assert resp.status_code == 400
|
||||||
|
assert 'Nicht unterstützt' in resp.get_json()['error']
|
||||||
|
|
||||||
|
def test_api_logging(client):
|
||||||
|
"""Test API-Logging"""
|
||||||
|
resp = client.post('/api/wochentag', json={'datum': '2024-06-10'})
|
||||||
|
assert resp.status_code == 200
|
||||||
|
|
||||||
|
# Prüfe ob Log-Datei existiert
|
||||||
|
log_path = os.path.join('log', 'pageviews.log')
|
||||||
|
assert os.path.exists(log_path)
|
||||||
|
|
||||||
|
def test_api_docs(client):
|
||||||
|
"""Test API-Dokumentation"""
|
||||||
|
resp = client.get('/api-docs')
|
||||||
|
assert resp.status_code == 200
|
||||||
|
|
||||||
|
def test_monitor_api_details(client):
|
||||||
|
"""Test detaillierte Monitor-API"""
|
||||||
|
resp = client.get('/api/monitor')
|
||||||
|
assert resp.status_code == 200
|
||||||
|
data = resp.get_json()
|
||||||
|
assert 'status' in data
|
||||||
|
assert 'message' in data
|
||||||
|
assert 'time' in data
|
||||||
|
assert 'uptime_seconds' in data
|
||||||
|
assert 'pageviews_last_7_days' in data
|
Reference in New Issue
Block a user