diff --git a/.github/workflows/ci-release.yml b/.github/workflows/ci-release.yml new file mode 100644 index 00000000..b980f9cd --- /dev/null +++ b/.github/workflows/ci-release.yml @@ -0,0 +1,165 @@ +name: CI and Release + +on: + pull_request: + branches: + - main + paths-ignore: + - docs/** + push: + branches: + - main + tags: + - v3.* + +permissions: + id-token: write + contents: read + +env: + BUILD_CONFIGURATION: Release + DOTNET_SKIP_FIRST_TIME_EXPERIENCE: true + DOTNET_CLI_TELEMETRY_OPTOUT: true + NUGET_OUTPUT_DIR: artifacts/nuget + +jobs: + build-test-pack: + runs-on: windows-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup .NET SDK from global.json + uses: actions/setup-dotnet@v4 + with: + global-json-file: src/global.json + + - name: Restore + run: dotnet restore src/ZendeskApi_v2.sln + + - name: Build + run: dotnet build src/ZendeskApi_v2.sln --configuration ${{ env.BUILD_CONFIGURATION }} --no-restore + env: + TF_BUILD: true + + - name: Test (with Zendesk credentials) + if: ${{ secrets.ADMIN_ID != '' && secrets.ADMIN_EMAIL != '' && secrets.ADMIN_API_TOKEN != '' }} + run: dotnet test tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj --configuration ${{ env.BUILD_CONFIGURATION }} --no-build + env: + admin__id: ${{ secrets.ADMIN_ID }} + admin__email: ${{ secrets.ADMIN_EMAIL }} + admin__password: not-used + admin__apiToken: ${{ secrets.ADMIN_API_TOKEN }} + + - name: Test skipped notice + if: ${{ secrets.ADMIN_ID == '' || secrets.ADMIN_EMAIL == '' || secrets.ADMIN_API_TOKEN == '' }} + shell: pwsh + run: | + Write-Host "Zendesk integration tests were skipped because required secrets are missing." + Write-Host "Set ADMIN_ID, ADMIN_EMAIL, and ADMIN_API_TOKEN to enable test execution in CI." + + - name: Pack + run: dotnet pack src/ZendeskApi_v2/ZendeskApi_v2.csproj --configuration ${{ env.BUILD_CONFIGURATION }} --no-build --output ${{ env.NUGET_OUTPUT_DIR }} + env: + TF_BUILD: true + + - name: Upload packages + uses: actions/upload-artifact@v4 + with: + name: nuget-packages + path: | + ${{ env.NUGET_OUTPUT_DIR }}/*.nupkg + ${{ env.NUGET_OUTPUT_DIR }}/*.snupkg + + publish: + needs: build-test-pack + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v3.')) }} + runs-on: windows-latest + permissions: + id-token: write + contents: write + packages: write + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download packages + uses: actions/download-artifact@v4 + with: + name: nuget-packages + path: artifacts/nuget + + - name: Determine prerelease + id: prerelease + shell: pwsh + run: | + $packages = Get-ChildItem "artifacts/nuget/*.nupkg" | Where-Object { -not $_.Name.EndsWith(".symbols.nupkg") } + if (-not $packages) { + throw "No NuGet package found to publish." + } + + $packageName = $packages[0].Name + $versionMatch = [regex]::Match($packageName, '\\d+\\.\\d+\\.\\d+(?:\\.\\d+)?(?:[-+][^\\.]+(?:\\.[^\\.]+)*)?') + if (-not $versionMatch.Success) { + throw "Unable to parse package version from $packageName" + } + + $version = $versionMatch.Value + $isPrerelease = $version.Contains("-") -or $version.Contains("+") + + "package_version=$version" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + "is_prerelease=$($isPrerelease.ToString().ToLowerInvariant())" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + "release_date=$(Get-Date -Format 'dd MMMM yyyy')" | Out-File -FilePath $env:GITHUB_OUTPUT -Append + + - name: Azure login (OIDC federated identity) + if: ${{ secrets.AZURE_TENANT_ID != '' && secrets.AZURE_CLIENT_ID != '' && secrets.AZURE_SUBSCRIPTION_ID != '' && secrets.AZURE_TRUSTED_SIGNING_ENDPOINT != '' && secrets.AZURE_TRUSTED_SIGNING_ACCOUNT != '' && secrets.AZURE_TRUSTED_SIGNING_PROFILE != '' }} + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Sign packages with Azure Artifact Signing + if: ${{ secrets.AZURE_TENANT_ID != '' && secrets.AZURE_CLIENT_ID != '' && secrets.AZURE_SUBSCRIPTION_ID != '' && secrets.AZURE_TRUSTED_SIGNING_ENDPOINT != '' && secrets.AZURE_TRUSTED_SIGNING_ACCOUNT != '' && secrets.AZURE_TRUSTED_SIGNING_PROFILE != '' }} + uses: azure/trusted-signing-action@v0 + with: + endpoint: ${{ secrets.AZURE_TRUSTED_SIGNING_ENDPOINT }} + signing-account-name: ${{ secrets.AZURE_TRUSTED_SIGNING_ACCOUNT }} + certificate-profile-name: ${{ secrets.AZURE_TRUSTED_SIGNING_PROFILE }} + files-folder: ${{ github.workspace }}\artifacts\nuget + files-folder-filter: nupkg + + - name: Fail publish when signing config is missing + if: ${{ secrets.AZURE_TENANT_ID == '' || secrets.AZURE_CLIENT_ID == '' || secrets.AZURE_SUBSCRIPTION_ID == '' || secrets.AZURE_TRUSTED_SIGNING_ENDPOINT == '' || secrets.AZURE_TRUSTED_SIGNING_ACCOUNT == '' || secrets.AZURE_TRUSTED_SIGNING_PROFILE == '' }} + shell: pwsh + run: | + throw "Azure Artifact Signing federated identity configuration is incomplete. Set AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_SUBSCRIPTION_ID, AZURE_TRUSTED_SIGNING_ENDPOINT, AZURE_TRUSTED_SIGNING_ACCOUNT, and AZURE_TRUSTED_SIGNING_PROFILE." + + - name: Publish prerelease to GitHub Packages + if: ${{ steps.prerelease.outputs.is_prerelease == 'true' && secrets.GITHUB_FEED_URL != '' && secrets.GITHUB_FEED_API_KEY != '' }} + shell: pwsh + run: dotnet nuget push "artifacts/nuget/*.nupkg" --skip-duplicate --api-key "${{ secrets.GITHUB_FEED_API_KEY }}" --source "${{ secrets.GITHUB_FEED_URL }}" + + - name: Publish prerelease to MyGet + if: ${{ steps.prerelease.outputs.is_prerelease == 'true' && secrets.MYGET_FEED_URL != '' && secrets.MYGET_API_KEY != '' }} + shell: pwsh + run: dotnet nuget push "artifacts/nuget/*.nupkg" --skip-duplicate --api-key "${{ secrets.MYGET_API_KEY }}" --source "${{ secrets.MYGET_FEED_URL }}" + + - name: Publish stable to NuGet.org + if: ${{ startsWith(github.ref, 'refs/tags/v3.') && steps.prerelease.outputs.is_prerelease == 'false' && secrets.NUGET_API_KEY != '' }} + shell: pwsh + run: dotnet nuget push "artifacts/nuget/*.nupkg" --skip-duplicate --api-key "${{ secrets.NUGET_API_KEY }}" --source "https://api.nuget.org/v3/index.json" + + - name: Create GitHub Release (draft) + if: ${{ startsWith(github.ref, 'refs/tags/v3.') && steps.prerelease.outputs.is_prerelease == 'false' }} + uses: softprops/action-gh-release@v2 + with: + draft: true + name: ${{ steps.prerelease.outputs.package_version }} (${{ steps.prerelease.outputs.release_date }}) + files: | + artifacts/nuget/*.nupkg + artifacts/nuget/*.snupkg \ No newline at end of file diff --git a/.github/workflows/deploy-infrastructure.yml b/.github/workflows/deploy-infrastructure.yml new file mode 100644 index 00000000..f73620dd --- /dev/null +++ b/.github/workflows/deploy-infrastructure.yml @@ -0,0 +1,92 @@ +name: Deploy Infrastructure (Prod) + +on: + workflow_dispatch: + inputs: + phase: + description: Deployment phase (bootstrap creates RG/account, finalize creates certificate profile) + required: true + default: bootstrap + type: choice + options: + - bootstrap + - finalize + - full + deployment_location: + description: Azure region for subscription deployment metadata + required: true + default: eastus + type: string + identity_validation_id: + description: Identity validation ID required for finalize/full phase certificate profile creation + required: false + type: string + +permissions: + id-token: write + contents: read + +jobs: + deploy-prod: + runs-on: ubuntu-latest + environment: prod + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Azure login (OIDC) + uses: azure/login@v2 + with: + client-id: ${{ secrets.AZURE_CLIENT_ID }} + tenant-id: ${{ secrets.AZURE_TENANT_ID }} + subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }} + + - name: Register Azure Artifact Signing provider + shell: bash + run: az provider register --namespace Microsoft.CodeSigning --wait + + - name: Resolve phase parameters + id: phase + shell: bash + run: | + phase="${{ inputs.phase }}" + identityValidationId="${{ inputs.identity_validation_id }}" + + if [[ "$phase" == "bootstrap" ]]; then + echo "create_certificate_profile=false" >> "$GITHUB_OUTPUT" + echo "identity_validation_id=" >> "$GITHUB_OUTPUT" + exit 0 + fi + + if [[ -z "$identityValidationId" ]]; then + echo "identity_validation_id input is required for '$phase' phase" >&2 + exit 1 + fi + + echo "create_certificate_profile=true" >> "$GITHUB_OUTPUT" + echo "identity_validation_id=$identityValidationId" >> "$GITHUB_OUTPUT" + + - name: Validate template with what-if + shell: bash + run: | + az deployment sub what-if \ + --name "zendeskapi-prod-${{ github.run_id }}" \ + --location "${{ inputs.deployment_location }}" \ + --template-file infra/main.bicep \ + --parameters @infra/parameters/prod.parameters.json \ + location="${{ inputs.deployment_location }}" \ + createCertificateProfile=${{ steps.phase.outputs.create_certificate_profile }} \ + identityValidationId="${{ steps.phase.outputs.identity_validation_id }}" + + - name: Deploy template + shell: bash + run: | + az deployment sub create \ + --name "zendeskapi-prod-${{ github.run_id }}" \ + --location "${{ inputs.deployment_location }}" \ + --template-file infra/main.bicep \ + --parameters @infra/parameters/prod.parameters.json \ + location="${{ inputs.deployment_location }}" \ + createCertificateProfile=${{ steps.phase.outputs.create_certificate_profile }} \ + identityValidationId="${{ steps.phase.outputs.identity_validation_id }}" \ No newline at end of file diff --git a/README.md b/README.md index 607f2314..3717f405 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ [![CodeFactor](https://www.codefactor.io/repository/github/speedygeek/zendeskapi_v2/badge)](https://www.codefactor.io/repository/github/speedygeek/zendeskapi_v2) [![Build Status](https://dev.azure.com/speedygeek/Zendesk/_apis/build/status/Speedygeek.ZendeskApi_v2?branchName=main)](https://dev.azure.com/speedygeek/Zendesk/_build/latest?definitionId=15&branchName=main) +[![CI and Release](https://github.com/Speedygeek/ZendeskApi_v2/actions/workflows/ci-release.yml/badge.svg?branch=main)](https://github.com/Speedygeek/ZendeskApi_v2/actions/workflows/ci-release.yml) | Prerelease | Stable | |---|---| @@ -20,6 +21,10 @@ about the client please feel to ask them in our [GitHub Discussions][discussions If you have questions about your account or the api its self please contact the zendesk team at [api@zendesk.com](mailto:api@zendesk.com) +## CI/CD Documentation + +CI/CD and signing documentation has moved to `docs/ci-cd.md`. + ## Contributing Any and all are welcome to contribute to this project. diff --git a/ci/azure-pipelines.yml b/ci/azure-pipelines.yml index 351ba38e..2e6ca026 100644 --- a/ci/azure-pipelines.yml +++ b/ci/azure-pipelines.yml @@ -5,13 +5,14 @@ resources: - repo: self + variables: - name: BuildConfiguration value: 'Release' - name: TF_BUILD value: 'true' - #- name: System.Debug - # value: true + - name: System.Debug + value: true - name: DOTNET_CLI_TELEMETRY_OPTOUT value: true - name: DOTNET_SKIP_FIRST_TIME_EXPERIENCE @@ -19,19 +20,9 @@ variables: - group: GitHub_Feed - group: Zendesk_Creds -trigger: - batch: true - branches: - include: - - main - - refs/tags/* -pr: - branches: - include: - - main - paths: - exclude: - - docs/* +# Disabled: CI/CD moved to GitHub Actions workflows under .github/workflows. +trigger: none +pr: none pool: vmImage: 'windows-latest' @@ -65,7 +56,7 @@ jobs: env: admin__id: $(Admin.ID) admin__email: $(Admin.Email) - admin__password: $(Admin.Password) + admin__password: "not used nay more" admin__apiToken: $(Admin.ApiToken) - task: DotNetCoreCLI@2 diff --git a/docs/ci-cd.md b/docs/ci-cd.md new file mode 100644 index 00000000..ff0d9d90 --- /dev/null +++ b/docs/ci-cd.md @@ -0,0 +1,41 @@ +# CI/CD and Signing + +Build, package, signing, and publishing are managed in GitHub Actions: + +1. `.github/workflows/ci-release.yml` +2. `.github/workflows/deploy-infrastructure.yml` + +The legacy Azure DevOps pipeline in `ci/azure-pipelines.yml` is disabled (`trigger: none`, `pr: none`) and retained only as historical reference. + +## Required Signing Secrets + +Configure these repository or environment secrets for Azure Artifact Signing with federated identity: + +1. `AZURE_TENANT_ID` +2. `AZURE_CLIENT_ID` +3. `AZURE_SUBSCRIPTION_ID` +4. `AZURE_TRUSTED_SIGNING_ENDPOINT` +5. `AZURE_TRUSTED_SIGNING_ACCOUNT` +6. `AZURE_TRUSTED_SIGNING_PROFILE` + +The workflows use OIDC via `azure/login@v2`. Configure a federated credential on the Microsoft Entra application backing `AZURE_CLIENT_ID` for this repository/environment. + +## Package Publish Secrets + +1. `NUGET_API_KEY` (stable tag releases) +2. `GITHUB_FEED_URL` and `GITHUB_FEED_API_KEY` (prerelease feed) +3. `MYGET_FEED_URL` and `MYGET_API_KEY` (prerelease feed) + +## Test Secrets + +Integration tests require: + +1. `ADMIN_ID` +2. `ADMIN_EMAIL` +3. `ADMIN_API_TOKEN` + +If test secrets are missing, the workflow skips integration tests and logs a notice. + +## Related Docs + +Infrastructure-specific documentation lives in `infra/README.md`. \ No newline at end of file diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 00000000..1fd8f75a --- /dev/null +++ b/infra/README.md @@ -0,0 +1,53 @@ +# Infrastructure Documentation + +This folder contains all infrastructure-as-code and operations notes for production deployment and artifact-signing lifecycle. + +## Deployment Scope + +Production infrastructure deployment is manual-only through `.github/workflows/deploy-infrastructure.yml` and uses: + +1. `infra/main.bicep` +2. `infra/modules/signing-resources.bicep` +3. `infra/parameters/prod.parameters.json` + +The deployment workflow runs subscription-scope deployment and does the following: + +1. Registers `Microsoft.CodeSigning` resource provider. +2. Creates or updates the configured production resource group. +3. Creates or updates Azure Artifact Signing account and certificate profile. +4. Executes `az deployment sub what-if` before `az deployment sub create`. + +## Phased Deployment Model + +The deployment workflow supports explicit phases to handle human identity-verification dependencies: + +1. `bootstrap` + 1. Creates or updates resource group and artifact signing account. + 2. Does not create certificate profile. +2. `finalize` + 1. Creates or updates certificate profile after identity verification is completed by a human. + 2. Requires `identity_validation_id` workflow input. +3. `full` + 1. Executes bootstrap and finalize behavior in one run. + 2. Requires `identity_validation_id` workflow input. + +Default safe behavior is bootstrap-only. `infra/parameters/prod.parameters.json` sets `createCertificateProfile` to `false` and `identityValidationId` to empty. + +## Authentication Model + +Infrastructure and signing workflows use OIDC federation via `azure/login@v2`. + +Required Azure-related repository or environment secrets: + +1. `AZURE_TENANT_ID` +2. `AZURE_CLIENT_ID` +3. `AZURE_SUBSCRIPTION_ID` +4. `AZURE_TRUSTED_SIGNING_ENDPOINT` +5. `AZURE_TRUSTED_SIGNING_ACCOUNT` +6. `AZURE_TRUSTED_SIGNING_PROFILE` + +Configure a federated credential on the Microsoft Entra application backing `AZURE_CLIENT_ID` for this repository/environment. + +## Legacy Signing Cleanup + +Use `infra/signing-azure-cleanup.md` to track and remove no-longer-needed Azure resources from the retired signing implementation. \ No newline at end of file diff --git a/infra/main.bicep b/infra/main.bicep new file mode 100644 index 00000000..bdb109da --- /dev/null +++ b/infra/main.bicep @@ -0,0 +1,71 @@ +targetScope = 'subscription' + +@description('Location used for subscription deployment metadata.') +param location string = deployment().location + +@description('Name of the resource group that will host artifact signing resources.') +param resourceGroupName string + +@description('Location of the resource group. Defaults to deployment location.') +param resourceGroupLocation string = location + +@description('Azure Artifact Signing account name.') +param codeSigningAccountName string + +@description('Certificate profile name used by the signing workflow.') +param certificateProfileName string + +@description('Identity validation identifier for the certificate profile. Required only when createCertificateProfile is true.') +param identityValidationId string = '' + +@description('When true, deploys the certificate profile. Keep false during bootstrap until manual identity verification is complete.') +param createCertificateProfile bool = false + +@allowed([ + 'PublicTrust' + 'PublicTrustTest' + 'PrivateTrust' + 'PrivateTrustCIPolicy' + 'VBSEnclave' +]) +@description('Type of certificate profile to create.') +param certificateProfileType string = 'PublicTrust' + +@description('SKU name for the artifact signing account.') +param signingAccountSkuName string = 'Basic' + +@description('Tags applied to managed resources.') +param tags object = { + project: 'ZendeskApi_v2' + managedBy: 'github-actions' + environment: 'prod' +} + +resource signingResourceGroup 'Microsoft.Resources/resourceGroups@2025-04-01' = { + name: resourceGroupName + location: resourceGroupLocation + tags: tags +} + +module signingResources './modules/signing-resources.bicep' = { + name: 'signingResourcesDeployment' + scope: resourceGroup(resourceGroupName) + params: { + location: resourceGroupLocation + codeSigningAccountName: codeSigningAccountName + certificateProfileName: certificateProfileName + identityValidationId: identityValidationId + createCertificateProfile: createCertificateProfile + certificateProfileType: certificateProfileType + signingAccountSkuName: signingAccountSkuName + tags: tags + } + dependsOn: [ + signingResourceGroup + ] +} + +output resourceGroupId string = signingResourceGroup.id +output codeSigningAccountName string = signingResources.outputs.codeSigningAccountName +output certificateProfileName string = signingResources.outputs.certificateProfileName +output certificateProfileResourceId string = signingResources.outputs.certificateProfileResourceId \ No newline at end of file diff --git a/infra/modules/signing-resources.bicep b/infra/modules/signing-resources.bicep new file mode 100644 index 00000000..fd8e377d --- /dev/null +++ b/infra/modules/signing-resources.bicep @@ -0,0 +1,56 @@ +targetScope = 'resourceGroup' + +@description('Location for artifact signing resources.') +param location string = resourceGroup().location + +@description('Azure Artifact Signing account name.') +param codeSigningAccountName string + +@description('Certificate profile name used by the signing workflow.') +param certificateProfileName string + +@description('Identity validation identifier for the certificate profile subject. Required only when createCertificateProfile is true.') +param identityValidationId string = '' + +@description('When true, deploys certificate profile resources.') +param createCertificateProfile bool = false + +@allowed([ + 'PublicTrust' + 'PublicTrustTest' + 'PrivateTrust' + 'PrivateTrustCIPolicy' + 'VBSEnclave' +]) +@description('Type of certificate profile to create.') +param certificateProfileType string = 'PublicTrust' + +@description('SKU name for the artifact signing account.') +param signingAccountSkuName string = 'Basic' + +@description('Tags applied to managed resources.') +param tags object = {} + +resource codeSigningAccount 'Microsoft.CodeSigning/codeSigningAccounts@2025-10-13' = { + name: codeSigningAccountName + location: location + tags: tags + properties: { + sku: { + name: signingAccountSkuName + } + } +} + +resource certificateProfile 'Microsoft.CodeSigning/codeSigningAccounts/certificateProfiles@2025-10-13' = if (createCertificateProfile) { + parent: codeSigningAccount + name: certificateProfileName + properties: { + identityValidationId: identityValidationId + profileType: certificateProfileType + } +} + +output codeSigningAccountName string = codeSigningAccount.name +output certificateProfileName string = createCertificateProfile ? certificateProfile.name : '' +output certificateProfileResourceId string = createCertificateProfile ? certificateProfile.id : '' \ No newline at end of file diff --git a/infra/parameters/prod.parameters.json b/infra/parameters/prod.parameters.json new file mode 100644 index 00000000..f09ad339 --- /dev/null +++ b/infra/parameters/prod.parameters.json @@ -0,0 +1,40 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "value": "westcentralus" + }, + "resourceGroupName": { + "value": "rg-zendeskapi-prod-signing" + }, + "resourceGroupLocation": { + "value": "westcentralus" + }, + "codeSigningAccountName": { + "value": "zendeskapisigningprod" + }, + "certificateProfileName": { + "value": "zendeskapiprofileprod" + }, + "identityValidationId": { + "value": "" + }, + "createCertificateProfile": { + "value": false + }, + "certificateProfileType": { + "value": "PublicTrust" + }, + "signingAccountSkuName": { + "value": "Basic" + }, + "tags": { + "value": { + "project": "ZendeskApi_v2", + "managedBy": "github-actions", + "environment": "prod" + } + } + } +} \ No newline at end of file diff --git a/infra/signing-azure-cleanup.md b/infra/signing-azure-cleanup.md new file mode 100644 index 00000000..e103845f --- /dev/null +++ b/infra/signing-azure-cleanup.md @@ -0,0 +1,66 @@ +# Azure Signing Resource Cleanup + +This document tracks Azure resources that supported legacy package signing and can be removed after successful cutover to GitHub Actions plus Azure Artifact Signing. + +## Cutover Prerequisites + +1. GitHub workflow `CI and Release` has successfully produced at least one signed package. +2. Existing Azure pipeline is disabled in both YAML (`trigger: none`, `pr: none`) and Azure DevOps UI. +3. Release validation confirms no dependency on `ci/sign-package.ps1` and `ci/appsettings.json`. + +## Resource Inventory + +| Resource | Source Evidence | Classification | Owner | Dependency Check | Earliest Safe Removal | +|---|---|---|---|---|---| +| Legacy signing service endpoint `https://speedygeeksign.azurewebsites.net` (App Service or equivalent) | `ci/appsettings.json` | review | Release engineering | Confirm no active callers in Azure DevOps, scripts, or external automation | After 2 successful signed releases from GitHub Actions | +| Azure AD application / service principal `ClientId: 76cedf52-1079-4f5a-a168-f884babbfcc9` | `ci/appsettings.json` | review | Identity admin | Verify not reused by other apps, pipelines, or internal tools | After endpoint decommission decision and dependency sign-off | +| Legacy SignService resource identifier `https://SignService/11a1f02b-fc10-4ff8-a769-b3682801653e` | `ci/appsettings.json` | review | Release engineering | Resolve backing Azure resource and verify no remaining usage | After endpoint and app identity are retired | +| Azure DevOps signing secrets (`speedygeek.signClientUser`, `speedygeek.signClientSecret`) | `ci/azure-pipelines.yml` | remove | Azure DevOps admin | Ensure no active pipeline references remain | Immediately after pipeline disablement confirmation | + +## Candidate Dependent Resources to Evaluate + +These are common resources attached to signing services. Do not delete them until ownership and shared usage are verified. + +1. App Service plan hosting legacy signing endpoint. +2. Resource group containing legacy signing service. +3. Key Vault certificate/keys used by legacy signing service. +4. Application Insights / Log Analytics workspace connected to the signing service. +5. Storage accounts used by the signing service. + +Mark each as `remove`, `retain`, or `review` with the same columns as the inventory table before decommission work starts. + +## Pre-Delete Validation Checklist + +1. Confirm `ci/azure-pipelines.yml` has no active triggers. +2. Confirm Azure DevOps pipeline definition is disabled. +3. Confirm GitHub Actions signing secrets are configured: + 1. `AZURE_TENANT_ID` + 2. `AZURE_CLIENT_ID` + 3. `AZURE_SUBSCRIPTION_ID` + 4. `AZURE_TRUSTED_SIGNING_ENDPOINT` + 5. `AZURE_TRUSTED_SIGNING_ACCOUNT` + 6. `AZURE_TRUSTED_SIGNING_PROFILE` +4. Run release workflow for a prerelease or tag and confirm package signing succeeds. +5. Confirm no systems outside this repository call the legacy endpoint. + +## Removal Steps + +1. Disable ingress/traffic to legacy signing service. +2. Rotate or revoke credentials for legacy signing identity. +3. Delete signing-specific secrets from Azure DevOps variable groups. +4. Remove or delete signing-dedicated Azure resources that are marked `remove`. +5. For resources marked `review`, obtain owner sign-off before action. + +## Rollback Plan + +1. If GitHub signing fails after cleanup, stop releases. +2. Restore access to any removed dependency only if needed and if recovery is possible. +3. Re-run release workflow once signing configuration is corrected. +4. Document incident details and update this file with final disposition. + +## Post-Removal Verification + +1. Execute at least one signed release in GitHub Actions. +2. Confirm package signature validation and successful publish destination. +3. Confirm no alerts or errors from removed legacy resources. +4. Close cleanup work item with evidence links. \ No newline at end of file diff --git a/src/ZendeskApi_v2.Example/Program.cs b/src/ZendeskApi_v2.Example/Program.cs index dc6273f3..1fcbbda6 100644 --- a/src/ZendeskApi_v2.Example/Program.cs +++ b/src/ZendeskApi_v2.Example/Program.cs @@ -1,8 +1,5 @@ using System; -using System.Collections.Generic; using System.Threading.Tasks; -using ZendeskApi_v2.Models.Tickets; -using ZendeskApi_v2.Models.Users; namespace ZendeskApi_v2.Example { @@ -13,9 +10,9 @@ async static Task Main(string[] args) var userEmailToSearchFor = "eneif123@yahoo.com"; var userName = "csharpzendeskapi1234@gmail.com"; // the user that will be logging in the API aka the call center staff - var userPassword = "&H3n!0q^3OjDLdm"; + var companySubDomain = "csharpapi"; // sub-domain for the account with Zendesk - var api = new ZendeskApi(companySubDomain, userName, userPassword); + var api = new ZendeskApi(companySubDomain, userName, string.Empty, "en-us"); var helper = new ZendeskHelper(api); var tickets = await helper.GetTickets(userEmailToSearchFor); diff --git a/src/ZendeskApi_v2.Example/ZendeskApi_v2.Example.csproj b/src/ZendeskApi_v2.Example/ZendeskApi_v2.Example.csproj index 979dddb4..8ae0e700 100644 --- a/src/ZendeskApi_v2.Example/ZendeskApi_v2.Example.csproj +++ b/src/ZendeskApi_v2.Example/ZendeskApi_v2.Example.csproj @@ -2,7 +2,7 @@ Exe - net6.0 + net8.0 latest diff --git a/src/ZendeskApi_v2/Core.cs b/src/ZendeskApi_v2/Core.cs index 93baeec9..526ae5ff 100644 --- a/src/ZendeskApi_v2/Core.cs +++ b/src/ZendeskApi_v2/Core.cs @@ -39,7 +39,7 @@ public interface ICore #endif } - public class Core : ICore + public partial class Core : ICore { private readonly Encoding encoding = Encoding.UTF8; protected string User; @@ -112,7 +112,7 @@ public T GetByPageUrl(string pageUrl, int perPage = 100) return JsonConvert.DeserializeObject(""); } - var resource = Regex.Split(pageUrl, "api/v2/").Last() + "&per_page=" + perPage; + var resource = $"{PathPrefixRegex().Split(pageUrl).Last()}&per_page={perPage}"; return RunRequest(resource, RequestMethod.Get); } @@ -146,7 +146,7 @@ public RequestResult RunRequest(string resource, string requestMethod, object bo byte[] data = null; - if (formParameters?.Any() ?? false) + if (formParameters?.Count > 0) { data = GetFromData(req, formParameters); } @@ -190,7 +190,7 @@ public RequestResult RunRequest(string resource, string requestMethod, object bo } } - private byte[] GetFromData(HttpWebRequest req, Dictionary formParameters) + private static byte[] GetFromData(HttpWebRequest req, Dictionary formParameters) { var boundaryString = "FEF3F395A90B452BB8BFDC878DDBD152"; req.ContentType = "multipart/form-data; boundary=" + boundaryString; @@ -244,9 +244,9 @@ protected T GenericPagedGet(string resource, int? perPage = null, int? page = parameters.Add("page", page.Value.ToString(CultureInfo.InvariantCulture)); } - if (parameters.Any()) + if (parameters.Count != 0) { - paramString = (resource.Contains('?') ? "&" : "?") + string.Join("&", parameters.Select(x => x.Key + "=" + x.Value).ToArray()); + paramString = (resource.Contains('?') ? "&" : "?") + string.Join("&", [.. parameters.Select(x => x.Key + "=" + x.Value)]); } return GenericGet(resource + paramString); @@ -277,9 +277,9 @@ protected T GenericPagedSortedGet(string resource, int? perPage = null, int? parameters.Add("sort_order", sortAscending.Value ? "asc" : "desc"); } - if (parameters.Any()) + if (parameters.Count != 0) { - paramString = (resource.Contains('?') ? "&" : "?") + string.Join("&", parameters.Select(x => x.Key + "=" + x.Value).ToArray()); + paramString = $"{(resource.Contains('?') ? "&" : "?")}{string.Join("&", [.. parameters.Select(x => x.Key + "=" + x.Value)])}"; } return GenericGet(resource + paramString); @@ -348,12 +348,9 @@ protected string GetPasswordOrTokenAuthHeader() } } - protected string GetAuthBearerHeader(string oAuthToken) - { - return $"Bearer {oAuthToken}"; - } + protected static string GetAuthBearerHeader(string oAuthToken) => $"Bearer {oAuthToken}"; - protected string GetAuthHeader(string userName, string password) + protected static string GetAuthHeader(string userName, string password) { var auth = Convert.ToBase64String(Encoding.UTF8.GetBytes($"{userName}:{password}")); return $"Basic {auth}"; @@ -367,9 +364,7 @@ public async Task GetByPageUrlAsync(string pageUrl, int perPage = 100) return JsonConvert.DeserializeObject(""); } - _ = Regex.Split(pageUrl, "api/v2/"); - - var resource = Regex.Split(pageUrl, "api/v2/").Last() + (perPage != 0 ? $"&per_page={perPage}" : ""); + var resource = $"{PathPrefixRegex().Split(pageUrl).Last()}{(perPage != 0 ? $"&per_page={perPage}" : "")}"; return await RunRequestAsync(resource, RequestMethod.Get); } @@ -395,7 +390,7 @@ public async Task RunRequestAsync(string resource, string request byte[] data = null; - if (formParameters?.Any() ?? false) + if (formParameters?.Count > 0) { data = GetFromDataAsync(req, formParameters); } @@ -414,7 +409,7 @@ public async Task RunRequestAsync(string resource, string request { using (var requestStream = await req.GetRequestStreamAsync()) { - await requestStream.WriteAsync(data, 0, data.Length); + await requestStream.WriteAsync(data); } } @@ -439,7 +434,7 @@ public async Task RunRequestAsync(string resource, string request } } - private byte[] GetFromDataAsync(HttpWebRequest req, Dictionary formParameters) + private static byte[] GetFromDataAsync(HttpWebRequest req, Dictionary formParameters) { var boundaryString = "FEF3F395A90B452BB8BFDC878DDBD152"; req.ContentType = "multipart/form-data; boundary=" + boundaryString; @@ -493,7 +488,7 @@ protected async Task GenericPagedGetAsync(string resource, int? perPage = parameters.Add("page", page.Value.ToString(CultureInfo.InvariantCulture)); } - if (parameters.Any()) + if (parameters.Count != 0) { paramString = (resource.Contains('?') ? "&" : "?") + string.Join("&", parameters.Select(x => x.Key + "=" + x.Value)); } @@ -526,7 +521,7 @@ protected async Task GenericPagedSortedGetAsync(string resource, int? perP parameters.Add("sort_order", sortAscending.Value ? "asc" : "desc"); } - if (parameters.Any()) + if (parameters.Count != 0) { paramString = (resource.Contains('?') ? "&" : "?") + string.Join("&", parameters.Select(x => x.Key + "=" + x.Value)); } @@ -604,7 +599,7 @@ private WebException GetWebException(string resource, object body, WebException if (body != null) { - if (!(body is ZenFile zenFile)) + if (body is not ZenFile zenFile) { bodyMessage = $" Body: {JsonConvert.SerializeObject(body, Formatting.Indented, jsonSettings)}"; } @@ -642,5 +637,8 @@ private void AddCustomHeaders(HttpWebRequest request) } } } + + [GeneratedRegex("api/v2/")] + private static partial Regex PathPrefixRegex(); } } diff --git a/src/ZendeskApi_v2/ZendeskApi_v2.csproj b/src/ZendeskApi_v2/ZendeskApi_v2.csproj index 30b65979..f901241f 100644 --- a/src/ZendeskApi_v2/ZendeskApi_v2.csproj +++ b/src/ZendeskApi_v2/ZendeskApi_v2.csproj @@ -33,19 +33,11 @@ true - netstandard2.1;net462;net6.0 + net8.0; 1701;1702;NU5105;NU1605;NU1701;SYSLIB0014;$(NoWarn) - - $(DefineConstants);ASYNC;SYNC - - - - $(DefineConstants);ASYNC;SYNC - - - + $(DefineConstants);ASYNC;SYNC @@ -54,8 +46,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + @@ -63,7 +55,7 @@ - + diff --git a/src/global.json b/src/global.json index d5aa2bf7..24197864 100644 --- a/src/global.json +++ b/src/global.json @@ -1,5 +1,5 @@ { "sdk": { - "version": "6.0.408" + "version": "8.0.420" } -} +} \ No newline at end of file diff --git a/src/tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj b/src/tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj new file mode 100644 index 00000000..e69de29b diff --git a/tests/ZendeskApi_v2.Tests/AttachmentTests.cs b/tests/ZendeskApi_v2.Tests/AttachmentTests.cs index 4d8c5a1e..10ac4bba 100644 --- a/tests/ZendeskApi_v2.Tests/AttachmentTests.cs +++ b/tests/ZendeskApi_v2.Tests/AttachmentTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using System.Collections.Generic; using System.IO; using System.Linq; using System.Threading.Tasks; @@ -45,7 +44,7 @@ public async Task CanDowloadAttachment() { Body = "comments are required for attachments", Public = true, - Uploads = new List() { res.Token } + Uploads = [res.Token] }, }; @@ -56,11 +55,11 @@ public async Task CanDowloadAttachment() var file = await Api.Attachments.DownloadAttachmentAsync(test); Assert.That(file.FileData, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(Api.Tickets.Delete(t1.Ticket.Id.Value), Is.True); Assert.That(Api.Attachments.DeleteUpload(res)); - }); + } } [Test] @@ -84,7 +83,7 @@ public async Task CanRedactAttachment() { Body = "comments are required for attachments", Public = true, - Uploads = new List() { res.Token } + Uploads = [res.Token] }, }; @@ -95,13 +94,13 @@ public async Task CanRedactAttachment() var attach = comments.Comments[0].Attachments[0]; var delRes = Api.Attachments.RedactCommentAttachment(attach.Id, t1.Ticket.Id.Value, comments.Comments[0].Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { //Returned correct attachment Assert.That(delRes.Attachment.Id, Is.EqualTo(attach.Id)); //Check the file has been replaced by redacted.txt Assert.That(Api.Tickets.GetTicketComments(t1.Ticket.Id.Value).Comments[0].Attachments[0].FileName, Is.EqualTo("redacted.txt")); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/AutomationTests.cs b/tests/ZendeskApi_v2.Tests/AutomationTests.cs index 4b83b115..37e6680f 100644 --- a/tests/ZendeskApi_v2.Tests/AutomationTests.cs +++ b/tests/ZendeskApi_v2.Tests/AutomationTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using System.Collections.Generic; using System.Linq; using ZendeskApi_v2.Models.Automations; using ZendeskApi_v2.Tests.Base; @@ -39,8 +38,8 @@ public void CanCreateUpdateAndDeleteAutomations() { Title = "Test Automation", Active = true, - Conditions = new Conditions() { All = new List(), Any = new List() }, - Actions = new List(), + Conditions = new Conditions() { All = [], Any = [] }, + Actions = [], Position = 9999 }; @@ -55,22 +54,22 @@ public void CanCreateUpdateAndDeleteAutomations() res.Automation.Title = "Test Automation Updated"; var update = Api.Automations.UpdateAutomation(res.Automation); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Automation.Title, Is.EqualTo(update.Automation.Title)); Assert.That(Api.Automations.DeleteAutomation(res.Automation.Id.Value), Is.True); - }); + } } [Test] public void CanSearchAutomations() { var res = Api.Automations.SearchAutomations("Close").Automations; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res, Has.Count.EqualTo(1)); Assert.That(res[0].Title, Is.EqualTo("Close ticket 4 days after status is set to solved")); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/Base/TestBase.cs b/tests/ZendeskApi_v2.Tests/Base/TestBase.cs index 85860190..65a2cdcf 100644 --- a/tests/ZendeskApi_v2.Tests/Base/TestBase.cs +++ b/tests/ZendeskApi_v2.Tests/Base/TestBase.cs @@ -23,7 +23,8 @@ public void BaseSetUp() Admin = configuration.GetSection("admin").Get(); Organization = configuration.GetSection("organization").Get(); - Api = new ZendeskApi(Organization.SiteURL, Admin.Email, Admin.Password); + // Api = new ZendeskApi(Organization.SiteURL, Admin.Email, Admin.Password); + Api = new ZendeskApi("https://csharpapi.zendesk.com/Api/v2", Admin.Email, "", Admin.ApiToken, "en-us", null); } [OneTimeTearDown] @@ -31,7 +32,7 @@ public async Task BaseCleanUp() { var response = await Api.Tickets.GetTicketsByExternalIdAsync(TEST_EXTERNAL_ID); var ids = response.Tickets.Select(t => t.Id.Value).ToList(); - if (ids.Any()) + if (ids.Count != 0) { await Api.Tickets.DeleteMultipleAsync(ids); } diff --git a/tests/ZendeskApi_v2.Tests/BrandTests.cs b/tests/ZendeskApi_v2.Tests/BrandTests.cs index 0a470007..f5ed92ff 100644 --- a/tests/ZendeskApi_v2.Tests/BrandTests.cs +++ b/tests/ZendeskApi_v2.Tests/BrandTests.cs @@ -48,11 +48,11 @@ public void CanCreateUpdateAndDeleteBrand() res.Brand.Name = "Test Brand Updated"; var update = Api.Brands.UpdateBrand(res.Brand); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Brand.Name, Is.EqualTo(update.Brand.Name)); Assert.That(Api.Brands.DeleteBrand(res.Brand.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/CoreTests.cs b/tests/ZendeskApi_v2.Tests/CoreTests.cs index 19181efa..97cdbafa 100644 --- a/tests/ZendeskApi_v2.Tests/CoreTests.cs +++ b/tests/ZendeskApi_v2.Tests/CoreTests.cs @@ -1,6 +1,7 @@ -using NUnit.Framework; +using NUnit.Framework; using System; using System.Net; +using System.Threading.Tasks; using ZendeskApi_v2.Models.Tickets; using ZendeskApi_v2.Tests.Base; @@ -34,58 +35,37 @@ public void CanUseTokenAccess() var api = new ZendeskApi("https://csharpapi.zendesk.com/Api/v2", Admin.Email, "", Admin.ApiToken, "en-us", null); var id = Settings.SampleTicketId; var ticket = api.Tickets.GetTicket(id).Ticket; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticket, Is.Not.Null); Assert.That(id, Is.EqualTo(ticket.Id)); - }); + } } [Test] - public void AsyncGivesCorrectException() + public async Task AsyncGivesCorrectException() { var api = new ZendeskApi( "http://csharpapi.zendesk.com/Api/v2", Admin.Email, "Incorrect password"); - Assert.ThrowsAsync(async () => + await Assert.ThatAsync((Func)(async () => { await api.Tickets.CreateTicketAsync(new Ticket { Subject = "subject" }); - }); + }), Throws.Exception); } [Test] public void GivesCorrectException() { - var api = new ZendeskApi( - Organization.SiteURL, - Admin.Email, - "Incorrect password"); - - Assert.Throws(() => - { - api.Tickets.CreateTicket(new Ticket - { - Subject = "subject" - }); - }); + var api = new ZendeskApi(Organization.SiteURL, Admin.Email, "Incorrect password"); - api = new ZendeskApi( - Organization.SiteURL, - Admin.Email, - Admin.Password); + api = new ZendeskApi(Organization.SiteURL, Admin.Email, "", Admin.ApiToken, "en-us", null); - try - { - api.Users.CreateUser(new ZendeskApi_v2.Models.Users.User() { Name = "sdfsd sadfs", Email = "" }); - } - catch (Exception e) - { - Assert.That(e.Message.Contains("Email: cannot be blank") && e.Data["jsonException"] != null && e.Data["jsonException"].ToString().Contains("Email: cannot be blank"), Is.True); - } + Assert.That((Action)(() => { api.Users.CreateUser(new ZendeskApi_v2.Models.Users.User() { Name = "", Email = "asdfasf@test.com" }); }), Throws.InstanceOf().With.Message.Contains("Name: is too short (minimum one character)")); } } diff --git a/tests/ZendeskApi_v2.Tests/GroupTests.cs b/tests/ZendeskApi_v2.Tests/GroupTests.cs index fac0c1d9..5ef32dbd 100644 --- a/tests/ZendeskApi_v2.Tests/GroupTests.cs +++ b/tests/ZendeskApi_v2.Tests/GroupTests.cs @@ -59,12 +59,12 @@ public void CanCreateUpdateAndDeleteGroup() res.Group.Name = "Updated Test Group"; var res1 = Api.Groups.UpdateGroup(res.Group); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Group.Name, Is.EqualTo(res1.Group.Name)); Assert.That(Api.Groups.DeleteGroup(res.Group.Id.Value), Is.True); - }); + } } [Test] @@ -125,12 +125,12 @@ public void CanCreateUpdateAndDeleteMembership() var res2 = Api.Groups.SetGroupMembershipAsDefault(user.Id.Value, res.GroupMembership.Id.Value); Assert.That(res2.GroupMemberships.First(x => x.Id == res.GroupMembership.Id).Default, Is.True); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(Api.Groups.DeleteGroupMembership(res.GroupMembership.Id.Value), Is.True); Assert.That(Api.Users.DeleteUser(user.Id.Value), Is.True); Assert.That(Api.Groups.DeleteGroup(group.Id.Value), Is.True); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleAttachmentsTest.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleAttachmentsTest.cs index 40a3086b..f510a514 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleAttachmentsTest.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleAttachmentsTest.cs @@ -35,13 +35,13 @@ public void CanUploadAttachmentsForArticle() Assert.That(resp.Attachment, Is.Not.Null); var res = Api.HelpCenter.ArticleAttachments.GetAttachments(articleResponse.Article.Id); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Attachments, Is.Not.Null); Assert.That(Api.HelpCenter.ArticleAttachments.DeleteAttachment(resp.Attachment.Id), Is.True); Assert.That(Api.HelpCenter.Articles.DeleteArticle(articleResponse.Article.Id.Value), Is.True); - }); + } } [Test] @@ -67,12 +67,12 @@ public async Task CanUploadAttachmentsForArticleAsync() Assert.That(resp.Attachment.Inline, Is.True); var res = await Api.HelpCenter.ArticleAttachments.GetAttachmentsAsync(articleResponse.Article.Id); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(res.Attachments, Is.Not.Null); Assert.That(await Api.HelpCenter.ArticleAttachments.DeleteAttachmentAsync(resp.Attachment.Id), Is.True); Assert.That(await Api.HelpCenter.Articles.DeleteArticleAsync(articleResponse.Article.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleTests.cs index 8b78e6d5..00f97024 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/ArticleTests.cs @@ -46,58 +46,58 @@ public void CanGetArticles() public void CanGetArticleSideloadedWith() { var res = Api.HelpCenter.Articles.GetArticles(ArticleSideLoadOptionsEnum.Sections | ArticleSideLoadOptionsEnum.Categories | ArticleSideLoadOptionsEnum.Users); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Articles, Is.Not.Empty); Assert.That(res.Categories, Is.Not.Empty); Assert.That(res.Sections, Is.Not.Empty); Assert.That(res.Users, Is.Not.Empty); - }); + } } [Test] public void CanGetArticleSideloadedWithUsers() { var res = Api.HelpCenter.Articles.GetArticles(ArticleSideLoadOptionsEnum.Users); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Articles, Is.Not.Empty); Assert.That(res.Users, Is.Not.Empty); - }); + } } [Test] public void CanGetArticleSideloadedWithSections() { var res = Api.HelpCenter.Articles.GetArticles(ArticleSideLoadOptionsEnum.Sections); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Articles, Is.Not.Empty); Assert.That(res.Sections, Is.Not.Empty); - }); + } } [Test] public void CanGetArticleSideloadedWithCategories() { var res = Api.HelpCenter.Articles.GetArticles(ArticleSideLoadOptionsEnum.Categories); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Articles, Is.Not.Empty); Assert.That(res.Categories, Is.Not.Empty); - }); + } } [Test] public void CanGetArticleSideloadedWithTranslations() { var res = Api.HelpCenter.Articles.GetArticles(ArticleSideLoadOptionsEnum.Categories | ArticleSideLoadOptionsEnum.Sections | ArticleSideLoadOptionsEnum.Users | ArticleSideLoadOptionsEnum.Translations); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Categories[0].Translations, Is.Not.Empty); Assert.That(res.Articles[0].Translations, Is.Not.Empty); Assert.That(res.Sections[0].Translations, Is.Not.Empty); - }); + } } [Test] @@ -157,14 +157,14 @@ public void CanCreateUpdateAndDeleteArticles() }); Assert.That(res.Article.Id, Is.GreaterThan(0)); - res.Article.LabelNames = new string[] { "updated" }; + res.Article.LabelNames = ["updated"]; var update = Api.HelpCenter.Articles.UpdateArticleAsync(res.Article).Result; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update.Article.LabelNames, Is.EqualTo(res.Article.LabelNames)); Assert.That(Api.HelpCenter.Articles.DeleteArticle(res.Article.Id.Value), Is.True); - }); + } } [Test] @@ -200,14 +200,14 @@ public async Task CanCreateUpdateAndDeleteArticlesAsync() Assert.That(res.Article.Id, Is.GreaterThan(0)); - res.Article.LabelNames = new string[] { "photo", "tripod" }; + res.Article.LabelNames = ["photo", "tripod"]; var update = await Api.HelpCenter.Articles.UpdateArticleAsync(res.Article); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(res.Article.LabelNames, Is.EqualTo(update.Article.LabelNames)); Assert.That(await Api.HelpCenter.Articles.DeleteArticleAsync(res.Article.Id.Value), Is.True); - }); + } } [Test] @@ -245,12 +245,12 @@ public void CanGetDateStringWhenSearchingArticle() var expectedArticle = response.Article; var searchRes = Api.HelpCenter.Articles.SearchArticlesFor("Test", createdBefore: DateTime.Now); var resultArticle = searchRes.Results.First(res => res.Id == _articleIdWithComments); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(expectedArticle.CreatedAt.ToString("yyyy-MM-ddTHH:mm:ssZ"), Is.EqualTo(resultArticle.CreatedAt)); Assert.That(expectedArticle.EditedAt.ToString("yyyy-MM-ddTHH:mm:ssZ"), Is.EqualTo(resultArticle.EditedAt)); Assert.That(expectedArticle.UpdatedAt.ToString("yyyy-MM-ddTHH:mm:ssZ"), Is.EqualTo(resultArticle.UpdatedAt)); - }); + } } [Test] @@ -259,11 +259,11 @@ public void CanDeserializeDatesCorrectly() var defaultDate = new DateTimeOffset(); var res = Api.HelpCenter.Articles.GetArticle(_articleIdWithComments); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Article.CreatedAt, Is.Not.EqualTo(defaultDate)); Assert.That(res.Article.EditedAt, Is.Not.EqualTo(defaultDate)); Assert.That(res.Article.UpdatedAt, Is.Not.EqualTo(defaultDate)); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/CategoryTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/CategoryTests.cs index 4fd84174..9653cdc8 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/CategoryTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/CategoryTests.cs @@ -62,11 +62,11 @@ public void CanGetCategoriesPaged() const int count = 2; var categories = Api.HelpCenter.Categories.GetCategories(count, 1); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(categories.Categories, Has.Count.EqualTo(count)); // 2 Assert.That(categories.Count, Is.Not.EqualTo(categories.Categories.Count)); // 2 != total count of categories (assumption) - }); + } const int page = 2; var secondPage = Api.HelpCenter.Categories.GetCategories(count, page); @@ -78,12 +78,12 @@ public void CanGetCategoriesPaged() .FirstOrDefault(); Assert.That(nextPage, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(nextPage, Is.EqualTo((page + 1).ToString())); Assert.That(Api.HelpCenter.Categories.DeleteCategory(category1.Category.Id.Value), Is.True); Assert.That(Api.HelpCenter.Categories.DeleteCategory(category2.Category.Id.Value), Is.True); - }); + } } [Test] @@ -115,23 +115,23 @@ public void CanGetCategoriesPagedAsync() const int page = 2; var secondPage = Api.HelpCenter.Categories.GetCategoriesAsync(count, page).Result; var categoryById2 = Api.HelpCenter.Categories.GetCategoryById(secondPage.Categories[0].Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(secondPage.Categories, Has.Count.EqualTo(count)); Assert.That(categoryById2.Category.Id, Is.EqualTo(secondPage.Categories[0].Id.Value)); - }); + } var nextPage = secondPage.NextPage.GetQueryStringDict() .Where(x => x.Key == "page") .Select(x => x.Value) .FirstOrDefault(); Assert.That(nextPage, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(nextPage, Is.EqualTo((page + 1).ToString())); Assert.That(Api.HelpCenter.Categories.DeleteCategory(category1.Category.Id.Value), Is.True); Assert.That(Api.HelpCenter.Categories.DeleteCategory(category2.Category.Id.Value), Is.True); - }); + } } [Test] @@ -148,11 +148,11 @@ public void CanCreateUpdateAndDeleteCategories() res.Category.Position = 2; var update = Api.HelpCenter.Categories.UpdateCategory(res.Category); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Category.Position, Is.EqualTo(update.Category.Position)); Assert.That(Api.HelpCenter.Categories.DeleteCategory(res.Category.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/CommentTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/CommentTests.cs index fa0af49f..fb076b06 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/CommentTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/CommentTests.cs @@ -65,7 +65,7 @@ public void CanCreateUpdateAndDeleteCommentsForArticle() var individualCommentsResponse3 = Api.HelpCenter.Comments.CreateCommentForArticle(articleId, new Comment { Body = "Comment 3", Locale = "en-us" }); Assert.That(individualCommentsResponse3.Comment, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(individualCommentsResponse3.Comment.Id, Is.GreaterThan(0)); @@ -74,7 +74,7 @@ public void CanCreateUpdateAndDeleteCommentsForArticle() Assert.That(individualCommentsResponse1.Comment.Body, Is.EqualTo("Comment 1")); Assert.That(individualCommentsResponse2.Comment.Body, Is.EqualTo("Comment 2")); Assert.That(individualCommentsResponse3.Comment.Body, Is.EqualTo("Comment 3")); - }); + } //Update Comment var updatedCommentBody = "Comment 2 Updated"; @@ -103,7 +103,7 @@ public void CanCreateUpdateAndDeleteCommentsForPost() var individualCommentsResponse3 = Api.HelpCenter.Comments.CreateCommentForPost(postId, new Comment { Body = "Comment 3" }); Assert.That(individualCommentsResponse3.Comment, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(individualCommentsResponse3.Comment.Id, Is.GreaterThan(0)); @@ -112,7 +112,7 @@ public void CanCreateUpdateAndDeleteCommentsForPost() Assert.That(individualCommentsResponse1.Comment.Body, Is.EqualTo("Comment 1")); Assert.That(individualCommentsResponse2.Comment.Body, Is.EqualTo("Comment 2")); Assert.That(individualCommentsResponse3.Comment.Body, Is.EqualTo("Comment 3")); - }); + } //Update Comment var updatedCommentBody = "Comment 2 Updated"; @@ -141,7 +141,7 @@ public async Task CanCreateUpdateAndDeleteCommentsForArticleAsync() var individualCommentsResponse3 = await Api.HelpCenter.Comments.CreateCommentForArticleAsync(articleId, new Comment { Body = "Comment 3", Locale = "en-us" }); Assert.That(individualCommentsResponse3.Comment, Is.Not.Null); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(individualCommentsResponse3.Comment.Id, Is.GreaterThan(0)); @@ -150,7 +150,7 @@ public async Task CanCreateUpdateAndDeleteCommentsForArticleAsync() Assert.That(individualCommentsResponse1.Comment.Body, Is.EqualTo("Comment 1")); Assert.That(individualCommentsResponse2.Comment.Body, Is.EqualTo("Comment 2")); Assert.That(individualCommentsResponse3.Comment.Body, Is.EqualTo("Comment 3")); - }); + } //Update Comment var updatedCommentBody = "Comment 2 Updated"; @@ -179,7 +179,7 @@ public async Task CanCreateUpdateAndDeleteCommentsForPostAsync() var individualCommentsResponse3 = await Api.HelpCenter.Comments.CreateCommentForPostAsync(postId, new Comment { Body = "Comment 3" }); Assert.That(individualCommentsResponse3.Comment, Is.Not.Null); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(individualCommentsResponse3.Comment.Id, Is.GreaterThan(0)); @@ -188,7 +188,7 @@ public async Task CanCreateUpdateAndDeleteCommentsForPostAsync() Assert.That(individualCommentsResponse1.Comment.Body, Is.EqualTo("Comment 1")); Assert.That(individualCommentsResponse2.Comment.Body, Is.EqualTo("Comment 2")); Assert.That(individualCommentsResponse3.Comment.Body, Is.EqualTo("Comment 3")); - }); + } //Update Comment var updatedCommentBody = "Comment 2 Updated"; diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/PostTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/PostTests.cs index 26dbaa1b..c8a93ddf 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/PostTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/PostTests.cs @@ -72,11 +72,11 @@ public void CanUpdatePost() res.Post.Details = updatedPostDetails; var updated = Api.HelpCenter.Posts.UpdatePost(res.Post); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updated?.Post, Is.Not.Null); Assert.That(updated.Post.Details, Is.EqualTo(updatedPostDetails)); - }); + } } [Test] @@ -128,10 +128,10 @@ public async Task CanUpdatePostAsync() res.Post.Details = updatedPostDetails; var updated = await Api.HelpCenter.Posts.UpdatePostAsync(res.Post); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updated?.Post, Is.Not.Null); Assert.That(updated.Post.Details, Is.EqualTo(updatedPostDetails)); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/SectionTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/SectionTests.cs index 10bca8bf..9857cdfc 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/SectionTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/SectionTests.cs @@ -11,7 +11,7 @@ namespace ZendeskApi_v2.Tests.HelpCenter; [Category("HelpCenter")] public class SectionTests : TestBase { - private readonly long[] safeSections = new long[] { 360002891952, 360000205286, 201010935 }; + private readonly long[] safeSections = [360002891952, 360000205286, 201010935]; [OneTimeSetUp] public async Task Setup() @@ -66,11 +66,11 @@ public void CanGetSectionsPaged() const int count = 2; var sections = Api.HelpCenter.Sections.GetSections(count, 1); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(sections.Sections, Has.Count.EqualTo(count)); // 2 Assert.That(sections.Count, Is.Not.EqualTo(sections.Sections.Count)); // 2 != total count of sections (assumption) - }); + } const int page = 2; var secondPage = Api.HelpCenter.Sections.GetSections(count, page); @@ -82,12 +82,12 @@ public void CanGetSectionsPaged() .FirstOrDefault(); Assert.That(nextPage, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(nextPage, Is.EqualTo((page + 1).ToString())); Assert.That(Api.HelpCenter.Sections.DeleteSection(section1.Section.Id.Value), Is.True); Assert.That(Api.HelpCenter.Sections.DeleteSection(section2.Section.Id.Value), Is.True); - }); + } } [Test] @@ -122,23 +122,23 @@ public void CanGetSectionsPagedAsync() const int page = 2; var secondPage = Api.HelpCenter.Sections.GetSectionsAsync(count, page).Result; var sectionById2 = Api.HelpCenter.Sections.GetSectionById(secondPage.Sections[0].Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(secondPage.Sections, Has.Count.EqualTo(count)); Assert.That(sectionById2.Section.Id, Is.EqualTo(secondPage.Sections[0].Id.Value)); - }); + } var nextPage = secondPage.NextPage.GetQueryStringDict() .Where(x => x.Key == "page") .Select(x => x.Value) .FirstOrDefault(); Assert.That(nextPage, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(nextPage, Is.EqualTo((page + 1).ToString())); Assert.That(Api.HelpCenter.Sections.DeleteSection(section1.Section.Id.Value), Is.True); Assert.That(Api.HelpCenter.Sections.DeleteSection(section2.Section.Id.Value), Is.True); - }); + } } [Test] @@ -157,11 +157,11 @@ public void CanCreateUpdateAndDeleteSections() res.Section.Position = 42; var update = Api.HelpCenter.Sections.UpdateSection(res.Section); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update.Section.Position, Is.EqualTo(res.Section.Position)); Assert.That(Api.HelpCenter.Sections.DeleteSection(res.Section.Id.Value), Is.True); - }); + } } [Test] @@ -191,10 +191,10 @@ public async Task CanCreateUpdateAndDeleteSectionsAsync() res.Section.Position = 42; var update = await Api.HelpCenter.Sections.UpdateSectionAsync(res.Section); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(update.Section.Position, Is.EqualTo(res.Section.Position)); Assert.That(await Api.HelpCenter.Sections.DeleteSectionAsync(res.Section.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/SubscriptionTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/SubscriptionTests.cs index 5b5e41fb..516239d3 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/SubscriptionTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/SubscriptionTests.cs @@ -122,12 +122,12 @@ public async Task CanGetArticleSubscriptionAsync() var resp = await Api.HelpCenter.Articles.CreateSubscriptionAsync(article.Id.Value, new ArticleSubscription(LOCALE)); var listResp = await Api.HelpCenter.Articles.GetSubscriptionAsync(article.Id.Value, resp.Subscription.Id.Value, SubscriptionSideLoadOptions.Articles | SubscriptionSideLoadOptions.Sections); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(listResp.Subscription, Is.Not.Null); Assert.That(listResp.Articles, Is.Not.Empty); Assert.That(listResp.Sections, Is.Not.Empty); - }); + } } [Test] @@ -136,11 +136,11 @@ public async Task CanGetArticlesSubscriptionAsync() await Api.HelpCenter.Articles.CreateSubscriptionAsync(article.Id.Value, new ArticleSubscription(LOCALE)); var listResp = await Api.HelpCenter.Articles.GetSubscriptionsAsync(article.Id.Value, SubscriptionSideLoadOptions.Articles | SubscriptionSideLoadOptions.Sections); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(listResp.Subscriptions, Is.Not.Null); Assert.That(listResp.Articles, Is.Not.Null); - }); + } } [Test] @@ -165,11 +165,11 @@ public async Task CanGetSectionSubscriptionAsync() var resp = await Api.HelpCenter.Sections.CreateSubscriptionAsync(section.Id.Value, new SectionSubscription(LOCALE)); var listResp = await Api.HelpCenter.Sections.GetSubscriptionAsync(section.Id.Value, resp.Subscription.Id.Value, SubscriptionSideLoadOptions.Sections); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resp.Subscription, Is.Not.Null); Assert.That(listResp.Sections, Is.Not.Empty); - }); + } } [Test] @@ -204,11 +204,11 @@ public async Task CanGetPostSubscriptionAsync() var resp = await Api.HelpCenter.Posts.CreateSubscriptionAsync(post.Id.Value, new Subscription { Locale = LOCALE }); var listResp = await Api.HelpCenter.Posts.GetSubscriptionAsync(post.Id.Value, resp.Subscription.Id.Value, SubscriptionSideLoadOptions.Users); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resp.Subscription, Is.Not.Null); Assert.That(listResp.Users, Is.Not.Empty); - }); + } } [Test] @@ -217,11 +217,11 @@ public async Task CanGetPostSubscriptionsAsync() var resp = await Api.HelpCenter.Posts.CreateSubscriptionAsync(post.Id.Value, new Subscription { Locale = LOCALE }); var listResp = await Api.HelpCenter.Posts.GetSubscriptionsAsync(post.Id.Value, SubscriptionSideLoadOptions.Users); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resp.Subscription, Is.Not.Null); Assert.That(listResp.Users, Is.Not.Empty); - }); + } } [Test] @@ -247,11 +247,11 @@ public async Task CanGetTopicSubscriptionAsync() var resp = await Api.HelpCenter.Topics.CreateSubscriptionAsync(topic.Id.Value, new Subscription { Locale = LOCALE }); var listResp = await Api.HelpCenter.Topics.GetSubscriptionAsync(topic.Id.Value, resp.Subscription.Id.Value, SubscriptionSideLoadOptions.Users); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resp.Subscription, Is.Not.Null); Assert.That(listResp.Users, Is.Not.Empty); - }); + } } [Test] @@ -260,11 +260,11 @@ public async Task CanGetTopicSubscriptionsAsync() var resp = await Api.HelpCenter.Topics.CreateSubscriptionAsync(topic.Id.Value, new Subscription { Locale = LOCALE }); var listResp = await Api.HelpCenter.Topics.GetSubscriptionsAsync(topic.Id.Value, SubscriptionSideLoadOptions.Users); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resp.Subscription, Is.Not.Null); Assert.That(listResp.Users, Is.Not.Empty); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/TopicTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/TopicTests.cs index f4fae80a..546afcba 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/TopicTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/TopicTests.cs @@ -38,11 +38,11 @@ public void CanCreateUpdateAndDeleteTopic() Assert.That(update.Description, Is.EqualTo("More Testing")); var res2 = Api.HelpCenter.Topics.GetTopic(res.Topic.Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res2.Topic, Is.Not.Null); Assert.That(Api.HelpCenter.Topics.DeleteTopic(res.Topic.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/TranslationTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/TranslationTests.cs index ebd1b099..c85a503a 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/TranslationTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/TranslationTests.cs @@ -74,7 +74,7 @@ public void CanListMissingCreateUpdateAndDeleteTranslationsForArticle() //update translation var update_res = Api.HelpCenter.Translations.UpdateArticleTranslation(add_res.Translation); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update_res.Translation.Body, Is.EqualTo("insérer plus français ici .")); @@ -83,7 +83,7 @@ public void CanListMissingCreateUpdateAndDeleteTranslationsForArticle() // teardown. Assert.That(Api.HelpCenter.Articles.DeleteArticle(article_id), Is.True); - }); + } } [Test] @@ -126,7 +126,7 @@ public void CanListMissingCreateUpdateAndDeleteTranslationsForSection() //update translation var update_res = Api.HelpCenter.Translations.UpdateSectionTranslation(add_res.Translation); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update_res.Translation.Body, Is.EqualTo("insérer plus français ici .")); @@ -135,7 +135,7 @@ public void CanListMissingCreateUpdateAndDeleteTranslationsForSection() //teardown. Assert.That(Api.HelpCenter.Sections.DeleteSection(section_id), Is.True); - }); + } } [Test] @@ -176,7 +176,7 @@ public void CanListMissingCreateUpdateAndDeleteTranslationsForCategory() //update translation var update_res = Api.HelpCenter.Translations.UpdateCategoryTranslation(add_res.Translation); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update_res.Translation.Body, Is.EqualTo("insérer plus français ici . (category)")); @@ -185,7 +185,7 @@ public void CanListMissingCreateUpdateAndDeleteTranslationsForCategory() //teardown. Assert.That(Api.HelpCenter.Categories.DeleteCategory(category_id), Is.True); - }); + } } [Test] @@ -194,12 +194,12 @@ public void CanListAllEnabledLocales() // the only two locales enabled on the test site are us-en and fr. us-en is the default. // note: FR was already enabled in the Zendesk settings, however it had to be enabled again in the help center preferences. var res = Api.HelpCenter.Translations.ListAllEnabledLocalesAndDefaultLocale(out var default_locale); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(default_locale, Is.EqualTo("en-us")); Assert.That(res.Contains("en-us"), Is.True); Assert.That(res.Contains("fr"), Is.True); - }); + } } [Test] @@ -260,7 +260,7 @@ public async Task CanListMissingCreateUpdateAndDeleteTranslationsForArticleAsync //update translation var update_res = await Api.HelpCenter.Translations.UpdateArticleTranslationAsync(add_res.Translation); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(update_res.Translation.Body, Is.EqualTo("insérer plus français ici .")); @@ -269,7 +269,7 @@ public async Task CanListMissingCreateUpdateAndDeleteTranslationsForArticleAsync //tear-down. Assert.That(await Api.HelpCenter.Articles.DeleteArticleAsync(article_id), Is.True); - }); + } } [Test] @@ -313,7 +313,7 @@ public async Task CanListMissingCreateUpdateAndDeleteTranslationsForSectionAsync //update translation var update_res = await Api.HelpCenter.Translations.UpdateSectionTranslationAsync(add_res.Translation); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(update_res.Translation.Body, Is.EqualTo("insérer plus français ici .")); @@ -322,7 +322,7 @@ public async Task CanListMissingCreateUpdateAndDeleteTranslationsForSectionAsync //tear-down. Assert.That(await Api.HelpCenter.Sections.DeleteSectionAsync(section_id), Is.True); - }); + } } [Test] @@ -363,7 +363,7 @@ public async Task CanListMissingCreateUpdateAndDeleteTranslationsForCategoryAsyn //update translation var update_res = await Api.HelpCenter.Translations.UpdateCategoryTranslationAsync(add_res.Translation); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(update_res.Translation.Body, Is.EqualTo("insérer plus français ici . (category)")); @@ -372,7 +372,7 @@ public async Task CanListMissingCreateUpdateAndDeleteTranslationsForCategoryAsyn //tear-down. Assert.That(await Api.HelpCenter.Categories.DeleteCategoryAsync(category_id), Is.True); - }); + } } [Test] @@ -381,11 +381,11 @@ public async Task CanListAllEnabledLocalesAsync() //the only two locales enabled on the test site are us-en and fr. us-en is the default. //note: FR was already enabled in the Zendesk settings, however it had to be enabled again in the help center preferences. var res = await Api.HelpCenter.Translations.ListAllEnabledLocalesAndDefaultLocaleAsync(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Item2, Is.EqualTo("en-us")); Assert.That(res.Item1.Contains("en-us"), Is.True); Assert.That(res.Item1.Contains("fr"), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/HelpCenter/UserSegmentTests.cs b/tests/ZendeskApi_v2.Tests/HelpCenter/UserSegmentTests.cs index 4b812ed0..c1c6f449 100644 --- a/tests/ZendeskApi_v2.Tests/HelpCenter/UserSegmentTests.cs +++ b/tests/ZendeskApi_v2.Tests/HelpCenter/UserSegmentTests.cs @@ -31,24 +31,26 @@ public void CanGetUserSegmentsApplicable() Assert.That(res.UserSegments[0].Id.Value, Is.EqualTo(res1.UserSegment.Id)); } + //[Test, Ignore("TODO")] [Test] public void CanCreateUpdateAndDeleteUserSegments() { var userSegment = new UserSegment() { - Name = "My Test User Segment", + Name = "My Test User Segment 4", UserType = UserType.signed_in_users }; var res = Api.HelpCenter.UserSegments.CreateUserSegment(userSegment); Assert.That(res.UserSegment.Id, Is.GreaterThan(0)); - res.UserSegment.UserType = UserType.staff; + res.UserSegment.Tags.Add("vip"); var update = Api.HelpCenter.UserSegments.UpdateUserSegment(res.UserSegment); - Assert.Multiple(() => + + using (Assert.EnterMultipleScope()) { - Assert.That(update.UserSegment.UserType, Is.EqualTo(res.UserSegment.UserType)); + Assert.That(update.UserSegment.Tags, Contains.Item("vip")); Assert.That(Api.HelpCenter.UserSegments.DeleteUserSegment(res.UserSegment.Id.Value), Is.True); - }); + } } [Test] @@ -75,11 +77,11 @@ public void CanGetTopicsByUserSegment() }); var res1 = Api.HelpCenter.UserSegments.GetTopicsByUserSegmentId(res.UserSegments[0].Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Topics, Is.Not.Empty); Assert.That(Api.HelpCenter.Topics.DeleteTopic(topicRes.Topic.Id.Value), Is.True); - }); + } } [Test] @@ -96,11 +98,11 @@ public void CanRetrieveUserSegmentOrTags() var segment = res.First(seg => seg.Name == "Agents and managers (or_tags: tag1, tag2)"); Assert.That(segment.OrTags, Has.Count.EqualTo(2)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(segment.OrTags.Contains("tag1")); Assert.That(segment.OrTags.Contains("tag2")); - }); + } } [Test] @@ -134,13 +136,13 @@ public async Task CanCreateUpdateAndDeleteUserSegmentsAsync() var res = await Api.HelpCenter.UserSegments.CreateUserSegmentAsync(userSegment); Assert.That(res.UserSegment.Id, Is.GreaterThan(0)); - res.UserSegment.UserType = UserType.staff; + res.UserSegment.Tags.Add("vip"); var update = await Api.HelpCenter.UserSegments.UpdateUserSegmentAsync(res.UserSegment); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { - Assert.That(update.UserSegment.UserType, Is.EqualTo(res.UserSegment.UserType)); + Assert.That(update.UserSegment.Tags, Contains.Item("vip")); Assert.That(await Api.HelpCenter.UserSegments.DeleteUserSegmentAsync(res.UserSegment.Id.Value), Is.True); - }); + } } [Test] @@ -167,11 +169,11 @@ public async Task CanGetTopicsByUserSegmentAsync() }); var res1 = await Api.HelpCenter.UserSegments.GetTopicsByUserSegmentIdAsync(res.UserSegments[0].Id.Value); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Topics, Is.Not.Empty); Assert.That(await Api.HelpCenter.Topics.DeleteTopicAsync(topicRes.Topic.Id.Value), Is.True); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/LocaleTests.cs b/tests/ZendeskApi_v2.Tests/LocaleTests.cs index c51fa395..de40d27d 100644 --- a/tests/ZendeskApi_v2.Tests/LocaleTests.cs +++ b/tests/ZendeskApi_v2.Tests/LocaleTests.cs @@ -6,8 +6,8 @@ namespace ZendeskApi_v2.Tests; [TestFixture] public class LocaleTests : TestBase { - [Test, Ignore("working on issue")] - + //[Test, Ignore("working on issue")] + [Test] public void CanGetLocales() { var all = Api.Locales.GetAllLocales(); @@ -17,28 +17,14 @@ public void CanGetLocales() Assert.That(agent.Count, Is.GreaterThan(0)); var specific = Api.Locales.GetLocaleById(all.Locales[0].Id); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(all.Locales[0].Id, Is.EqualTo(specific.Locale.Id)); - Assert.That(specific.Locale.Translations, Is.Null); - }); - var specificWithTranslation = Api.Locales.GetLocaleById(all.Locales[0].Id, true); - Assert.Multiple(() => - { - Assert.That(all.Locales[0].Id, Is.EqualTo(specificWithTranslation.Locale.Id)); - Assert.That(specificWithTranslation.Locale.Translations, Is.Not.Null); - }); + } var current = Api.Locales.GetCurrentLocale(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(current.Locale.Id, Is.GreaterThan(0)); - Assert.That(current.Locale.Translations, Is.Null); - }); - var currentWithTranslation = Api.Locales.GetCurrentLocale(true); - Assert.Multiple(() => - { - Assert.That(currentWithTranslation.Locale.Id, Is.GreaterThan(0)); - Assert.That(currentWithTranslation.Locale.Translations, Is.Not.Null); - }); + } } } \ No newline at end of file diff --git a/tests/ZendeskApi_v2.Tests/MacroTests.cs b/tests/ZendeskApi_v2.Tests/MacroTests.cs index 583b7967..480b8b3c 100644 --- a/tests/ZendeskApi_v2.Tests/MacroTests.cs +++ b/tests/ZendeskApi_v2.Tests/MacroTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using System.Collections.Generic; using System.Linq; using ZendeskApi_v2.Extensions; using ZendeskApi_v2.Models.Constants; @@ -43,12 +42,12 @@ public void CanGetMacrosPaginated() .Where(x => x.Key == "page") .Select(x => x.Value) .FirstOrDefault(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(nextPage, Is.Not.Null); Assert.That((page + 1).ToString(), Is.EqualTo(nextPage)); - }); + } } [Test] @@ -57,7 +56,7 @@ public void CanCreateUpdateAndDeleteMacros() var create = Api.Macros.CreateMacro(new Macro { Title = "Roger Wilco", - Actions = new List { new Action { Field = "status", Value = new List { "open" } } } + Actions = [new Action { Field = "status", Value = ["open"] }] }); Assert.That(create.Macro.Id, Is.GreaterThan(0)); @@ -75,12 +74,12 @@ public void CanCreateUpdateAndDeleteMacros() }).Ticket; var applyToTicket = Api.Macros.ApplyMacroToTicket(ticket.Id.Value, create.Macro.Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticket.Id, Is.EqualTo(applyToTicket.Result.Ticket.Id)); Assert.That(Api.Tickets.Delete(ticket.Id.Value), Is.True); Assert.That(Api.Macros.DeleteMacro(create.Macro.Id.Value), Is.True); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/Models/Requests/RequestTests.cs b/tests/ZendeskApi_v2.Tests/Models/Requests/RequestTests.cs index 4dd4273e..4d529fb0 100644 --- a/tests/ZendeskApi_v2.Tests/Models/Requests/RequestTests.cs +++ b/tests/ZendeskApi_v2.Tests/Models/Requests/RequestTests.cs @@ -40,7 +40,7 @@ public void TestDeserialize() var openRequest = JsonConvert.DeserializeObject(OpenRequestJson); Assert.That(openRequest, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(openRequest.Url, Is.EqualTo(Url)); Assert.That(openRequest.Id, Is.EqualTo(Id)); @@ -49,14 +49,14 @@ public void TestDeserialize() Assert.That(openRequest.Description, Is.EqualTo(Description)); Assert.That(openRequest.RequesterId, Is.EqualTo(RequesterId)); Assert.That(openRequest.CanBeSolvedByMe, Is.EqualTo(OpenCanBeSolvedByMe)); - }); + } var solvedRequest = JsonConvert.DeserializeObject(SolvedRequestJson); Assert.That(solvedRequest, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(solvedRequest.Status, Is.EqualTo(SolvedStatus)); Assert.That(solvedRequest.CanBeSolvedByMe, Is.EqualTo(SolvedCanBeSolvedByMe)); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/Models/Tickets/FromTests.cs b/tests/ZendeskApi_v2.Tests/Models/Tickets/FromTests.cs index c35568fd..09439597 100644 --- a/tests/ZendeskApi_v2.Tests/Models/Tickets/FromTests.cs +++ b/tests/ZendeskApi_v2.Tests/Models/Tickets/FromTests.cs @@ -15,13 +15,13 @@ public void DeserializeAllFieldsTest() var from = JsonConvert.DeserializeObject(AllFieldsJson); Assert.That(from, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(from.FormattedPhone, Is.EqualTo("+49 89 555 666777")); Assert.That(from.Phone, Is.EqualTo("+4989555666777")); Assert.That(from.Name, Is.EqualTo("Caller +49 89 555 666777")); Assert.That(from.Address, Is.EqualTo("Test")); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/Models/Tickets/ToTests.cs b/tests/ZendeskApi_v2.Tests/Models/Tickets/ToTests.cs index 6340add9..9dbd9abe 100644 --- a/tests/ZendeskApi_v2.Tests/Models/Tickets/ToTests.cs +++ b/tests/ZendeskApi_v2.Tests/Models/Tickets/ToTests.cs @@ -15,13 +15,13 @@ public void DeserializeAllFieldsTest() var to = JsonConvert.DeserializeObject(AllFieldsJson); Assert.That(to, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(to.FormattedPhone, Is.EqualTo("+49 89 555 666777")); Assert.That(to.Phone, Is.EqualTo("+4989555666777")); Assert.That(to.Name, Is.EqualTo("Caller +49 89 555 666777")); Assert.That(to.Address, Is.EqualTo("Test")); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/Models/Voice/FromTests.cs b/tests/ZendeskApi_v2.Tests/Models/Voice/FromTests.cs index 5993ab7b..c531b70a 100644 --- a/tests/ZendeskApi_v2.Tests/Models/Voice/FromTests.cs +++ b/tests/ZendeskApi_v2.Tests/Models/Voice/FromTests.cs @@ -15,13 +15,13 @@ public void DeserializeAllFieldsTest() var from = JsonConvert.DeserializeObject(AllFieldsJson); Assert.That(from, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(from.CurrentQueueActivity.AgentsOnline, Is.EqualTo(3)); Assert.That(from.CurrentQueueActivity.CallsWaiting, Is.EqualTo(13)); Assert.That(from.CurrentQueueActivity.CallbacksWaiting, Is.EqualTo(7)); Assert.That(from.CurrentQueueActivity.AverageWaitTime, Is.EqualTo(142)); Assert.That(from.CurrentQueueActivity.LongestWaitTime, Is.EqualTo(387)); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/OrganizationTests.cs b/tests/ZendeskApi_v2.Tests/OrganizationTests.cs index 78b35f2a..80843d5d 100644 --- a/tests/ZendeskApi_v2.Tests/OrganizationTests.cs +++ b/tests/ZendeskApi_v2.Tests/OrganizationTests.cs @@ -87,7 +87,7 @@ public void CanGetMultipleOrganizations() Name = "Test Org2" }); - var orgs = Api.Organizations.GetMultipleOrganizations(new[] { org.Organization.Id.Value, org2.Organization.Id.Value }); + var orgs = Api.Organizations.GetMultipleOrganizations([org.Organization.Id.Value, org2.Organization.Id.Value]); Assert.That(orgs.Organizations, Has.Count.EqualTo(2)); } @@ -105,12 +105,12 @@ public void CanGetMultipleOrganizationsByExternalId() Name = "Test Org2 with externalId", ExternalId = "TestExternalId2" }); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(org.Organization.Id, Is.GreaterThan(0)); Assert.That(org2.Organization.Id, Is.GreaterThan(0)); - }); - var orgs = Api.Organizations.GetMultipleOrganizationsByExternalIds(new[] { org.Organization.ExternalId, org2.Organization.ExternalId }); + } + var orgs = Api.Organizations.GetMultipleOrganizationsByExternalIds([org.Organization.ExternalId, org2.Organization.ExternalId]); Assert.That(orgs.Organizations, Has.Count.EqualTo(2)); } @@ -127,12 +127,12 @@ public void CanCreateUpdateAndDeleteOrganizations() res.Organization.Notes = "Here is a sample note"; var update = Api.Organizations.UpdateOrganization(res.Organization); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Organization.Notes, Is.EqualTo(update.Organization.Notes)); Assert.That(Api.Organizations.DeleteOrganization(res.Organization.Id.Value), Is.True); - }); + } } [Test] @@ -147,19 +147,19 @@ public void CanCreateOrUpdateOrganizations() res.Organization.Name = "Test Org (updated)"; var update = Api.Organizations.CreateOrUpdateOrganization(res.Organization); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update.Organization.Id, Is.EqualTo(res.Organization.Id)); Assert.That(update.Organization.Name, Is.EqualTo(res.Organization.Name)); Assert.That(Api.Organizations.DeleteOrganization(res.Organization.Id.Value), Is.True); - }); + } } [Test] public void CanCreateMultipleOrganizations() { - var createJobStatus = Api.Organizations.CreateMultipleOrganizations(new[] - { + var createJobStatus = Api.Organizations.CreateMultipleOrganizations( + [ new Organization { Name = "Create Multiple Test Org 1" @@ -168,7 +168,7 @@ public void CanCreateMultipleOrganizations() { Name = "Create Multiple Test Org 2" } - }); + ]); Assert.That(createJobStatus.JobStatus.Status, Is.EqualTo("queued")); JobStatusResponse job; @@ -184,14 +184,14 @@ public void CanCreateMultipleOrganizations() Assert.That(job.JobStatus.Results, Has.Count.EqualTo(2)); foreach (var result in job.JobStatus.Results) - Assert.That(result.Id, Is.Not.EqualTo(0)); + Assert.That(result.Id, Is.Not.Zero); } [Test] public async Task CanCreateMultipleOrganizationsAsync() { - var createJobStatus = await Api.Organizations.CreateMultipleOrganizationsAsync(new[] - { + var createJobStatus = await Api.Organizations.CreateMultipleOrganizationsAsync( + [ new Organization { Name = "Create Multiple Async Test Org 1" @@ -200,7 +200,7 @@ public async Task CanCreateMultipleOrganizationsAsync() { Name = "Create Multiple Async Test Org 2" } - }); + ]); Assert.That(createJobStatus.JobStatus.Status, Is.EqualTo("queued")); JobStatusResponse job; @@ -216,7 +216,7 @@ public async Task CanCreateMultipleOrganizationsAsync() Assert.That(job.JobStatus.Results, Has.Count.EqualTo(2)); foreach (var result in job.JobStatus.Results) - Assert.That(result.Id, Is.Not.EqualTo(0)); + Assert.That(result.Id, Is.Not.Zero); } [Test] @@ -231,12 +231,12 @@ public async Task CanCreateOrUpdateOrganizationsAsync() res.Organization.Name = "Test Org (updated)"; var update = await Api.Organizations.CreateOrUpdateOrganizationAsync(res.Organization); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update.Organization.Id, Is.EqualTo(res.Organization.Id)); Assert.That(update.Organization.Name, Is.EqualTo(res.Organization.Name)); Assert.That(Api.Organizations.DeleteOrganization(res.Organization.Id.Value), Is.True); - }); + } } [Test] @@ -251,11 +251,11 @@ public void CanCreateUpdateAndDeleteMultipleOrganizations() { Name = "Test Org 2" }); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Organization.Id, Is.GreaterThan(0)); Assert.That(res2.Organization.Id, Is.GreaterThan(0)); - }); + } res1.Organization.Notes = "Here is a sample note 1"; res2.Organization.Notes = "Here is a sample note 2"; @@ -276,11 +276,11 @@ public void CanCreateUpdateAndDeleteMultipleOrganizations() var updatedOrganizationIds = new List { res1.Organization.Id.Value, res2.Organization.Id.Value }; var updatedOrganizations = Api.Organizations.GetMultipleOrganizations(updatedOrganizationIds); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updatedOrganizations.Organizations.FirstOrDefault(o => o.Id == res1.Organization.Id).Notes, Is.EqualTo(res1.Organization.Notes)); Assert.That(updatedOrganizations.Organizations.FirstOrDefault(o => o.Id == res2.Organization.Id).Notes, Is.EqualTo(res2.Organization.Notes)); - }); + } Api.Organizations.DeleteOrganization(res1.Organization.Id.Value); Api.Organizations.DeleteOrganization(res2.Organization.Id.Value); } @@ -368,7 +368,7 @@ public void CanDeleteMultipleOrganizationsByExternalIds() foreach (var result in job.JobStatus.Results) { - Assert.That(result.Id, Is.Not.EqualTo(0)); + Assert.That(result.Id, Is.Not.Zero); } var externalIds = orgs.Select(o => o.ExternalId).ToList(); @@ -405,13 +405,13 @@ public void CanCreateAndDeleteOrganizationMemberships() var org_membership = new OrganizationMembership() { UserId = res.User.Id, OrganizationId = org.Organization.Id }; var res2 = Api.Organizations.CreateOrganizationMembership(org_membership); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res2.OrganizationMembership.Id, Is.GreaterThan(0)); Assert.That(Api.Organizations.DeleteOrganizationMembership(res2.OrganizationMembership.Id.Value), Is.True); Assert.That(Api.Users.DeleteUser(res.User.Id.Value), Is.True); Assert.That(Api.Organizations.DeleteOrganization(org.Organization.Id.Value), Is.True); - }); + } } [Test] @@ -453,11 +453,11 @@ public async Task CanCreateUpdateAndDeleteMultipleOrganizationsAsync() { Name = "Test Org 2 Async" }); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Organization.Id, Is.GreaterThan(0)); Assert.That(res2.Organization.Id, Is.GreaterThan(0)); - }); + } res1.Organization.Notes = "Here is a sample note 1"; res2.Organization.Notes = "Here is a sample note 2"; @@ -478,11 +478,11 @@ public async Task CanCreateUpdateAndDeleteMultipleOrganizationsAsync() var updatedOrganizationIds = new List { res1.Organization.Id.Value, res2.Organization.Id.Value }; var updatedOrganizations = await Api.Organizations.GetMultipleOrganizationsAsync(updatedOrganizationIds); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updatedOrganizations.Organizations.FirstOrDefault(o => o.Id == res1.Organization.Id).Notes, Is.EqualTo(res1.Organization.Notes)); Assert.That(updatedOrganizations.Organizations.FirstOrDefault(o => o.Id == res2.Organization.Id).Notes, Is.EqualTo(res2.Organization.Notes)); - }); + } await Api.Organizations.DeleteOrganizationAsync(res1.Organization.Id.Value); await Api.Organizations.DeleteOrganizationAsync(res2.Organization.Id.Value); } diff --git a/tests/ZendeskApi_v2.Tests/RequestTests.cs b/tests/ZendeskApi_v2.Tests/RequestTests.cs index f7e74931..06bde26e 100644 --- a/tests/ZendeskApi_v2.Tests/RequestTests.cs +++ b/tests/ZendeskApi_v2.Tests/RequestTests.cs @@ -22,25 +22,20 @@ public void CanGetAllRequests() [TestCase(1, 2)] public void CanGetAllRequestsPaged(int perPage, int page) { - Assert.DoesNotThrow(() => - { var res = Api.Requests.GetAllRequests(perPage: perPage, page: page); - Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { + Assert.That(res, Is.Not.Null); Assert.That(res.Requests, Is.Not.Null); Assert.That(res.PageSize, Is.EqualTo(perPage)); Assert.That(res.Page, Is.EqualTo(page)); - }); - }); + } } [Test] public void CanGetAllRequestsSorted() { - Assert.DoesNotThrow(() => - { var unsorted = Api.Requests.GetAllRequests(); Assert.That(unsorted, Is.Not.Null); @@ -52,7 +47,6 @@ public void CanGetAllRequestsSorted() Assert.That(sorted, Is.Not.Null); Assert.That(sorted.Requests, Is.Not.Null); Assert.That(sorted.Requests.AsQueryable(), Is.EqualTo(sorted.Requests.OrderBy(request => request.UpdatedAt).AsQueryable())); - }); } [Test] @@ -66,25 +60,20 @@ public void CanGetOpenRequests() [TestCase(1, 2)] public void CanGetAllOpenRequestsPaged(int perPage, int page) { - Assert.DoesNotThrow(() => - { var res = Api.Requests.GetAllOpenRequests(perPage: perPage, page: page); Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Requests, Is.Not.Null); Assert.That(res.PageSize, Is.EqualTo(perPage)); Assert.That(res.Page, Is.EqualTo(page)); - }); - }); + } } [Test] public void CanGetAllOpenRequestsSorted() { - Assert.DoesNotThrow(() => - { var unsorted = Api.Requests.GetAllOpenRequests(); Assert.That(unsorted, Is.Not.Null); @@ -96,7 +85,6 @@ public void CanGetAllOpenRequestsSorted() Assert.That(sorted, Is.Not.Null); Assert.That(sorted.Requests, Is.Not.Null); Assert.That(sorted.Requests.AsQueryable(), Is.EqualTo(sorted.Requests.OrderBy(request => request.UpdatedAt).AsQueryable())); - }); } [Test] @@ -110,25 +98,20 @@ public void CanGetAllSolvedRequests() [TestCase(1, 2)] public void CanGetAllSolvedRequestsPaged(int perPage, int page) { - Assert.DoesNotThrow(() => - { var res = Api.Requests.GetAllSolvedRequests(perPage: perPage, page: page); - Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { + Assert.That(res, Is.Not.Null); Assert.That(res.Requests, Is.Not.Null); Assert.That(res.PageSize, Is.EqualTo(perPage)); Assert.That(res.Page, Is.EqualTo(page)); - }); - }); + } } [Test] public void CanGetAllSolvedRequestsSorted() { - Assert.DoesNotThrow(() => - { var unsorted = Api.Requests.GetAllSolvedRequests(); Assert.That(unsorted, Is.Not.Null); @@ -140,7 +123,6 @@ public void CanGetAllSolvedRequestsSorted() Assert.That(sorted, Is.Not.Null); Assert.That(sorted.Requests, Is.Not.Null); Assert.That(sorted.Requests.AsQueryable(), Is.EqualTo(sorted.Requests.OrderBy(request => request.UpdatedAt).AsQueryable())); - }); } [Test] @@ -156,7 +138,7 @@ public void CanCreateAndUpdateRequests() { Name = "Test Name" }, - Tags = new List { "tag1", "tag2" } + Tags = ["tag1", "tag2"] }; var res = Api.Requests.CreateRequest(req); @@ -166,17 +148,17 @@ public void CanCreateAndUpdateRequests() { Assert.That(res, Is.Not.Null); Assert.That(res.Request, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Request.Id.HasValue, Is.True); Assert.That(res.Request.Type, Is.EqualTo(RequestType.Incident)); Assert.That(res.Request.Id.Value, Is.GreaterThan(0)); - }); + } var user = Api.Users.GetUser(res.Request.RequesterId.Value); Assert.That(user.User.Name, Is.EqualTo("Test Name")); var ticket = Api.Tickets.GetTicket(res.Request.Id.Value); - CollectionAssert.AreEquivalent(new[] { "tag1", "tag2" }, ticket.Ticket.Tags); + Assert.That(ticket.Ticket.Tags, Is.EquivalentTo(["tag1", "tag2"])); var res1 = Api.Requests.GetRequestById(res.Request.Id.Value); Assert.That(res.Request.Id, Is.EqualTo(res1.Request.Id)); @@ -200,11 +182,11 @@ public void CanCreateAndUpdateRequests() res1.Request.RequesterId = 56766413L; var res5 = Api.Requests.UpdateRequest(res1.Request); var res6 = Api.Requests.GetRequestById(res.Request.Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res6.Request.RequesterId, Is.EqualTo(res5.Request.RequesterId)); Assert.That(res3.Comments.Last().Id, Is.EqualTo(res4.Comment.Id)); - }); + } } finally { @@ -231,7 +213,7 @@ public void CanCreateRequestWithEmailCCs() { Name = "Test Name" }, - Tags = new List { "tag1", "tag2" }, + Tags = ["tag1", "tag2"], EmailCCs = emailCCs }; @@ -241,21 +223,21 @@ public void CanCreateRequestWithEmailCCs() { Assert.That(res, Is.Not.Null); Assert.That(res.Request, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Request.Id.HasValue, Is.True); Assert.That(res.Request.Id.Value, Is.GreaterThan(0)); Assert.That(res.Request.Type, Is.EqualTo(RequestType.Incident)); - }); + } var user = Api.Users.GetUser(res.Request.RequesterId.Value); Assert.That(user.User.Name, Is.EqualTo("Test Name")); var ticket = Api.Tickets.GetTicket(res.Request.Id.Value); - CollectionAssert.AreEquivalent(new[] { "tag1", "tag2" }, ticket.Ticket.Tags); + Assert.That(ticket.Ticket.Tags, Is.EquivalentTo(["tag1", "tag2"])); var collaboratorsIds = ticket.Ticket.CollaboratorIds; var collaborators = Api.Users.GetMultipleUsers(collaboratorsIds.AsEnumerable()); - CollectionAssert.AreEquivalent(emailCCs.Select(e => e.UserEmail), collaborators.Users.Select(u => u.Email)); + Assert.That(collaborators.Users.Select(u => u.Email), Is.EquivalentTo(emailCCs.Select(e => e.UserEmail))); } finally { diff --git a/tests/ZendeskApi_v2.Tests/SatisfactionRatingTests.cs b/tests/ZendeskApi_v2.Tests/SatisfactionRatingTests.cs index 753b5b2a..394dc6b6 100644 --- a/tests/ZendeskApi_v2.Tests/SatisfactionRatingTests.cs +++ b/tests/ZendeskApi_v2.Tests/SatisfactionRatingTests.cs @@ -10,23 +10,23 @@ public class SatisfactionRatingTests : TestBase public void CanGetBadSatisfactionRatings() { var receivedSatisfactionRating = Api.SatisfactionRatings.GetSatisfactionRatingById(360342335066); //From Ticket 15157 - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(receivedSatisfactionRating.SatisfactionRating.Score, Is.EqualTo("bad")); Assert.That(receivedSatisfactionRating.SatisfactionRating.Comment, Is.EqualTo("poor job!")); Assert.That(receivedSatisfactionRating.SatisfactionRating.Reason, Is.EqualTo("The issue was not resolved")); - }); + } } [Test] public void CanGetGoodSatisfactionRatings() { var receivedSatisfactionRating = Api.SatisfactionRatings.GetSatisfactionRatingById(360342335186); //From Ticket 15156 - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(receivedSatisfactionRating.SatisfactionRating.Score, Is.EqualTo("good")); Assert.That(receivedSatisfactionRating.SatisfactionRating.Comment, Is.EqualTo("nice job!")); Assert.That(receivedSatisfactionRating.SatisfactionRating.Reason, Is.EqualTo("No reason provided")); - }); + } } } \ No newline at end of file diff --git a/tests/ZendeskApi_v2.Tests/ScheduleTests.cs b/tests/ZendeskApi_v2.Tests/ScheduleTests.cs index 736a3cf3..be341254 100644 --- a/tests/ZendeskApi_v2.Tests/ScheduleTests.cs +++ b/tests/ZendeskApi_v2.Tests/ScheduleTests.cs @@ -64,12 +64,12 @@ public void CanCreateUpdateAndDeleteSchedule() res.Schedule.TimeZone = "Central Time (US & Canada)"; var update = Api.Schedules.UpdateSchedule(res.Schedule); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Schedule.TimeZone, Is.EqualTo(update.Schedule.TimeZone)); Assert.That(Api.Schedules.DeleteSchedule(res.Schedule.Id.Value), Is.True); - }); + } } [Test] @@ -93,11 +93,11 @@ public void CanUpdateIntervals() var update = Api.Schedules.UpdateIntervals(res.Schedule.Id.Value, work); Assert.That(update.WorkWeek.Intervals, Is.Not.Empty); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update.WorkWeek.Intervals[0].EndTime, Is.EqualTo(work.Intervals[0].EndTime)); Assert.That(Api.Schedules.DeleteSchedule(res.Schedule.Id.Value), Is.True); - }); + } } [Test] @@ -120,13 +120,13 @@ public void CanCreateUpdateAndDeleteHoliday() res2.Holiday.EndDate = DateTimeOffset.UtcNow.AddDays(3).Date; var update = Api.Schedules.UpdateHoliday(res.Schedule.Id.Value, res2.Holiday); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res2.Holiday.Name, Is.EqualTo(update.Holiday.Name)); Assert.That(res2.Holiday.EndDate, Is.EqualTo(update.Holiday.EndDate)); Assert.That(Api.Schedules.DeleteHoliday(res.Schedule.Id.Value, res2.Holiday.Id.Value), Is.True); Assert.That(Api.Schedules.DeleteSchedule(res.Schedule.Id.Value), Is.True); - }); + } } } \ No newline at end of file diff --git a/tests/ZendeskApi_v2.Tests/SearchTests.cs b/tests/ZendeskApi_v2.Tests/SearchTests.cs index 66beb235..5f12fd05 100644 --- a/tests/ZendeskApi_v2.Tests/SearchTests.cs +++ b/tests/ZendeskApi_v2.Tests/SearchTests.cs @@ -14,11 +14,11 @@ public class SearchTests : TestBase public void CanSearch() { var res = Api.Search.SearchFor(Admin.Email); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Results[0].ResultType, Is.EqualTo("user")); Assert.That(res.Results[0].Id, Is.GreaterThan(0)); - }); + } } [Test] @@ -35,11 +35,11 @@ public void TotalNumberOftickesShouldbeSameWhenReterivingNextPage() var total = res.Count; Assert.That(res.Count, Is.GreaterThan(0)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Count, Is.GreaterThan(res.Results.Count)); //result has more than one page Assert.That(!string.IsNullOrEmpty(res.NextPage), Is.True); //It has next page - }); + } res = Api.Search.SearchFor("Effective", page: 2); //fetch next page Assert.That(res.Count, Is.GreaterThan(0)); Assert.That(res.Count, Is.EqualTo(total)); //number of results should be same as page 1 @@ -50,12 +50,12 @@ public void TicketHasSubject() { var res = Api.Search.SearchFor("my printer is on fire"); - Assert.That(res, Is.Not.EqualTo(null)); - Assert.Multiple(() => + Assert.That(res, Is.Not.Null); + using (Assert.EnterMultipleScope()) { Assert.That(res.Results, Is.Not.Empty); Assert.That(!string.IsNullOrEmpty(res.Results[0].Subject), Is.True); - }); + } } [Test] @@ -63,24 +63,24 @@ public void TicketSearchByTicketAnonymousType() { var res = Api.Search.SearchFor("my printer is on fire"); - Assert.That(res, Is.Not.EqualTo(null)); - Assert.Multiple(() => + Assert.That(res, Is.Not.Null); + using (Assert.EnterMultipleScope()) { Assert.That(res.Results, Has.Count.GreaterThan(10)); Assert.That(!string.IsNullOrEmpty(res.Results[0].Subject), Is.True); - }); + } var noRes = Api.Search.SearchFor("my printer is on fire"); - Assert.That(noRes, Is.Not.EqualTo(null)); + Assert.That(noRes, Is.Not.Null); Assert.That(noRes.Results, Is.Empty); res = Api.Search.SearchFor("my printer is on fire", perPage: 10); - Assert.That(res, Is.Not.EqualTo(null)); - Assert.Multiple(() => + Assert.That(res, Is.Not.Null); + using (Assert.EnterMultipleScope()) { Assert.That(res.Results, Has.Count.EqualTo(10)); Assert.That(res.Page, Is.EqualTo(1)); - }); + } Assert.That(res.Results[0] is Ticket, Is.True); } @@ -89,24 +89,24 @@ public async Task TicketSearchByTicketAnonymousTypeAsync() { var res = await Api.Search.SearchForAsync("my printer is on fire"); - Assert.That(res, Is.Not.EqualTo(null)); - Assert.Multiple(() => + Assert.That(res, Is.Not.Null); + using (Assert.EnterMultipleScope()) { Assert.That(res.Results, Has.Count.GreaterThan(10)); Assert.That(!string.IsNullOrEmpty(res.Results[0].Subject), Is.True); - }); + } var noRes = await Api.Search.SearchForAsync("my printer is on fire"); - Assert.That(noRes, Is.Not.EqualTo(null)); + Assert.That(noRes, Is.Not.Null); Assert.That(noRes.Results, Is.Empty); res = await Api.Search.SearchForAsync("my printer is on fire", perPage: 10); - Assert.That(res, Is.Not.EqualTo(null)); - Assert.Multiple(() => + Assert.That(res, Is.Not.Null); + using (Assert.EnterMultipleScope()) { Assert.That(res.Results, Has.Count.EqualTo(10)); Assert.That(res.Page, Is.EqualTo(1)); - }); + } Assert.That(res.Results[0] is Ticket, Is.True); } @@ -115,13 +115,13 @@ public void UserSearchByUserAnonymousType() { var res = Api.Search.SearchFor(Admin.Email); - Assert.That(res, Is.Not.EqualTo(null)); + Assert.That(res, Is.Not.Null); Assert.That(res.Results, Has.Count.EqualTo(1)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Results[0].Id, Is.EqualTo(Admin.ID)); Assert.That(res.Results[0] is User, Is.True); - }); + } } [Test] @@ -129,13 +129,13 @@ public async Task UserSearchByUserAnonymousTypeAsync() { var res = await Api.Search.SearchForAsync(Admin.Email); - Assert.That(res, Is.Not.EqualTo(null)); + Assert.That(res, Is.Not.Null); Assert.That(res.Results, Has.Count.EqualTo(1)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Results[0].Id, Is.EqualTo(Admin.ID)); Assert.That(res.Results[0] is User, Is.True); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/TargetTests.cs b/tests/ZendeskApi_v2.Tests/TargetTests.cs index b0612720..2f3ceb95 100644 --- a/tests/ZendeskApi_v2.Tests/TargetTests.cs +++ b/tests/ZendeskApi_v2.Tests/TargetTests.cs @@ -22,44 +22,6 @@ public void Setup() } } - [Test, Ignore("DeprecatedTargetType")] - public void CanCreateUpdateAndDeleteHttpTargets() - { - var target = new HTTPTarget() - { - Title = "Test Email Target", - Active = false, - TargetUrl = "https://test.com", - ContentType = "application/json", - Method = "post", - Username = "TestUser", - Password = "TestPass" - }; - - var targetResult = (HTTPTarget)Api.Targets.CreateTarget(target).Target; - Assert.That(targetResult, Is.Not.Null); - Assert.That(targetResult, Is.InstanceOf()); - Assert.Multiple(() => - { - Assert.That(targetResult.Active, Is.False); - Assert.That(targetResult.TargetUrl, Is.EqualTo("https://test.com")); - Assert.That(targetResult.Type, Is.EqualTo("http_target")); - Assert.That(targetResult.ContentType, Is.EqualTo("application/json")); - Assert.That(targetResult.Method, Is.EqualTo("post")); - Assert.That(targetResult.Username, Is.EqualTo("TestUser")); - Assert.That(targetResult.Password, Is.Null); - }); - targetResult.Active = true; - - var update = (HTTPTarget)Api.Targets.UpdateTarget(targetResult).Target; - Assert.Multiple(() => - { - Assert.That(update.Active, Is.EqualTo(targetResult.Active)); - - Assert.That(Api.Targets.DeleteTarget(update.Id.Value), Is.True); - }); - } - [Test] public void CanCreateUpdateAndDeleteTargets() { @@ -74,21 +36,21 @@ public void CanCreateUpdateAndDeleteTargets() var emailResult = (EmailTarget)Api.Targets.CreateTarget(target).Target; Assert.That(emailResult, Is.Not.Null); Assert.That(emailResult, Is.InstanceOf()); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(emailResult.Type, Is.EqualTo("email_target")); Assert.That(emailResult.Email, Is.EqualTo("test@test.com")); Assert.That(emailResult.Subject, Is.EqualTo("Test")); - }); + } emailResult.Subject = "Test Update"; var update = (EmailTarget)Api.Targets.UpdateTarget(emailResult).Target; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(update.Subject, Is.EqualTo(emailResult.Subject)); Assert.That(Api.Targets.DeleteTarget(emailResult.Id.Value), Is.True); - }); + } } [Test] @@ -119,10 +81,10 @@ public void CanRetrieveMultipleTargetTypes() Assert.That(emailResult2, Is.Not.Null); Assert.That(emailResult2, Is.InstanceOf()); _ = Api.Targets.GetAllTargets(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(Api.Targets.DeleteTarget(emailResult.Id.Value), Is.True); Assert.That(Api.Targets.DeleteTarget(emailResult2.Id.Value), Is.True); - }); + } } } \ No newline at end of file diff --git a/tests/ZendeskApi_v2.Tests/TicketTestPart2.cs b/tests/ZendeskApi_v2.Tests/TicketTestPart2.cs index 6b39fed4..22c2207f 100644 --- a/tests/ZendeskApi_v2.Tests/TicketTestPart2.cs +++ b/tests/ZendeskApi_v2.Tests/TicketTestPart2.cs @@ -23,7 +23,7 @@ public async Task TestSetUp() Title = "testing", Description = "test description", TitleInPortal = "Test Tagger", - CustomFieldOptions = new List(), + CustomFieldOptions = [], Active = true }; @@ -62,11 +62,11 @@ public async Task CanGetTicketsByExternalIdAsync() var resp1 = await Api.Tickets.CreateTicketAsync(ticket); var response = await Api.Tickets.GetTicketsByExternalIdAsync(ticket.ExternalId); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(response.Tickets, Is.Not.Empty); Assert.That(await Api.Tickets.DeleteAsync(resp1.Ticket.Id.Value), Is.True); - }); + } } [Test] @@ -82,11 +82,11 @@ public void CanGetTicketsByExternalId() var resp1 = Api.Tickets.CreateTicket(ticket); var response = Api.Tickets.GetTicketsByExternalId(ticket.ExternalId); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(response.Tickets, Is.Not.Empty); Assert.That(Api.Tickets.Delete(resp1.Ticket.Id.Value), Is.True); - }); + } } [Test] @@ -122,7 +122,7 @@ public async Task CanBatchUpdateTickets() var job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", System.StringComparison.CurrentCultureIgnoreCase) && count < 10) { await Task.Delay(1000); job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); @@ -147,7 +147,7 @@ public async Task CustomDropDownFieldSaveAsync() Subject = "my printer is on fire", Comment = new Comment { Body = "HELP" }, Priority = TicketPriorities.Urgent, - CustomFields = new List { new CustomField { Id = customDropDownId, Value = "mywork" } }, + CustomFields = [new CustomField { Id = customDropDownId, Value = "mywork" }], ExternalId = TEST_EXTERNAL_ID }; @@ -159,13 +159,13 @@ public async Task CustomDropDownFieldSaveAsync() var resp2 = await Api.Tickets.UpdateTicketAsync(newTicket, new Comment { Body = "Update ticket" }); var updateTicket = resp2.Ticket; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(newTicket.CustomFields.FirstOrDefault(x => x.Id == customDropDownId).Value, Is.EqualTo(updateTicket.CustomFields.FirstOrDefault(x => x.Id == customDropDownId).Value)); Assert.That(Api.Tickets.Delete(newTicket.Id.Value), Is.True); - }); + } } [Test] @@ -191,7 +191,7 @@ public async Task CanGetFollowUpIds() var resp3 = await Api.Tickets.CreateTicketAsync(ticket_Followup); var resp4 = Api.Tickets.GetTicket(closedTicket.Id.Value); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(resp3.Ticket.Via.Source.Rel, Is.EqualTo("follow_up")); Assert.That(resp4.Ticket.FollowUpIds, Has.Count.EqualTo(1)); @@ -199,6 +199,6 @@ public async Task CanGetFollowUpIds() Assert.That(await Api.Tickets.DeleteAsync(resp3.Ticket.Id.Value), Is.True); Assert.That(await Api.Tickets.DeleteAsync(closedTicket.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/TicketTests.cs b/tests/ZendeskApi_v2.Tests/TicketTests.cs index c1c5e1ea..a31b5eb3 100644 --- a/tests/ZendeskApi_v2.Tests/TicketTests.cs +++ b/tests/ZendeskApi_v2.Tests/TicketTests.cs @@ -47,11 +47,11 @@ public void CanGetTicketsAsyncWithSideLoad() { var tickets = Api.Tickets.GetAllTicketsAsync(sideLoadOptions: ticketSideLoadOptions); Assert.That(tickets.Result.Count, Is.GreaterThan(0)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Result.Users.Any(), Is.True); Assert.That(tickets.Result.Organizations.Any(), Is.True); - }); + } } [Test] @@ -80,11 +80,11 @@ public void CanGetTicketsWithSideLoad() { var tickets = Api.Tickets.GetAllTickets(sideLoadOptions: ticketSideLoadOptions); Assert.That(tickets.Count, Is.GreaterThan(0)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Users.Any(), Is.True); Assert.That(tickets.Organizations.Any(), Is.True); - }); + } } [Test] @@ -105,12 +105,12 @@ public void CanGetTicketsPaged() .Where(x => x.Key == "page") .Select(x => x.Value) .FirstOrDefault(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(nextPage, Is.Not.Null); Assert.That((page + 1).ToString(), Is.EqualTo(nextPage)); - }); + } } [Test] @@ -118,11 +118,11 @@ public void CanGetTicketById() { var id = Settings.SampleTicketId; var ticket = Api.Tickets.GetTicket(id).Ticket; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticket, Is.Not.Null); Assert.That(id, Is.EqualTo(ticket.Id)); - }); + } } [Test] @@ -131,14 +131,14 @@ public void CanGetTicketByIdWithSideLoad() var id = Settings.SampleTicketId; var ticket = Api.Tickets.GetTicket(id, sideLoadOptions: ticketSideLoadOptions); Assert.That(ticket, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticket.Ticket, Is.Not.Null); Assert.That(id, Is.EqualTo(ticket.Ticket.Id)); Assert.That(ticket.Users.Any(), Is.True); Assert.That(ticket.Organizations.Any(), Is.True); Assert.That(ticket.Ticket.Dates, Is.Not.Null); - }); + } } [Test] @@ -154,12 +154,12 @@ public void CanGetTicketsByOrganizationIdPaged() { var id = Organization.ID; var ticketsRes = Api.Tickets.GetTicketsByOrganizationID(id, 2, 3); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketsRes.PageSize, Is.EqualTo(3)); Assert.That(ticketsRes.Tickets, Has.Count.EqualTo(3)); Assert.That(ticketsRes.Count, Is.GreaterThan(0)); - }); + } var nextPage = ticketsRes.NextPage.GetQueryStringDict() .Where(x => x.Key == "page") .Select(x => x.Value) @@ -174,12 +174,12 @@ public void CanGetTicketsByOrganizationIdPaged() public void CanGetTicketsByViewIdPaged() { var ticketsRes = Api.Tickets.GetTicketsByViewID(Settings.ViewId, 10, 2); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketsRes.PageSize, Is.EqualTo(10)); Assert.That(ticketsRes.Tickets, Has.Count.EqualTo(10)); Assert.That(ticketsRes.Count, Is.GreaterThan(0)); - }); + } var nextPage = ticketsRes.NextPage.GetQueryStringDict() .Where(x => x.Key == "page") .Select(x => x.Value) @@ -204,23 +204,23 @@ public void CanGetTicketsByViewIdPagedWithSideLoad() public async Task CanTicketsByUserIdPagedAsyncWithSideLoad() { var ticketsRes = await Api.Tickets.GetTicketsByUserIDAsync(Admin.ID, 50, 2, sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketsRes.Users.Any(), Is.True); Assert.That(ticketsRes.Organizations.Any(), Is.True); - }); + } } [Test] public void CanAssignedTicketsByUserIdPaged() { var ticketsRes = Api.Tickets.GetAssignedTicketsByUserID(Admin.ID, 5, 2); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketsRes.PageSize, Is.EqualTo(5)); Assert.That(ticketsRes.Tickets, Has.Count.EqualTo(5)); Assert.That(ticketsRes.Count, Is.GreaterThan(0)); - }); + } var nextPage = ticketsRes.NextPage.GetQueryStringDict() .Where(x => x.Key == "page") .Select(x => x.Value) @@ -235,11 +235,11 @@ public void CanAssignedTicketsByUserIdPaged() public void CanAssignedTicketsByUserIdPagedAsyncWithSideLoad() { var ticketsRes = Api.Tickets.GetAssignedTicketsByUserIDAsync(Admin.ID, 5, 2, sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketsRes.Result.Users.Any(), Is.True); Assert.That(ticketsRes.Result.Organizations.Any(), Is.True); - }); + } } [Test] @@ -247,11 +247,11 @@ public void CanGetMultipleTickets() { var ids = new List() { Settings.SampleTicketId, Settings.SampleTicketId2 }; var tickets = Api.Tickets.GetMultipleTickets(ids); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets, Is.Not.Null); Assert.That(ids, Has.Count.EqualTo(tickets.Count)); - }); + } } [Test] @@ -259,11 +259,11 @@ public async Task CanGetMultipleTicketsAsync() { var ids = new List() { Settings.SampleTicketId, Settings.SampleTicketId2 }; var tickets = await Api.Tickets.GetMultipleTicketsAsync(ids); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets, Is.Not.Null); Assert.That(ids, Has.Count.EqualTo(tickets.Count)); - }); + } } [Test] @@ -271,16 +271,16 @@ public void CanGetMultipleTicketsWithSideLoad() { var ids = new List() { Settings.SampleTicketId, Settings.SampleTicketId2 }; var tickets = Api.Tickets.GetMultipleTickets(ids, sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets, Is.Not.Null); Assert.That(ids, Has.Count.EqualTo(tickets.Count)); - }); - Assert.Multiple(() => + } + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Users.Any(), Is.True); Assert.That(tickets.Organizations.Any(), Is.True); - }); + } } [Test] @@ -288,16 +288,16 @@ public async Task CanGetMultipleTicketsAsyncWithSideLoad() { var ids = new List() { Settings.SampleTicketId, Settings.SampleTicketId2 }; var tickets = await Api.Tickets.GetMultipleTicketsAsync(ids, sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets, Is.Not.Null); Assert.That(ids, Has.Count.EqualTo(tickets.Count)); - }); - Assert.Multiple(() => + } + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Users.Any(), Is.True); Assert.That(tickets.Organizations.Any(), Is.True); - }); + } } [Test] @@ -305,11 +305,11 @@ public void CanGetMultipleTicketsSingleTicket() { var ids = new List() { Settings.SampleTicketId }; var tickets = Api.Tickets.GetMultipleTickets(ids); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets, Is.Not.Null); Assert.That(ids, Has.Count.EqualTo(tickets.Count)); - }); + } } [Test] @@ -317,11 +317,11 @@ public async Task CanGetMultipleTicketsAsyncSingleTicket() { var ids = new List() { Settings.SampleTicketId }; var tickets = await Api.Tickets.GetMultipleTicketsAsync(ids); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets, Is.Not.Null); Assert.That(ids, Has.Count.EqualTo(tickets.Count)); - }); + } } [Test] @@ -332,8 +332,8 @@ public void BooleanCustomFieldValuesArePreservedOnUpdate() Subject = "my printer is on fire", Comment = new Comment() { Body = "HELP" }, Priority = TicketPriorities.Urgent, - CustomFields = new List() - { + CustomFields = + [ new CustomField() { Id = Settings.CustomFieldId, @@ -344,19 +344,19 @@ public void BooleanCustomFieldValuesArePreservedOnUpdate() Id = Settings.CustomBoolFieldId, Value = true } - } + ] }; var res = Api.Tickets.CreateTicket(ticket).Ticket; - Assert.That(res.CustomFields.Where(f => f.Id == Settings.CustomBoolFieldId).FirstOrDefault().Value, Is.EqualTo(ticket.CustomFields[1].Value)); + Assert.That(res.CustomFields.FirstOrDefault(f => f.Id == Settings.CustomBoolFieldId).Value, Is.EqualTo(ticket.CustomFields[1].Value)); var updateResponse = Api.Tickets.UpdateTicket(res, new Comment() { Body = "Just trying to update it!", Public = true }); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updateResponse.Ticket.CustomFields[1].Value, Is.EqualTo(ticket.CustomFields[1].Value)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); - }); + } } [Test] @@ -367,25 +367,25 @@ public void CanCreateUpdateAndDeleteTicket() Subject = "my printer is on fire", Comment = new Comment() { Body = "HELP" }, Priority = TicketPriorities.Urgent, - CustomFields = new List() - { + CustomFields = + [ new CustomField() { Id = Settings.CustomFieldId, Value = "testing" } - } + ] }; var res = Api.Tickets.CreateTicket(ticket).Ticket; Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Id, Is.GreaterThan(0)); Assert.That(res.UpdatedAt, Is.EqualTo(res.CreatedAt)); - }); + } res.Status = TicketStatus.Solved; res.AssigneeId = Admin.ID; @@ -394,14 +394,14 @@ public void CanCreateUpdateAndDeleteTicket() res.CustomFields[0].Value = "updated"; - var updateResponse = Api.Tickets.UpdateTicket(res, new Comment() { Body = body, Public = true, Uploads = new List() }); - Assert.Multiple(() => + var updateResponse = Api.Tickets.UpdateTicket(res, new Comment() { Body = body, Public = true, Uploads = [] }); + using (Assert.EnterMultipleScope()) { Assert.That(updateResponse, Is.Not.Null); Assert.That(updateResponse.Ticket.CollaboratorIds, Is.Not.Empty); Assert.That(updateResponse.Ticket.UpdatedAt, Is.GreaterThanOrEqualTo(updateResponse.Ticket.CreatedAt)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); - }); + } } [Test] @@ -412,26 +412,26 @@ public void CanPermanentlyDeleteTicket() Subject = "my printer is on fire", Comment = new Comment() { Body = "HELP" }, Priority = TicketPriorities.Urgent, - CustomFields = new List() - { + CustomFields = + [ new CustomField() { Id = Settings.CustomFieldId, Value = "testing" } - } + ] }; var res = Api.Tickets.CreateTicket(ticket).Ticket; Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Id, Is.GreaterThan(0)); Assert.That(res.UpdatedAt, Is.EqualTo(res.CreatedAt)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); Assert.That(Api.Tickets.DeleteTicketPermanently(res.Id.Value), Is.True); - }); + } } [Test] @@ -442,24 +442,24 @@ public void CanCreateUpdateAndDeleteHTMLTicket() Subject = "my printer is on fire", Comment = new Comment() { HtmlBody = "HELP
HELP On a New line." }, Priority = TicketPriorities.Urgent, - CustomFields = new List() - { + CustomFields = + [ new CustomField() { Id = Settings.CustomFieldId, Value = "testing" } - } + ] }; var res = Api.Tickets.CreateTicket(ticket).Ticket; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res, Is.Not.Null); Assert.That(res.Id, Is.GreaterThan(0)); Assert.That(res.UpdatedAt, Is.EqualTo(res.CreatedAt)); - }); + } res.Status = TicketStatus.Solved; res.AssigneeId = Admin.ID; @@ -469,15 +469,15 @@ public void CanCreateUpdateAndDeleteHTMLTicket() res.CustomFields[0].Value = "updated"; - var updateResponse = Api.Tickets.UpdateTicket(res, new Comment() { HtmlBody = htmlBody, Public = true, Uploads = new List() }); + var updateResponse = Api.Tickets.UpdateTicket(res, new Comment() { HtmlBody = htmlBody, Public = true, Uploads = [] }); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updateResponse, Is.Not.Null); Assert.That(updateResponse.Ticket.CollaboratorIds, Is.Not.Empty); Assert.That(updateResponse.Ticket.UpdatedAt, Is.GreaterThanOrEqualTo(updateResponse.Ticket.CreatedAt)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); - }); + } } [Test] @@ -498,11 +498,11 @@ public void CanGetTicketHTMLComments() public void CanGetTicketCommentsWithSideLoading() { var comments = Api.Tickets.GetTicketComments(2, sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(comments.Users, Is.Not.Empty); Assert.That(comments.Organizations, Is.Null); - }); + } } [Test] @@ -511,12 +511,12 @@ public void CanGetTicketCommentsPaged() const int perPage = 5; const int page = 2; var commentsRes = Api.Tickets.GetTicketComments(2, perPage, page); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(commentsRes.Comments, Has.Count.EqualTo(perPage)); Assert.That(commentsRes.PageSize, Is.EqualTo(perPage)); Assert.That(commentsRes.Page, Is.EqualTo(page)); - }); + } Assert.That(commentsRes.Comments[1].Body, Is.Not.Empty); var nextPageValue = commentsRes.NextPage.GetQueryStringDict() @@ -536,11 +536,11 @@ public void CanGetTicketCommentsPagedAndSorted() const int page = 1; var commentsRes = Api.Tickets.GetTicketComments(2, perPage, page); var commentsRes2 = Api.Tickets.GetTicketComments(2, false, perPage, page); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(commentsRes.Comments[0].CreatedAt, Is.EqualTo(new DateTimeOffset(2012, 10, 30, 13, 35, 11, TimeSpan.Zero))); Assert.That(commentsRes2.Comments[0].CreatedAt, Is.EqualTo(new DateTimeOffset(2014, 01, 24, 03, 29, 30, TimeSpan.Zero))); - }); + } } [Test] @@ -557,12 +557,12 @@ public void CanCreateTicketWithRequester() var res = Api.Tickets.CreateTicket(ticket).Ticket; Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.RequesterId, Is.EqualTo(Settings.CollaboratorId)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); - }); + } } [Test] @@ -580,12 +580,12 @@ public async Task CanCreateTicketWithRequesterAsync() Assert.That(res, Is.Not.Null); Assert.That(res.Ticket, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Ticket.RequesterId, Is.EqualTo(Settings.CollaboratorId)); Assert.That(Api.Tickets.Delete(res.Ticket.Id.Value), Is.True); - }); + } } [Test] @@ -606,12 +606,12 @@ public void CanCreateTicketWithDueDate() var res = Api.Tickets.CreateTicket(ticket).Ticket; Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.DueAt, Is.EqualTo(dueAt)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); - }); + } } [Test] @@ -628,12 +628,12 @@ public void CanCreateTicketWithTicketFormId() var res = Api.Tickets.CreateTicket(ticket).Ticket; Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketFormId, Is.EqualTo(Settings.TicketFormId)); Assert.That(Api.Tickets.Delete(res.Id.Value), Is.True); - }); + } } [Test] @@ -652,11 +652,11 @@ public void CanBulkUpdateTickets() Priority = TicketPriorities.Normal }).Ticket; - var res = Api.Tickets.BulkUpdate(new List() { t1.Id.Value, t2.Id.Value }, new BulkUpdate() + var res = Api.Tickets.BulkUpdate([t1.Id.Value, t2.Id.Value], new BulkUpdate() { Status = TicketStatus.Solved, Comment = new Comment() { Public = true, Body = "check your email" }, - CollaboratorEmails = new List() { Settings.ColloboratorEmail }, + CollaboratorEmails = [Settings.ColloboratorEmail], AssigneeId = Admin.ID }); @@ -664,12 +664,12 @@ public void CanBulkUpdateTickets() //also test JobStatuses while we have a job here var job = Api.JobStatuses.GetJobStatus(res.JobStatus.Id); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.JobStatus.Id, Is.EqualTo(job.JobStatus.Id)); - Assert.That(Api.Tickets.DeleteMultiple(new List() { t1.Id.Value, t2.Id.Value }), Is.True); - }); + Assert.That(Api.Tickets.DeleteMultiple([t1.Id.Value, t2.Id.Value]), Is.True); + } } [Test] @@ -690,17 +690,17 @@ public async Task CanAddAttachmentToTicketAsync() { Body = "comments are required for attachments", Public = true, - Uploads = new List() { res.Token } + Uploads = [res.Token] }, }; var t1 = await Api.Tickets.CreateTicketAsync(ticket); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(t1.Audit.Events.First().Attachments, Has.Count.EqualTo(1)); Assert.That(await Api.Tickets.DeleteAsync(t1.Ticket.Id.Value), Is.True); - }); + } } [Test] @@ -723,17 +723,17 @@ public void CanAddAttachmentToTicket() { Body = "comments are required for attachments", Public = true, - Uploads = new List() { res.Token } + Uploads = [res.Token] }, }; var t1 = Api.Tickets.CreateTicket(ticket); Assert.That(t1.Audit.Events.First().Attachments, Has.Count.EqualTo(1)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(Api.Tickets.Delete(t1.Ticket.Id.Value), Is.True); Assert.That(Api.Attachments.DeleteUpload(res)); - }); + } } [Test] @@ -764,12 +764,12 @@ public void CanGetIncidents() }).Ticket; var res = Api.Tickets.GetIncidents(t1.Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Tickets, Is.Not.Empty); - Assert.That(Api.Tickets.DeleteMultiple(new List() { t1.Id.Value, t2.Id.Value }), Is.True); - }); + Assert.That(Api.Tickets.DeleteMultiple([t1.Id.Value, t2.Id.Value]), Is.True); + } } [Test] @@ -784,73 +784,14 @@ public void CanGetProblems() }).Ticket; var res = Api.Tickets.GetProblems(); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Tickets, Is.Not.Empty); Assert.That(Api.Tickets.Delete(t1.Id.Value), Is.True); - }); + } } - //[Test] - //public void CanGetIncrementalTicketExportPaged() - //{ - // Thread.Sleep(60000); - // const int maxTicketsPerPage = 1000; - - // var res = Api.Tickets.GetIncrementalTicketExport(DateTime.Now.AddDays(-365)); - - // Assert.AreEqual(maxTicketsPerPage, res.Tickets.Count); - // Assert.That(res.NextPage, Is.Not.Null.Or.Empty); - //} - - //[Test] - //public void CanGetIncrementalTicketExportWithUsersSideLoadPaged() - //{ - // Thread.Sleep(60000); - // const int maxTicketsPerPage = 1000; - - // GroupTicketExportResponse res = Api.Tickets.GetIncrementalTicketExport(DateTime.Now.AddDays(-365), TicketSideLoadOptionsEnum.Users); - - // Assert.AreEqual(maxTicketsPerPage, res.Tickets.Count); - // Assert.IsTrue(res.Users.Count > 0); - // Assert.That(res.NextPage, Is.Not.Null.Or.Empty); - - // res = Api.Tickets.GetIncrementalTicketExportNextPage(res.NextPage); - - // Assert.IsTrue(res.Tickets.Count > 0); - // Assert.IsTrue(res.Users.Count > 0); - //} - - //[Test] - //public void CanGetIncrementalTicketExportWithGroupsSideLoadPaged() - //{ - // Thread.Sleep(60000); - - // const int maxTicketsPerPage = 1000; - - // var res = Api.Tickets.GetIncrementalTicketExport(DateTime.Now.AddDays(-700), TicketSideLoadOptionsEnum.Groups); - - // Assert.AreEqual(maxTicketsPerPage, res.Tickets.Count); - // Assert.IsTrue(res.Groups.Count > 0); - // Assert.That(res.NextPage, Is.Not.Null.Or.Empty); - - // res = Api.Tickets.GetIncrementalTicketExportNextPage(res.NextPage); - - // Assert.IsTrue(res.Tickets.Count > 0); - // Assert.IsTrue(res.Groups.Count > 0); - //} - - //[Test] - //public async Task CanGetIncrementalTicketExportAsyncWithSideLoadOptions() - //{ - // await Task.Delay(60000); - // var res = await Api.Tickets.GetIncrementalTicketExportAsync(DateTime.Now.AddDays(-31), TicketSideLoadOptionsEnum.Users); - - // Assert.That(res.Count, Is.GreaterThan(0)); - // Assert.That(res.Users, Is.Not.Null); - //} - [Test] public void CanGetTicketFields() { @@ -863,11 +804,11 @@ public void CanGetTicketFieldById() { var id = Settings.CustomFieldId; var ticketField = Api.Tickets.GetTicketFieldById(id).TicketField; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketField, Is.Not.Null); Assert.That(id, Is.EqualTo(ticketField.Id)); - }); + } } [Test] @@ -875,11 +816,11 @@ public void CanGetTicketFieldByIdAsync() { var id = Settings.CustomFieldId; var ticketField = Api.Tickets.GetTicketFieldByIdAsync(id).Result.TicketField; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(ticketField, Is.Not.Null); Assert.That(id, Is.EqualTo(ticketField.Id)); - }); + } } [Test] @@ -898,12 +839,12 @@ public void CanCreateUpdateAndDeleteTicketFields() updatedTF.Title = "My Custom Field"; var updatedRes = Api.Tickets.UpdateTicketField(updatedTF); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(updatedTF.Title, Is.EqualTo(updatedRes.TicketField.Title)); Assert.That(Api.Tickets.DeleteTicketField(updatedTF.Id.Value), Is.True); - }); + } } [TestCase(true, "test entry", "test_entry")] @@ -916,7 +857,7 @@ public void CanCreateAndDeleteTaggerTicketField(bool replaceNameSpaceWithUndersc Title = "My Tagger", Description = "test description", TitleInPortal = "Test Tagger", - CustomFieldOptions = new List() + CustomFieldOptions = [] }; tField.CustomFieldOptions.Add(new CustomFieldOptions() @@ -926,13 +867,13 @@ public void CanCreateAndDeleteTaggerTicketField(bool replaceNameSpaceWithUndersc }); var res = Api.Tickets.CreateTicketField(tField, replaceNameSpaceWithUnderscore); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketField, Is.Not.Null); Assert.That(expectedName, Is.EqualTo(res.TicketField.CustomFieldOptions[0].Name)); Assert.That(Api.Tickets.DeleteTicketField(res.TicketField.Id.Value), Is.True); - }); + } } [TestCase(true, "test entryA", "test entryA newTitle", "test entryB", "test entryC", "test_entryA", "test_entryA_newTitle", "test_entryB", "test_entryC")] @@ -953,7 +894,7 @@ public void CanCreateUpdateOptionsAndDeleteTaggerTicketField(bool replaceNameSpa Title = "My Tagger 2", Description = "test description", TitleInPortal = "Test Tagger", - CustomFieldOptions = new List() + CustomFieldOptions = [] }; tField.CustomFieldOptions.Add(new CustomFieldOptions() @@ -970,24 +911,24 @@ public void CanCreateUpdateOptionsAndDeleteTaggerTicketField(bool replaceNameSpa var res = Api.Tickets.CreateTicketField(tField, replaceNameSpaceWithUnderscore); Assert.That(res.TicketField, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketField.Id, Is.Not.Null); Assert.That(res.TicketField.CustomFieldOptions, Has.Count.EqualTo(2)); - }); + } Assert.That(res.TicketField.CustomFieldOptions[0].Value, Is.EqualTo(option1)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketField.CustomFieldOptions[1].Value, Is.EqualTo(option2)); Assert.That(res.TicketField.CustomFieldOptions[0].Name, Is.EqualTo(expectedName1)); Assert.That(res.TicketField.CustomFieldOptions[1].Name, Is.EqualTo(expectedName2)); - }); + } var id = res.TicketField.Id.Value; var tFieldU = new TicketField() { Id = id, - CustomFieldOptions = new List() + CustomFieldOptions = [] }; //update CustomFieldOption A @@ -1007,7 +948,7 @@ public void CanCreateUpdateOptionsAndDeleteTaggerTicketField(bool replaceNameSpa var resU = Api.Tickets.UpdateTicketField(tFieldU, replaceNameSpaceWithUnderscore); Assert.That(resU.TicketField.CustomFieldOptions, Has.Count.EqualTo(2)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resU.TicketField.CustomFieldOptions[0].Value, Is.EqualTo(option1_Update.Replace(" ", "_"))); Assert.That(resU.TicketField.CustomFieldOptions[1].Value, Is.EqualTo(option3)); @@ -1015,7 +956,7 @@ public void CanCreateUpdateOptionsAndDeleteTaggerTicketField(bool replaceNameSpa Assert.That(resU.TicketField.CustomFieldOptions[1].Name, Is.EqualTo(expectedName3)); Assert.That(Api.Tickets.DeleteTicketField(id), Is.True); - }); + } } [Test] @@ -1060,12 +1001,12 @@ public void CanCreateUpdateAndDeleteTicketForms() res.TicketForm.Active = false; var update = Api.Tickets.UpdateTicketForm(res.TicketForm); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketForm.Name, Is.EqualTo(update.TicketForm.Name)); Assert.That(Api.Tickets.DeleteTicketForm(res.TicketForm.Id.Value), Is.True); - }); + } } [Test] @@ -1090,11 +1031,11 @@ public void CanGetTicketMetricByTicketId() { var id = Settings.SampleTicketId; var metric = Api.Tickets.GetTicketMetricsForTicket(id).TicketMetric; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(metric, Is.Not.Null); Assert.That(id, Is.EqualTo(metric.TicketId)); - }); + } } [Test] @@ -1102,11 +1043,11 @@ public void CanGetTicketMetricByTicketIdAsync() { var id = Settings.SampleTicketId; var metric = Api.Tickets.GetTicketMetricsForTicketAsync(id).Result.TicketMetric; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(metric, Is.Not.Null); Assert.That(id, Is.EqualTo(metric.TicketId)); - }); + } } [Test] @@ -1114,11 +1055,11 @@ public void CanGetAllTicketsWithSideLoad() { var tickets = Api.Tickets.GetAllTickets(sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Users.Any(), Is.True); Assert.That(tickets.Organizations.Any(), Is.True); - }); + } } [Test] @@ -1126,12 +1067,12 @@ public void CanGetAllTicketsAsyncWithSideLoad() { var tickets = Api.Tickets.GetAllTicketsAsync(sideLoadOptions: ticketSideLoadOptions); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Result.Users.Any(), Is.True); Assert.That(tickets.Result.Organizations.Any(), Is.True); Assert.That(tickets.Result.Tickets, Has.Count.EqualTo(tickets.Result.Tickets.Where(t => t.CommentCount.HasValue).Count())); - }); + } } [Test] @@ -1140,11 +1081,11 @@ public void CanGetTicketsByOrganizationIDAsyncWithSideLoad() var id = Organization.ID; var tickets = Api.Tickets.GetTicketsByOrganizationIDAsync(id, sideLoadOptions: ticketSideLoadOptions); Assert.That(tickets.Result.Count, Is.GreaterThan(0)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Result.Users.Any(), Is.True); Assert.That(tickets.Result.Organizations.Any(), Is.True); - }); + } } [Test] @@ -1153,11 +1094,11 @@ public void CanCanGetTicketsByOrganizationIDWithSideLoad() var id = Organization.ID; var tickets = Api.Tickets.GetTicketsByOrganizationID(id, sideLoadOptions: ticketSideLoadOptions); Assert.That(tickets.Count, Is.GreaterThan(0)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(tickets.Users.Any(), Is.True); Assert.That(tickets.Organizations.Any(), Is.True); - }); + } } [Test] @@ -1166,7 +1107,7 @@ public void CanImportTicket() var ticket = new TicketImport() { Subject = "my printer is on fire", - Comments = new List { new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 1", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-2) }, new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 2", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-3) } }, + Comments = [new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 1", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-2) }, new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 2", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-3) }], Priority = TicketPriorities.Urgent, CreatedAt = DateTime.Now.AddDays(-5), UpdatedAt = DateTime.Now.AddDays(-4), @@ -1179,7 +1120,7 @@ public void CanImportTicket() var res = Api.Tickets.ImportTicket(ticket).Ticket; Assert.That(res, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Id.HasValue, Is.True); Assert.That(res.Id.Value, Is.GreaterThan(0)); @@ -1187,7 +1128,7 @@ public void CanImportTicket() Assert.That(res.UpdatedAt.Value.LocalDateTime, Is.GreaterThan(res.CreatedAt.Value.LocalDateTime)); Assert.That(res.Status, Is.EqualTo(TicketStatus.Solved)); Assert.That(res.Description, Is.EqualTo("test description")); - }); + } var resComments = Api.Tickets.GetTicketComments(res.Id.Value); Assert.That(resComments, Is.Not.Null); Assert.That(resComments.Count, Is.EqualTo(3)); @@ -1201,7 +1142,7 @@ public void CanImportTicketAsync() var ticket = new TicketImport() { Subject = "my printer is on fire", - Comments = new List { new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 1", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-2) }, new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 2", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-3) } }, + Comments = [new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 1", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-2) }, new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 2", Public = false, CreatedAt = DateTime.UtcNow.AddDays(-3) }], Priority = TicketPriorities.Urgent, CreatedAt = DateTime.Now.AddDays(-5), UpdatedAt = DateTime.Now.AddDays(-4), @@ -1214,14 +1155,14 @@ public void CanImportTicketAsync() var res = Api.Tickets.ImportTicketAsync(ticket); Assert.That(res.Result, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Result.Ticket.Id.Value, Is.GreaterThan(0)); Assert.That(res.Result.Ticket.CreatedAt.Value.LocalDateTime, Is.LessThan(DateTime.Now.AddDays(-4))); Assert.That(res.Result.Ticket.UpdatedAt.Value.LocalDateTime, Is.GreaterThan(res.Result.Ticket.CreatedAt.Value.LocalDateTime)); Assert.That(res.Result.Ticket.Status, Is.EqualTo(TicketStatus.Solved)); Assert.That(res.Result.Ticket.Description, Is.EqualTo("test description")); - }); + } var resComments = Api.Tickets.GetTicketComments(res.Result.Ticket.Id.Value); Assert.That(resComments, Is.Not.Null); Assert.That(resComments.Count, Is.EqualTo(3)); @@ -1261,7 +1202,7 @@ public void CanMergeTickets() var targetTicketId = tick.Ticket.Id.Value; var targetMergeComment = - $"Merged with ticket(s) {string.Join(", ", mergeIds.Select(m => $"#{m}").ToArray())}"; + $"Merged with ticket(s) {string.Join(", ", [.. mergeIds.Select(m => $"#{m}")])}"; var sourceMergeComment = $"Closing in favor of #{targetTicketId}"; var res = Api.Tickets.MergeTickets( @@ -1287,18 +1228,18 @@ public void CanMergeTickets() foreach (var id in mergeIds) { var oldTicket = Api.Tickets.GetTicket(id); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(oldTicket.Ticket.Id.Value, Is.EqualTo(id)); Assert.That(oldTicket.Ticket.Status, Is.EqualTo("closed")); - }); + } var oldComments = Api.Tickets.GetTicketComments(id); Assert.That(oldComments.Comments, Has.Count.EqualTo(2)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(oldComments.Comments[0].Body, Is.EqualTo(sourceDescription[counter])); Assert.That(oldComments.Comments[1].Body, Is.EqualTo(sourceMergeComment)); - }); + } Api.Tickets.DeleteAsync(id); counter++; } @@ -1308,11 +1249,11 @@ public void CanMergeTickets() var comments = Api.Tickets.GetTicketComments(targetTicketId); Assert.That(comments.Comments, Has.Count.EqualTo(2)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(comments.Comments[0].Body, Is.EqualTo(targetDescription)); Assert.That(comments.Comments[1].Body, Is.EqualTo(targetMergeComment)); - }); + } Api.Tickets.DeleteAsync(targetTicketId); } @@ -1348,7 +1289,7 @@ public async Task CanMergeTicketsAsync() var targetTicketId = tick.Ticket.Id.Value; var targetMergeComment = - $"Merged with ticket(s) {string.Join(", ", mergeIds.Select(m => $"#{m}").ToArray())}"; + $"Merged with ticket(s) {string.Join(", ", [.. mergeIds.Select(m => $"#{m}")])}"; var sourceMergeComment = $"Closing in favor of #{targetTicketId}"; var res = await Api.Tickets.MergeTicketsAsync( @@ -1372,18 +1313,18 @@ public async Task CanMergeTicketsAsync() foreach (var id in mergeIds) { var oldTicket = await Api.Tickets.GetTicketAsync(id); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(oldTicket.Ticket.Id.Value, Is.EqualTo(id)); Assert.That(oldTicket.Ticket.Status, Is.EqualTo("closed")); - }); + } var oldComments = await Api.Tickets.GetTicketCommentsAsync(id); Assert.That(oldComments.Comments, Has.Count.EqualTo(2)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(oldComments.Comments[0].Body, Is.EqualTo(sourceDescription[counter])); Assert.That(oldComments.Comments[1].Body, Is.EqualTo(sourceMergeComment)); - }); + } await Api.Tickets.DeleteAsync(id); counter++; } @@ -1393,11 +1334,11 @@ public async Task CanMergeTicketsAsync() var comments = await Api.Tickets.GetTicketCommentsAsync(targetTicketId); Assert.That(comments.Comments, Has.Count.EqualTo(2)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(comments.Comments[0].Body, Is.EqualTo(targetDescription)); Assert.That(comments.Comments[1].Body, Is.EqualTo(targetMergeComment)); - }); + } await Api.Tickets.DeleteAsync(targetTicketId); } @@ -1411,7 +1352,7 @@ public void CanBulkImportTicket() var ticket = new TicketImport() { Subject = "my printer is on fire", - Comments = new List { new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 1", CreatedAt = DateTime.UtcNow.AddDays(-2), Public = false }, new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 2", CreatedAt = DateTime.UtcNow.AddDays(-3), Public = false } }, + Comments = [new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 1", CreatedAt = DateTime.UtcNow.AddDays(-2), Public = false }, new TicketImportComment { AuthorId = Admin.ID, Value = "HELP comment created in Import 2", CreatedAt = DateTime.UtcNow.AddDays(-3), Public = false }], Priority = TicketPriorities.Urgent, CreatedAt = DateTime.Now.AddDays(-5), UpdatedAt = DateTime.Now.AddDays(-4), @@ -1431,7 +1372,7 @@ public void CanBulkImportTicket() Assert.That(res.JobStatus.Id, Is.EqualTo(job.JobStatus.Id)); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", StringComparison.CurrentCultureIgnoreCase) && count < 10) { Thread.Sleep(1000); job = Api.JobStatuses.GetJobStatus(res.JobStatus.Id); @@ -1449,11 +1390,11 @@ public void CanBulkImportTicket() Assert.That(resComments.Count, Is.EqualTo(3)); foreach (var c in resComments.Comments) { - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(c.CreatedAt.HasValue, Is.True); Assert.That(c.CreatedAt.Value.LocalDateTime, Is.LessThan(DateTime.Now.AddDays(-1))); - }); + } } Api.Tickets.DeleteAsync(r.Id); @@ -1491,14 +1432,14 @@ public async Task ViaChannel_Set_To_API_Issue_254() Subject = "my printer is on fire", Comment = new Comment() { Body = initCommentBody }, Priority = TicketPriorities.Urgent, - CustomFields = new List() - { + CustomFields = + [ new CustomField() { Id = Settings.CustomFieldId, Value = "testing" } - } + ] }; var resp = await Api.Tickets.CreateTicketAsync(ticket); @@ -1514,11 +1455,11 @@ public async Task ViaChannel_Set_To_API_Issue_254() var resp4 = await Api.Tickets.GetTicketCommentsAsync(newTicket.Id.Value, false); Assert.That(resp3.Comments.Any(c => c.Via?.Channel != "api"), Is.False); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(resp3.Comments[0].Body, Is.EqualTo(initCommentBody)); Assert.That(resp4.Comments[0].Body, Is.EqualTo(secondCommentBody)); - }); + } // clean up await Api.Tickets.DeleteAsync(newTicket.Id.Value); @@ -1533,8 +1474,8 @@ public async Task TicketField() Title = "My Tagger 2", Description = "test description", TitleInPortal = "Test Tagger", - CustomFieldOptions = new List - { + CustomFieldOptions = + [ new CustomFieldOptions { Name = "test entryA", @@ -1545,16 +1486,16 @@ public async Task TicketField() Name = "test entryB", Value = "test3" } - } + ] }; var res = await Api.Tickets.CreateTicketFieldAsync(tField); Assert.That(res.TicketField, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketField.Id, Is.Not.Null); Assert.That(res.TicketField.CustomFieldOptions, Has.Count.EqualTo(2)); - }); + } } [Test] @@ -1571,7 +1512,7 @@ public async Task CanCreateUpdateOptionsAndDeleteTaggerTicketFieldAsync() Title = "My Tagger 2", Description = "test description", TitleInPortal = "Test Tagger", - CustomFieldOptions = new List() + CustomFieldOptions = [] }; tField.CustomFieldOptions.Add(new CustomFieldOptions() @@ -1588,22 +1529,22 @@ public async Task CanCreateUpdateOptionsAndDeleteTaggerTicketFieldAsync() var res = await Api.Tickets.CreateTicketFieldAsync(tField); Assert.That(res.TicketField, Is.Not.Null); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketField.Id, Is.Not.Null); Assert.That(res.TicketField.CustomFieldOptions, Has.Count.EqualTo(2)); - }); - Assert.Multiple(() => + } + using (Assert.EnterMultipleScope()) { Assert.That(res.TicketField.CustomFieldOptions[0].Value, Is.EqualTo(option1)); Assert.That(res.TicketField.CustomFieldOptions[1].Value, Is.EqualTo(option2)); - }); + } var id = res.TicketField.Id.Value; var tFieldU = new TicketField() { Id = id, - CustomFieldOptions = new List() + CustomFieldOptions = [] }; //update CustomFieldOption A @@ -1623,13 +1564,13 @@ public async Task CanCreateUpdateOptionsAndDeleteTaggerTicketFieldAsync() var resU = await Api.Tickets.UpdateTicketFieldAsync(tFieldU); Assert.That(resU.TicketField.CustomFieldOptions, Has.Count.EqualTo(2)); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(resU.TicketField.CustomFieldOptions[0].Value, Is.EqualTo(option1_Update)); Assert.That(resU.TicketField.CustomFieldOptions[1].Value, Is.Not.EqualTo(option2)); Assert.That(await Api.Tickets.DeleteTicketFieldAsync(id), Is.True); - }); + } } [Test] @@ -1639,13 +1580,13 @@ public async Task CanGetBrandId() var brand = respBrand.Brands[0]; var ticket = new Ticket { Comment = new Comment { Body = "This is a Brand id Test", Public = false }, BrandId = brand.Id }; var respTicket = await Api.Tickets.CreateTicketAsync(ticket); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(respTicket.Ticket.BrandId, Is.EqualTo(brand.Id)); // clean up Assert.That(await Api.Tickets.DeleteAsync(respTicket.Ticket.Id.Value), Is.True); - }); + } } [Test] @@ -1663,13 +1604,13 @@ public async Task CanGetIsPublicAsync() ticket.Comment.Public = false; var resp2 = await Api.Tickets.CreateTicketAsync(ticket); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(resp2.Ticket.IsPublic, Is.False); Assert.That(await Api.Tickets.DeleteAsync(resp1.Ticket.Id.Value), Is.True); Assert.That(await Api.Tickets.DeleteAsync(resp2.Ticket.Id.Value), Is.True); - }); + } } [Test] @@ -1702,13 +1643,13 @@ public async Task CanSetFollowupID() }; var resp3 = await Api.Tickets.CreateTicketAsync(ticket_Followup); - Assert.Multiple(async () => + using (Assert.EnterMultipleScope()) { Assert.That(resp3.Ticket.Via.Source.Rel, Is.EqualTo("follow_up")); Assert.That(await Api.Tickets.DeleteAsync(resp3.Ticket.Id.Value), Is.True); Assert.That(await Api.Tickets.DeleteAsync(closedTicket.Id.Value), Is.True); - }); + } } [Test] @@ -1728,7 +1669,7 @@ public void CanCreateManyTickets() Assert.That(job.JobStatus.Id, Is.EqualTo(res.JobStatus.Id)); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", StringComparison.CurrentCultureIgnoreCase) && count < 10) { Thread.Sleep(1000); job = Api.JobStatuses.GetJobStatus(res.JobStatus.Id); @@ -1762,7 +1703,7 @@ public async Task CanCreateManyTicketsAsync() Assert.That(job.JobStatus.Id, Is.EqualTo(res.JobStatus.Id)); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", StringComparison.CurrentCultureIgnoreCase) && count < 10) { await Task.Delay(1000); job = await Api.JobStatuses.GetJobStatusAsync(res.JobStatus.Id); @@ -1792,7 +1733,7 @@ public async Task CanGetIncrementalTicketExportNextPageAsync() { var baseRes = await Api.Tickets.GetIncrementalTicketExportAsync(DateTime.MinValue); - Assert.That(baseRes.NextPage, Is.Not.Null.Or.Empty); + Assert.That(baseRes.NextPage, Is.Not.Null.And.Not.Empty); var res = await Api.Tickets.GetIncrementalTicketExportNextPageAsync(baseRes.NextPage); @@ -1813,12 +1754,12 @@ public async Task CanPermanentlyDeleteTicketAsync() var deleteRes = await Api.Tickets.DeleteAsync(res.Ticket.Id.Value); var deleteAsyncRes = await Api.Tickets.DeleteTicketPermanentlyAsync(res.Ticket.Id.Value); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res, Is.Not.Null); Assert.That(res.Ticket, Is.Not.Null); Assert.That(deleteRes, Is.True); Assert.That(deleteAsyncRes, Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/TriggerTests.cs b/tests/ZendeskApi_v2.Tests/TriggerTests.cs index c9f6a27e..aa1edc41 100644 --- a/tests/ZendeskApi_v2.Tests/TriggerTests.cs +++ b/tests/ZendeskApi_v2.Tests/TriggerTests.cs @@ -39,8 +39,8 @@ public void CanCreateUpdateAndDeleteTriggers() { Title = "Test Trigger", Active = true, - Conditions = new Conditions() { All = new List(), Any = new List() }, - Actions = new List(), + Conditions = new Conditions() { All = [], Any = [] }, + Actions = [], Position = 9999 }; @@ -53,12 +53,12 @@ public void CanCreateUpdateAndDeleteTriggers() res.Trigger.Title = "Test Trigger Updated"; var update = Api.Triggers.UpdateTrigger(res.Trigger); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Trigger.Title, Is.EqualTo(update.Trigger.Title)); Assert.That(Api.Triggers.DeleteTrigger(res.Trigger.Id.Value), Is.True); - }); + } } [Test] @@ -71,8 +71,8 @@ public void CanReorderTriggers() { Title = "Test Trigger1", Active = true, - Conditions = new Conditions() { All = new List() { new All() { Field = "status", Operator = "is", Value = "open" } }, Any = new List() }, - Actions = new List() { new Action() { Field = "group_id", Value = "20402842" } }, + Conditions = new Conditions() { All = [new All() { Field = "status", Operator = "is", Value = "open" }], Any = [] }, + Actions = [new Action() { Field = "group_id", Value = "20402842" }], Position = 5000 }; @@ -80,8 +80,8 @@ public void CanReorderTriggers() { Title = "Test Trigger2", Active = true, - Conditions = new Conditions() { All = new List() { new All() { Field = "status", Operator = "is", Value = "open" } }, Any = new List() }, - Actions = new List() { new Action() { Field = "group_id", Value = "20402842" } }, + Conditions = new Conditions() { All = [new All() { Field = "status", Operator = "is", Value = "open" }], Any = [] }, + Actions = [new Action() { Field = "group_id", Value = "20402842" }], Position = 6000 }; @@ -93,12 +93,12 @@ public void CanReorderTriggers() Assert.That(Api.Triggers.ReorderTriggers(ids), Is.True); res = Api.Triggers.GetActiveTriggers().Triggers; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res3.Trigger.Id.Value, Is.EqualTo(res[0].Id.Value)); Assert.That(Api.Triggers.DeleteTrigger(res2.Trigger.Id.Value), Is.True); Assert.That(Api.Triggers.DeleteTrigger(res3.Trigger.Id.Value), Is.True); - }); + } } } diff --git a/tests/ZendeskApi_v2.Tests/UserTests.cs b/tests/ZendeskApi_v2.Tests/UserTests.cs index 7d6cac98..62af0239 100644 --- a/tests/ZendeskApi_v2.Tests/UserTests.cs +++ b/tests/ZendeskApi_v2.Tests/UserTests.cs @@ -116,11 +116,11 @@ public void CanGetUsersInOrgPaginated() } var res = Api.Users.GetUsersInOrganization(Organization.ID, 3, 0); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Users, Has.Count.EqualTo(3)); Assert.That(res.NextPage, Is.Not.Null); - }); + } users.ForEach(u => Api.Users.DeleteUser(u.Id.Value)); } @@ -147,13 +147,13 @@ public void CanCreateUpdateSuspendAndDeleteUser() var res1 = Api.Users.CreateUser(user); var userId = res1.User.Id ?? 0; - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.User.Id, Is.GreaterThan(0)); Assert.That(Api.Users.SetUsersPassword(userId, "t34sssting"), Is.True); Assert.That(Api.Users.ChangeUsersPassword(userId, "t34sssting", "newpassw33rd"), Is.True); - }); + } res1.User.Phone = "555-555-5555"; res1.User.RemotePhotoUrl = "http://i.imgur.com/b2gxj.jpg"; @@ -246,11 +246,11 @@ public void CanCreateOrUpdateUser_UpdateUser() var res2 = Api.Users.CreateOrUpdateUser(user); var user72group = Api.Users.SearchByEmail("test772@tester.com"); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(user72group.Count, Is.EqualTo(1)); Assert.That(res2.User.Name, Does.Contain("721")); - }); + } } [Test] @@ -333,11 +333,11 @@ public async Task CanCreateOrUpdateUserAsync_UpdateUser() var res2 = Api.Users.CreateOrUpdateUser(user); var user72group = Api.Users.SearchByEmail("test772@tester.com"); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(user72group.Count, Is.EqualTo(1)); Assert.That(res2.User.Name, Does.Contain("721")); - }); + } } [Test] @@ -353,11 +353,11 @@ public void CanFindUserByPhone() { var res1 = Api.Users.SearchByPhone(Settings.Phone); Assert.That(res1.Users, Is.Not.Empty); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Users.First().Phone, Is.EqualTo(Settings.Phone)); Assert.That(res1.Users.First().Name, Is.EqualTo("0897c9c1f80646118a8194c942aa84cf 162a3d865f194ef8b7a2ad3525ea6d7c")); - }); + } } [Test] @@ -365,11 +365,11 @@ public void CanFindUserByFormattedPhone() { var res1 = Api.Users.SearchByPhone(Settings.FormattedPhone); Assert.That(res1.Users, Is.Not.Empty); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Users.First().Phone, Is.EqualTo(Settings.FormattedPhone)); Assert.That(res1.Users.First().Name, Is.EqualTo("dc4d7cf57d0c435cbbb91b1d4be952fe 504b509b0b1e48dda2c8471a88f068a5")); - }); + } } [Test] @@ -377,11 +377,11 @@ public void CanFindUserByPhoneAsync() { var res1 = Api.Users.SearchByPhoneAsync(Settings.Phone).Result; Assert.That(res1.Users, Is.Not.Empty); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res1.Users.First().Phone, Is.EqualTo(Settings.Phone)); Assert.That(res1.Users.First().Name, Is.EqualTo("0897c9c1f80646118a8194c942aa84cf 162a3d865f194ef8b7a2ad3525ea6d7c")); - }); + } } [Test] @@ -448,11 +448,11 @@ public void CanCreateUpdateAndDeleteIdentities() var primaries = Api.Users.SetUserIdentityAsPrimary(userId, identityId); Assert.That(primaries.Identities.First(x => x.Primary).Id, Is.EqualTo(identityId)); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(Api.Users.DeleteUserIdentity(userId, identityId), Is.True); Assert.That(Api.Users.DeleteUser(userId), Is.True); - }); + } } [Test] @@ -460,11 +460,11 @@ public void CanGetMultipleUsers() { var userList = Api.Users.GetAllUsers(10, 1).Users.Select(u => u.Id.Value).ToList(); var result = Api.Users.GetMultipleUsers(userList, UserSideLoadOptions.Organizations | UserSideLoadOptions.Identities | UserSideLoadOptions.Roles); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(result.Count, Is.EqualTo(userList.Count)); Assert.That((result.Organizations != null && result.Organizations.Any()) || (result.Identities != null && result.Identities.Any()), Is.True); - }); + } } [Test] @@ -472,11 +472,11 @@ public void CanGetMultipleUsersAsync() { var userList = Api.Users.GetAllUsersAsync(10, 1).Result.Users.Select(u => u.Id.Value).ToList(); var result = Api.Users.GetMultipleUsers(userList, UserSideLoadOptions.Organizations | UserSideLoadOptions.Identities); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(result.Count, Is.EqualTo(userList.Count)); Assert.That((result.Organizations != null && result.Organizations.Any()) || (result.Identities != null && result.Identities.Any()), Is.True); - }); + } } [Test] @@ -492,11 +492,11 @@ public void CanSetUserPhoto() }; var user = Api.Users.SetUserPhoto(Admin.ID, file); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(user.User.Photo.ContentUrl, Is.Not.Null); Assert.That(user.User.Photo.Size, Is.Not.Zero); - }); + } } [Test] @@ -511,11 +511,11 @@ public async Task CanSetUserPhotoAsync() }; var user = await Api.Users.SetUserPhotoAsync(Admin.ID, file); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(user.User.Photo.ContentUrl, Is.Not.Null); Assert.That(user.User.Photo.Size, Is.Not.Zero); - }); + } } [Test] @@ -577,14 +577,14 @@ public async Task CanCreateUpdateAndDeleteIdentitiesAsync() await Api.Users.UpdateUserIdentityAsync(userId, res2.Identity); var res3 = await Api.Users.GetSpecificUserIdentityAsync(userId, identityId); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res3.Identity.Id, Is.EqualTo(identityId)); Assert.That(res3.Identity.Value, Is.EqualTo(res2.Identity.Value)); Assert.That(Api.Users.DeleteUserIdentity(userId, identityId), Is.True); Assert.That(Api.Users.DeleteUser(userId), Is.True); - }); + } } [Test] @@ -612,18 +612,18 @@ public async Task CanBulkDeleteUsersAsync() var count = 0; - while (jobResponse.JobStatus.Status.ToLower() != JobStatusCompleted && count < MaxRetryAttempts) + while (!jobResponse.JobStatus.Status.Equals(JobStatusCompleted, StringComparison.CurrentCultureIgnoreCase) && count < MaxRetryAttempts) { await Task.Delay(1000); jobResponse = Api.JobStatuses.GetJobStatus(jobResponse.JobStatus.Id); count++; } - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(jobResponse.JobStatus.Status.ToLower(), Is.EqualTo(JobStatusCompleted)); Assert.That(jobResponse.JobStatus.Total, Is.EqualTo(users.Count)); - }); + } } [Test] @@ -651,39 +651,39 @@ public void CanBulkDeleteUsers() var count = 0; - while (jobResponse.JobStatus.Status.ToLower() != JobStatusCompleted && count < MaxRetryAttempts) + while (!jobResponse.JobStatus.Status.Equals(JobStatusCompleted, StringComparison.CurrentCultureIgnoreCase) && count < MaxRetryAttempts) { Thread.Sleep(1000); jobResponse = Api.JobStatuses.GetJobStatus(jobResponse.JobStatus.Id); count++; } - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(jobResponse.JobStatus.Status.ToLower(), Is.EqualTo(JobStatusCompleted)); Assert.That(jobResponse.JobStatus.Total, Is.EqualTo(users.Count)); - }); + } } [Test] public void CanGetIncrementalUserExport() { var incrementalUserExport = Api.Users.GetIncrementalUserExport(Settings.Epoch); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(incrementalUserExport.Users, Is.Not.Empty); Assert.That(incrementalUserExport.Organizations, Is.Null); Assert.That(incrementalUserExport.Identities, Is.Null); Assert.That(incrementalUserExport.Groups, Is.Null); - }); + } var incrementalUserExportNextPage = Api.Users.GetIncrementalUserExportNextPage(incrementalUserExport.NextPage); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(incrementalUserExportNextPage.Users, Is.Not.Empty); Assert.That(incrementalUserExportNextPage.Organizations, Is.Null); Assert.That(incrementalUserExportNextPage.Identities, Is.Null); Assert.That(incrementalUserExportNextPage.Groups, Is.Null); - }); + } } //[Test] @@ -708,42 +708,42 @@ public void CanGetIncrementalUserExport() public async Task CanGetIncrementalUserExportAsync() { var incrementalUserExport = await Api.Users.GetIncrementalUserExportAsync(Settings.Epoch); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(incrementalUserExport.Users, Is.Not.Empty); Assert.That(incrementalUserExport.Organizations, Is.Null); Assert.That(incrementalUserExport.Identities, Is.Null); Assert.That(incrementalUserExport.Groups, Is.Null); - }); + } var incrementalUserExportNextPage = await Api.Users.GetIncrementalUserExportNextPageAsync(incrementalUserExport.NextPage); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(incrementalUserExportNextPage.Users, Is.Not.Empty); Assert.That(incrementalUserExportNextPage.Organizations, Is.Null); Assert.That(incrementalUserExportNextPage.Identities, Is.Null); Assert.That(incrementalUserExportNextPage.Groups, Is.Null); - }); + } } [Test] public async Task CanGetIncrementalUserExportAsyncWithSideLoadOptions() { var incrementalUserExport = await Api.Users.GetIncrementalUserExportAsync(Settings.Epoch, UserSideLoadOptions.Organizations | UserSideLoadOptions.Groups | UserSideLoadOptions.Identities); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(incrementalUserExport.Users, Is.Not.Empty); Assert.That(incrementalUserExport.Organizations, Is.Not.Null); Assert.That(incrementalUserExport.Identities, Is.Not.Null); Assert.That(incrementalUserExport.Groups, Is.Not.Null); - }); + } var incrementalUserExportNextPage = await Api.Users.GetIncrementalUserExportNextPageAsync(incrementalUserExport.NextPage); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(incrementalUserExportNextPage.Users, Is.Not.Empty); Assert.That(incrementalUserExportNextPage.Organizations, Is.Not.Null); Assert.That(incrementalUserExportNextPage.Identities, Is.Not.Null); Assert.That(incrementalUserExportNextPage.Groups, Is.Not.Null); - }); + } } [Test] @@ -793,7 +793,7 @@ public async Task CanBatchUpdateUsers() var job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", StringComparison.CurrentCultureIgnoreCase) && count < 10) { await Task.Delay(1000); job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); @@ -841,7 +841,7 @@ public async Task CanBulkUpdateUsers() var job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", StringComparison.CurrentCultureIgnoreCase) && count < 10) { await Task.Delay(1000); job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); @@ -878,7 +878,7 @@ public async Task CanBulkCreateUpdateUsersAsync() var updateResp = await Api.Users.BulkCreateUpdateUsersAsync(users); var job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); var count = 0; - while (job.JobStatus.Status.ToLower() != "completed" && count < 10) + while (!job.JobStatus.Status.Equals("completed", StringComparison.CurrentCultureIgnoreCase) && count < 10) { await Task.Delay(1000); job = await Api.JobStatuses.GetJobStatusAsync(updateResp.JobStatus.Id); diff --git a/tests/ZendeskApi_v2.Tests/ViewTests.cs b/tests/ZendeskApi_v2.Tests/ViewTests.cs index 26a0b767..15475f30 100644 --- a/tests/ZendeskApi_v2.Tests/ViewTests.cs +++ b/tests/ZendeskApi_v2.Tests/ViewTests.cs @@ -1,5 +1,4 @@ using NUnit.Framework; -using System.Collections.Generic; using System.Linq; using ZendeskApi_v2.Extensions; using ZendeskApi_v2.Models.Views; @@ -46,11 +45,11 @@ public void CanExecuteViews() { Api.Views.GetAllViews(); var res = Api.Views.ExecuteView(31559032); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(res.Rows, Is.Not.Empty); Assert.That(res.Columns, Is.Not.Empty); - }); + } } [Test] @@ -77,30 +76,30 @@ public void CanPreviewViews() { View = new PreviewView() { - All = new List { new All { Field = "status", Value = "open", Operator = "is" } }, - Output = new PreviewViewOutput { Columns = new List { "subject" } } + All = [new All { Field = "status", Value = "open", Operator = "is" }], + Output = new PreviewViewOutput { Columns = ["subject"] } } }; var previewRes = Api.Views.PreviewView(preview); - Assert.Multiple(() => + using (Assert.EnterMultipleScope()) { Assert.That(previewRes.Rows, Is.Not.Empty); Assert.That(previewRes.Columns, Is.Not.Empty); - }); + } } [Test] public void CanGetViewCounts() { var views = Api.Views.GetAllViews(); - var res = Api.Views.GetViewCounts(new List() { views.Views[0].Id }); - Assert.Multiple(() => + var res = Api.Views.GetViewCounts([views.Views[0].Id]); + using (Assert.EnterMultipleScope()) { Assert.That(res.ViewCounts, Is.Not.Empty); Assert.That(views.Count, Is.GreaterThan(0)); - }); + } } [Test] diff --git a/tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj b/tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj index fb2cd0c7..0ad17a79 100644 --- a/tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj +++ b/tests/ZendeskApi_v2.Tests/ZendeskApi_v2.Tests.csproj @@ -1,7 +1,7 @@  - net6.0 + net8.0 false latest 411e2606-2274-427d-ad1e-89c0d4bc9f5a @@ -9,20 +9,18 @@ - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + + + + + + + - - - +