$ErrorActionPreference = 'Stop' $base = 'http://localhost:3000' $out = @() # 1. Health $h = Invoke-RestMethod "$base/api/health" $out += "health: ok=$($h.ok) users=$($h.users)" # 2. Register first user (should become admin); log in if it already exists $s = New-Object Microsoft.PowerShell.Commands.WebRequestSession try { $r = Invoke-RestMethod -Uri "$base/api/auth/register" -Method Post -ContentType 'application/json' -Body (@{username='admin1';password='password123'} | ConvertTo-Json) -WebSession $s $out += "register admin1: role=$($r.user.role)" } catch { $r = Invoke-RestMethod -Uri "$base/api/auth/login" -Method Post -ContentType 'application/json' -Body (@{username='admin1';password='password123'} | ConvertTo-Json) -WebSession $s $out += "login admin1 (already existed): role=$($r.user.role)" } # 3. Session check $m = Invoke-RestMethod -Uri "$base/api/auth/me" -WebSession $s $out += "me: $($m.user.username) ($($m.user.role))" # 4. Second user (should be plain user); log in if it already exists $s2 = New-Object Microsoft.PowerShell.Commands.WebRequestSession try { $r2 = Invoke-RestMethod -Uri "$base/api/auth/register" -Method Post -ContentType 'application/json' -Body (@{username='djbob';password='password456'} | ConvertTo-Json) -WebSession $s2 $out += "register djbob: role=$($r2.user.role)" } catch { $r2 = Invoke-RestMethod -Uri "$base/api/auth/login" -Method Post -ContentType 'application/json' -Body (@{username='djbob';password='password456'} | ConvertTo-Json) -WebSession $s2 $out += "login djbob (already existed): role=$($r2.user.role)" } # 5. Admin: list users $users = Invoke-RestMethod -Uri "$base/api/admin/users" -WebSession $s $out += "admin users list: $($users.users.Count) user(s)" # 6. Admin: create a profile, then clone to djbob $p = Invoke-RestMethod -Uri "$base/api/profiles" -Method Post -ContentType 'application/json' -Body (@{name=('Main FM ' + [guid]::NewGuid().ToString('N').Substring(0,6));host='127.0.0.1';port='3306';database='radiodj';dbUser='rdj';dbPassword='secret'} | ConvertTo-Json) -WebSession $s $out += "profile created: id=$($p.profile.id) name=$($p.profile.name)" $uid1 = ($users.users | Where-Object username -eq 'admin1').id $uid2 = ($users.users | Where-Object username -eq 'djbob').id $before = (Invoke-RestMethod -Uri "$base/api/profiles" -WebSession $s2).profiles.Count $c = Invoke-RestMethod -Uri "$base/api/admin/clone-profiles" -Method Post -ContentType 'application/json' -Body (@{fromUserId=$uid1;toUserId=$uid2} | ConvertTo-Json) -WebSession $s $out += "clone profiles: cloned=$($c.cloned)" $bobProfiles = Invoke-RestMethod -Uri "$base/api/profiles" -WebSession $s2 $out += "djbob profiles: $before -> $($bobProfiles.profiles.Count) after clone" # 7. Artwork search (iTunes, live) $search = Invoke-RestMethod -Uri "$base/api/artwork/search" -Method Post -ContentType 'application/json' -Body (@{artist='Adele';title='Hello'} | ConvertTo-Json) -WebSession $s $out += "artwork search: $($search.results.Count) result(s), first from $($search.results[0].source)" # 8. Export ZIP (no DB update) with the found artwork $exportBody = @{ profileId = $p.profile.id; updateDb = $false; items = @(@{ id = 999; path = 'D:\Music\Adele\01 Hello.mp3'; audioBase = '01 Hello'; imageUrl = $search.results[0].full }) } | ConvertTo-Json -Depth 5 Invoke-WebRequest -Uri "$base/api/export" -Method Post -ContentType 'application/json' -Body $exportBody -WebSession $s -OutFile "$PSScriptRoot\test-export.zip" Add-Type -AssemblyName System.IO.Compression.FileSystem $zip = [System.IO.Compression.ZipFile]::OpenRead("$PSScriptRoot\test-export.zip") $names = ($zip.Entries | ForEach-Object { $_.FullName }) -join ', ' $zip.Dispose() $out += "export zip entries: $names" # 9. Unauthenticated request should 401 try { Invoke-RestMethod -Uri "$base/api/profiles" -WebSession (New-Object Microsoft.PowerShell.Commands.WebRequestSession) $out += "UNAUTH CHECK FAILED" } catch { $out += "unauth /api/profiles correctly rejected ($($_.Exception.Response.StatusCode.value__))" } $out | ForEach-Object { Write-Host $_ } Write-Host "ALL SMOKE TESTS DONE"