$ErrorActionPreference = 'Stop' Add-Type -AssemblyName System.Net.Http $baseUrl = 'http://localhost:5099' $stamp = Get-Date -Format 'yyyyMMddHHmmss' $username = "smoke$stamp" $password = 'Demo123!' $session = Invoke-RestMethod ` -Uri "$baseUrl/api/auth/register" ` -Method Post ` -ContentType 'application/json' ` -Body (@{ username = $username displayName = 'Smoke Test' password = $password } | ConvertTo-Json) $refreshed = Invoke-RestMethod ` -Uri "$baseUrl/api/auth/refresh" ` -Method Post ` -ContentType 'application/json' ` -Body (@{ refreshToken = $session.refreshToken } | ConvertTo-Json) $headers = @{ Authorization = "Bearer $($refreshed.accessToken)" } $installationId = "push-$stamp" $pushDevice = Invoke-RestMethod ` -Uri "$baseUrl/api/push/devices" ` -Headers $headers ` -Method Post ` -ContentType 'application/json' ` -Body (@{ platform = 1 installationId = $installationId deviceToken = "token-$stamp" deviceName = "Smoke Android $stamp" notificationsEnabled = $true } | ConvertTo-Json) $pushDevicesAfterRegister = Invoke-RestMethod ` -Uri "$baseUrl/api/push/devices" ` -Headers $headers ` -Method Get if ($null -eq $pushDevicesAfterRegister) { $pushDevicesAfterRegister = @() } else { $pushDevicesAfterRegister = @($pushDevicesAfterRegister) } $bob = Invoke-RestMethod -Uri "$baseUrl/api/users/search?q=bob" -Headers $headers -Method Get | Select-Object -First 1 $channel = Invoke-RestMethod ` -Uri "$baseUrl/api/chats/channel" ` -Headers $headers ` -Method Post ` -ContentType 'application/json' ` -Body (@{ title = "Smoke Channel $stamp" memberIds = @($bob.id) } | ConvertTo-Json) $message = Invoke-RestMethod ` -Uri "$baseUrl/api/chats/$($channel.id)/messages" ` -Headers $headers ` -Method Post ` -ContentType 'application/json' ` -Body (@{ text = 'channel smoke message' } | ConvertTo-Json) $edited = Invoke-RestMethod ` -Uri "$baseUrl/api/chats/$($channel.id)/messages/$($message.id)" ` -Headers $headers ` -Method Put ` -ContentType 'application/json' ` -Body (@{ text = 'channel smoke message edited' } | ConvertTo-Json) $tempFile = Join-Path $env:TEMP "massenger-voice-$stamp.ogg" "voice smoke test $stamp" | Set-Content -Path $tempFile -NoNewline $handler = New-Object System.Net.Http.HttpClientHandler $client = New-Object System.Net.Http.HttpClient($handler) $client.BaseAddress = [Uri]::new("$baseUrl/") $client.DefaultRequestHeaders.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue('Bearer', $refreshed.accessToken) $form = New-Object System.Net.Http.MultipartFormDataContent $form.Add((New-Object System.Net.Http.StringContent('voice caption')), 'text') $fileStream = [System.IO.File]::OpenRead($tempFile) $fileContent = New-Object System.Net.Http.StreamContent($fileStream) $fileContent.Headers.ContentType = New-Object System.Net.Http.Headers.MediaTypeHeaderValue('audio/ogg') $form.Add($fileContent, 'file', [System.IO.Path]::GetFileName($tempFile)) $uploadResponse = $client.PostAsync("api/chats/$($channel.id)/attachments", $form).GetAwaiter().GetResult() $uploadPayload = $uploadResponse.Content.ReadAsStringAsync().GetAwaiter().GetResult() $fileStream.Dispose() $form.Dispose() $client.Dispose() $handler.Dispose() if (-not $uploadResponse.IsSuccessStatusCode) { throw $uploadPayload } $voiceMessage = $uploadPayload | ConvertFrom-Json $attachment = $voiceMessage.attachments[0] $downloadHandler = New-Object System.Net.Http.HttpClientHandler $downloadClient = New-Object System.Net.Http.HttpClient($downloadHandler) $downloadClient.BaseAddress = [Uri]::new("$baseUrl/") $downloadClient.DefaultRequestHeaders.Authorization = New-Object System.Net.Http.Headers.AuthenticationHeaderValue('Bearer', $refreshed.accessToken) $downloadResponse = $downloadClient.GetAsync($attachment.downloadPath.TrimStart('/')).GetAwaiter().GetResult() $downloadBytes = $downloadResponse.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult() $downloadClient.Dispose() $downloadHandler.Dispose() $deleted = Invoke-RestMethod ` -Uri "$baseUrl/api/chats/$($channel.id)/messages/$($message.id)" ` -Headers $headers ` -Method Delete $bobSession = Invoke-RestMethod ` -Uri "$baseUrl/api/auth/login" ` -Method Post ` -ContentType 'application/json' ` -Body (@{ username = 'bob' password = 'demo123' } | ConvertTo-Json) $bobHeaders = @{ Authorization = "Bearer $($bobSession.accessToken)" } $subscriberBlocked = $false try { Invoke-RestMethod ` -Uri "$baseUrl/api/chats/$($channel.id)/messages" ` -Headers $bobHeaders ` -Method Post ` -ContentType 'application/json' ` -Body (@{ text = 'subscriber should not publish' } | ConvertTo-Json) | Out-Null } catch { $subscriberBlocked = $_.Exception.Response.StatusCode.value__ -eq 403 } $channelForBob = Invoke-RestMethod -Uri "$baseUrl/api/chats/$($channel.id)" -Headers $bobHeaders -Method Get $channelReload = Invoke-RestMethod -Uri "$baseUrl/api/chats/$($channel.id)" -Headers $headers -Method Get Invoke-RestMethod -Uri "$baseUrl/api/push/devices/$installationId" -Headers $headers -Method Delete | Out-Null $pushDevicesAfterDelete = Invoke-RestMethod ` -Uri "$baseUrl/api/push/devices" ` -Headers $headers ` -Method Get if ($null -eq $pushDevicesAfterDelete) { $pushDevicesAfterDelete = @() } else { $pushDevicesAfterDelete = @($pushDevicesAfterDelete) } Invoke-RestMethod -Uri "$baseUrl/api/auth/logout" -Headers $headers -Method Post | Out-Null $logoutBlocked = $false try { Invoke-RestMethod -Uri "$baseUrl/api/users/me" -Headers $headers -Method Get | Out-Null } catch { $logoutBlocked = $_.Exception.Response.StatusCode.value__ -eq 401 } [pscustomobject]@{ Username = $username ChannelId = $channel.id EditedMessageId = $edited.id EditedText = $edited.text DeletedFlag = $null -ne $deleted.deletedAt VoiceAttachmentId = $attachment.id VoiceKind = $attachment.kind VoiceKindOk = ($attachment.kind -eq 2) -or ($attachment.kind -eq 'VoiceNote') DownloadOk = [int]$downloadResponse.StatusCode -eq 200 -and $downloadBytes.Length -eq $attachment.fileSizeBytes PushRegistered = $pushDevice.installationId -eq $installationId PushListed = $pushDevicesAfterRegister.Count -eq 1 -and $pushDevicesAfterRegister[0].installationId -eq $installationId PushDeleted = $pushDevicesAfterDelete.Count -eq 0 MessageCount = $channelReload.messages.Count SubscriberBlocked = $subscriberBlocked ChannelReadOnly = -not $channelForBob.canSendMessages RefreshRotated = $session.refreshToken -ne $refreshed.refreshToken LogoutBlocked = $logoutBlocked }