#!/bin/bash # ProostenKrant end-to-end regressietest (draait tegen een draaiende stack op localhost:8080). # Gebruik: docker compose up -d && scripts/e2e-test.sh # Let op: de test maakt artikelen aan in de database en drukt een proefeditie. set -u # ProostenKrant end-to-end test set -u BASE=http://localhost:8080 JAR=/tmp/krant.cookies PASS="ProostenKrant2024!" PASS_FAILED=0 ok() { echo "PASS: $1"; } fail() { echo "FAIL: $1"; PASS_FAILED=1; } check() { # desc, expected, actual if [ "$2" = "$3" ]; then ok "$1"; else fail "$1 (expected [$2], got [$3])"; fi } contains() { # desc, file, pattern if grep -q "$3" "$2"; then ok "$1"; else fail "$1 (pattern '$3' not found in $2)"; fi } notcontains() { if ! grep -q "$3" "$2"; then ok "$1"; else fail "$1 (unexpected pattern '$3' in $2)"; fi } get_token() { # url, outfile -> sets TOKEN curl -s -b "$JAR" -c "$JAR" "$BASE$1" -o "$2" TOKEN=$(grep -o 'name="__RequestVerificationToken"[^>]*value="[^"]*"' "$2" | head -1 | sed 's/.*value="//;s/"$//') HANDLER=$(grep -o 'name="_handler" value="[^"]*"' "$2" | head -1 | sed 's/.*value="//;s/"$//') } echo "=== 1. Publieke pagina's (anoniem) ===" for p in "/" "/archief" "/indienen" "/login"; do code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE$p") check "GET $p" 200 "$code" done code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/dashboard") check "GET /dashboard anoniem -> 302" 302 "$code" echo "=== 2. Inloggen ===" rm -f "$JAR" get_token "/login" /tmp/t_login.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/login" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Username=douwe" \ --data-urlencode "Input.Password=$PASS" \ --data-urlencode "__RequestVerificationToken=$TOKEN" \ -o /dev/null -w "" code=$(curl -s -b "$JAR" -o /tmp/t_dash.html -w "%{http_code}" "$BASE/dashboard") check "GET /dashboard ingelogd" 200 "$code" contains "dashboard toont welkom" /tmp/t_dash.html "Welkom, Douwe" contains "dashboard toont stats" /tmp/t_dash.html "Kladartikelen" echo "=== 2b. Fout wachtwoord ===" rm -f "$JAR" get_token "/login" /tmp/t_login.html resp=$(curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/login" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Username=douwe" \ --data-urlencode "Input.Password=fout" \ --data-urlencode "__RequestVerificationToken=$TOKEN" -o /tmp/t_loginbad.html -w "%{http_code}") check "POST login met fout wachtwoord -> 200 met foutmelding" 200 "$resp" contains "foutmelding tonen" /tmp/t_loginbad.html "Ongeldige gebruikersnaam of wachtwoord" echo "=== 3. Opnieuw inloggen + artikel maken (redactie) ===" rm -f "$JAR" get_token "/login" /tmp/t_login.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/login" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Username=douwe" \ --data-urlencode "Input.Password=$PASS" \ --data-urlencode "__RequestVerificationToken=$TOKEN" -o /dev/null get_token "/artikelen/nieuw" /tmp/t_nieuw.html code=$(curl -s -b "$JAR" -X POST "$BASE/artikelen/nieuw" \ -F "_handler=$HANDLER" \ -F "Input.Title=Eerste artikel in de Blazor-krant" \ -F "Input.Content=Dit is de eerste testcase. De ProostenKrant is nu een Blazor-applicatie en dit artikel moet netjes in de database belanden." \ -F "Input.WriterId=1" \ -F "Input.EventDate=2026-10-01" \ -F "Input.SeasonId=3" \ -F "Input.Status=published" \ -F "Participants=1" -F "Participants=2" \ -F "Afbeelding=@/home/douwe/Projects/proostenkrant.net/app/public/images/articles/Marathon.jpg" \ -F "__RequestVerificationToken=$TOKEN" \ -o /dev/null -w "%{http_code}") check "POST nieuw artikel -> 302" 302 "$code" curl -s -b "$JAR" "$BASE/artikelen" -o /tmp/t_lijst.html contains "artikel staat in de lijst" /tmp/t_lijst.html "Eerste artikel in de Blazor-krant" echo "=== 4. Artikeldetail (publiek voor published) ===" NIEUWID=$(grep -o 'href="/artikelen/[0-9]*">Eerste artikel in de Blazor-krant' /tmp/t_lijst.html | grep -o '[0-9]*' | head -1) code=$(curl -s -o /tmp/t_art.html -w "%{http_code}" "$BASE/artikelen/$NIEUWID") check "GET /artikelen/$NIEUWID anoniem" 200 "$code" contains "artikelkop" /tmp/t_art.html "Eerste artikel in de Blazor-krant" contains "deelnemers avatars" /tmp/t_art.html "participant-avatar" if grep -q "uploads/articles" /tmp/t_art.html; then ok "artikelafbeelding geupload"; else fail "artikelafbeelding geupload"; fi echo "=== 5. Seizoenen + PDF genereren ===" curl -s -b "$JAR" "$BASE/seizoenen" -o /tmp/t_seizoenen.html contains "seizoenenoverzicht" /tmp/t_seizoenen.html "Druk deze editie" get_token "/seizoenen" /tmp/t_seizoenen.html code=$(curl -s -b "$JAR" -X POST "$BASE/api/genereer-pdf" \ -F "SeizoenId=3" \ -F "__RequestVerificationToken=$TOKEN" \ -o /dev/null -w "%{http_code}" --max-time 240) check "POST druk Herfst-editie -> 302" 302 "$code" PDF=$(ls -t /home/douwe/Projects/proostenkrant.net/app/storage/latex/*.pdf 2>/dev/null | head -1) if [ -n "$PDF" ] && [ -f "$PDF" ]; then ok "PDF gegenereerd: $(basename "$PDF")"; else fail "PDF gegenereerd"; PDF=""; fi if [ -n "$PDF" ]; then head -c 4 "$PDF" | grep -q "%PDF" && ok "PDF header geldig" || fail "PDF header geldig" size=$(stat -c%s "$PDF") [ "$size" -gt 20000 ] && ok "PDF grootte redelijk ($size b)" || fail "PDF grootte ($size b)" fi echo "=== 6. Editie downloaden en archief ===" if [ -n "$PDF" ]; then code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/edities/$(basename "$PDF")") check "GET /edities/PDF" 200 "$code" fi curl -s "$BASE/archief" -o /tmp/t_archief.html contains "archief toont editie" /tmp/t_archief.html "ProostenKrant" contains "archief toont gepubliceerd artikel" /tmp/t_archief.html "Eerste artikel in de Blazor-krant" echo "" echo "=== RESULTAAT DEEL 1: $([ $PASS_FAILED = 0 ] && echo ALLES GESLAAGD || echo FOUTEN GEVONDEN) ===" echo "" rm -f /tmp/krant.cookies2 # ProostenKrant end-to-end test — deel 2: inzendflow, bewerkflow, uitloggen set -u BASE=http://localhost:8080 JAR=/tmp/krant.cookies2 PASS="ProostenKrant2024!" PASS_FAILED=0 ok() { echo "PASS: $1"; } fail() { echo "FAIL: $1"; PASS_FAILED=1; } check() { if [ "$2" = "$3" ]; then ok "$1"; else fail "$1 (expected [$2], got [$3])"; fi; } contains() { if grep -q "$3" "$2"; then ok "$1"; else fail "$1 (pattern '$3' niet in $2)"; fi; } get_token() { curl -s -b "$JAR" -c "$JAR" "$BASE$1" -o "$2" TOKEN=$(grep -o 'name="__RequestVerificationToken"[^>]*value="[^"]*"' "$2" | head -1 | sed 's/.*value="//;s/"$//') HANDLER=$(grep -o 'name="_handler" value="[^"]*"' "$2" | head -1 | sed 's/.*value="//;s/"$//') } echo "=== 7. Inzendflow: paszin ===" rm -f "$JAR" code=$(curl -s -o /dev/null -w "%{http_code}" "$BASE/indienen/formulier") check "formulier zonder paszin -> redirect (302)" 302 "$code" get_token "/indienen" /tmp/u_ind.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Paszin=foutezin" \ --data-urlencode "__RequestVerificationToken=$TOKEN" \ -o /tmp/u_ind_bad.html contains "foute paszin -> foutmelding" /tmp/u_ind_bad.html "Onjuiste paszin" get_token "/indienen" /tmp/u_ind.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Paszin=$PASS" \ --data-urlencode "__RequestVerificationToken=$TOKEN" \ -o /dev/null -w "" -D /tmp/u_ind_ok.headers contains "juiste paszin -> cookie" /tmp/u_ind_ok.headers "ProostenKrant=" code=$(curl -s -b "$JAR" -o /tmp/u_form.html -w "%{http_code}" "$BASE/indienen/formulier") check "formulier met paszin -> 200" 200 "$code" contains "formulier toont titelveld" /tmp/u_form.html "Titel" echo "=== 8. Inzendflow: artikel indienen met foto ===" get_token "/indienen/formulier" /tmp/u_form.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen/formulier" \ -F "_handler=$HANDLER" \ -F "Input.Title=Een dagje aan zee" \ -F "Input.Content=We gingen met de hele familie naar Blankenberge. Het was prachtig weer en de zee was kalm. Iedereen heeft genoten van de dag." \ -F "Input.WriterId=2" \ -F "Input.EventDate=2026-10-05" \ -F "Participants=2" -F "Participants=3" \ -F "Afbeelding=@/tmp/blankenberge.jpg" \ -F "__RequestVerificationToken=$TOKEN" \ -o /dev/null -D /tmp/u_post.h -w "" loc=$(grep -i "^location" /tmp/u_post.h | tr -d '\r' | awk '{print $2}') echo "redirect: $loc" contains "redirect naar bevestiging" /tmp/u_post.h "indienen/bevestiging" curl -s "$loc" -o /tmp/u_bev.html contains "bevestiging toont titel" /tmp/u_bev.html "Een dagje aan zee" ARTID=$(echo "$loc" | grep -o "artikel=[0-9]*" | cut -d= -f2) echo "nieuw artikel-id: $ARTID" echo "=== 9. Cookie verlopen na indienen ===" code=$(curl -s -b "$JAR" -o /dev/null -w "%{http_code}" "$BASE/indienen/formulier") check "formulier opnieuw -> redirect (cookie weg)" 302 "$code" echo "=== 10. Bewerkflow: paszin -> lijst -> schrijver verificatie ===" rm -f "$JAR" get_token "/indienen/bewerken" /tmp/u_bp.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen/bewerken" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Paszin=$PASS" \ --data-urlencode "__RequestVerificationToken=$TOKEN" \ -o /dev/null curl -s -b "$JAR" "$BASE/indienen/bewerken/lijst" -o /tmp/u_lijst.html contains "lijst toont kladartikel" /tmp/u_lijst.html "Een dagje aan zee" echo "--- foute schrijver (id 1, echte schrijver is 2) ---" get_token "/indienen/bewerken/$ARTID" /tmp/u_ver.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen/bewerken/$ARTID" \ -F "_handler=$HANDLER" \ -F "Input.WriterId=1" \ -F "__RequestVerificationToken=$TOKEN" \ -o /tmp/u_ver_fout.html -w "foute POST status: %{http_code}\n" contains "verkeerde schrijver geweigerd" /tmp/u_ver_fout.html "Alleen de schrijver" echo "--- juiste schrijver (id 2) ---" get_token "/indienen/bewerken/$ARTID" /tmp/u_ver.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen/bewerken/$ARTID" \ -F "_handler=$HANDLER" \ -F "Input.WriterId=2" \ -F "__RequestVerificationToken=$TOKEN" \ -o /dev/null -D /tmp/u_ver_ok.h -w "juiste POST status: %{http_code}\n" loc=$(grep -i "^location" /tmp/u_ver_ok.h | tr -d '\r' | awk '{print $2}') echo "redirect: $loc" curl -s -b "$JAR" "$loc" -o /tmp/u_edit.html contains "bewerkformulier toont bestaande titel" /tmp/u_edit.html "Een dagje aan zee" contains "bewerkformulier staat in bewerkmodus" /tmp/u_edit.html "Artikel bewerken" echo "--- wijzig opslaan ---" get_token "/indienen/formulier" /tmp/u_edit.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/indienen/formulier" \ -F "_handler=$HANDLER" \ -F "Input.Title=Een dagje aan zee (ge-edit)" \ -F "Input.Content=We gingen met de hele familie naar Blankenberge. Het was prachtig weer en de zee was kalm. Iedereen heeft genoten van de dag. Update: het artikel is bewerkt." \ -F "Input.WriterId=2" \ -F "Input.EventDate=2026-10-05" \ -F "Participants=2" \ -F "__RequestVerificationToken=$TOKEN" \ -o /dev/null -D /tmp/u_edit_post.h contains "wijziging doorgestuurd" /tmp/u_edit_post.h "indienen/bevestiging" echo "=== 11. Redactie ziet nieuwe kladartikelen ===" rm -f "$JAR" get_token "/login" /tmp/u_login.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/login" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "Input.Username=douwe" \ --data-urlencode "Input.Password=$PASS" \ --data-urlencode "__RequestVerificationToken=$TOKEN" -o /dev/null curl -s -b "$JAR" "$BASE/artikelen?status=draft" -o /tmp/u_drafts.html contains "klad-overzicht toont bewerkte titel" /tmp/u_drafts.html "Een dagje aan zee (ge-edit)" echo "=== 12. Uitloggen ===" get_token "/uitloggen" /tmp/u_uit.html curl -s -b "$JAR" -c "$JAR" -X POST "$BASE/uitloggen" \ --data-urlencode "_handler=$HANDLER" \ --data-urlencode "__RequestVerificationToken=$TOKEN" \ -o /dev/null -w "" -D /tmp/u_uit.h code=$(curl -s -b "$JAR" -o /dev/null -w "%{http_code}" "$BASE/dashboard") check "dashboard na uitloggen -> 302" 302 "$code" echo "" echo "=== RESULTAAT DEEL 2: $([ $PASS_FAILED = 0 ] && echo ALLES GESLAAGD || echo FOUTEN GEVONDEN) ===" exit $PASS_FAILED