Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59f9bf290d | ||
|
|
b6b8f54c65 | ||
|
|
50139ee506 | ||
|
|
62947b2862 | ||
|
|
1748a08f7b | ||
|
|
3264d58f13 | ||
|
|
b6be468b3a | ||
|
|
3ec88aab65 | ||
|
|
da43086017 | ||
|
|
d62fe5e315 | ||
|
|
852192a5d2 | ||
|
|
f4498c3d05 | ||
|
|
b045b33049 | ||
|
|
32a4fbebd5 | ||
|
|
cc2f1df78e | ||
|
|
9b2fd1253b | ||
|
|
024697f3bf | ||
|
|
d8b76575ca | ||
|
|
5b00312158 | ||
|
|
d920e93d1e | ||
|
|
feba51a49d | ||
|
|
853c1acf7e | ||
|
|
3f10bd8c21 | ||
|
|
b13eb8aaf8 | ||
|
|
275478066e | ||
|
|
b01def0872 | ||
|
|
b106305167 | ||
|
|
103631de15 |
+101
-254
@@ -313,8 +313,8 @@ stages:
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
||||
LinuxPart3Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
macOSPart1Of3:
|
||||
vmImage: "macOS-latest"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
||||
@@ -325,8 +325,8 @@ stages:
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
||||
macOSPart3Of3:
|
||||
vmImage: "macOS-latest"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure namespace.
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
variables:
|
||||
@@ -389,8 +389,8 @@ stages:
|
||||
vmImage: "windows-latest"
|
||||
Tests__Database__DatabaseType: LocalDb
|
||||
Tests__Database__SQLServerMasterConnectionString: N/A
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
LinuxPart1Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: UmbracoIntegration123!
|
||||
@@ -410,8 +410,8 @@ stages:
|
||||
SA_PASSWORD: UmbracoIntegration123!
|
||||
Tests__Database__DatabaseType: SqlServer
|
||||
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure)"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
@@ -432,6 +432,33 @@ stages:
|
||||
displayName: Start SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- powershell: |
|
||||
$maxAttempts = 12
|
||||
$attempt = 0
|
||||
$status = ""
|
||||
|
||||
while (($status -ne 'running') -and ($attempt -lt $maxAttempts)) {
|
||||
Start-Sleep -Seconds 5
|
||||
# We use the docker inspect command to check the status of the container. If the container is not running, we wait 5 seconds and try again. And if reaches 12 attempts, we fail the build.
|
||||
$status = docker inspect -f '{{.State.Status}}' mssql
|
||||
|
||||
if ($status -ne 'running') {
|
||||
Write-Host "Waiting for SQL Server to be ready... Attempt $($attempt + 1)"
|
||||
$attempt++
|
||||
}
|
||||
}
|
||||
|
||||
if ($status -eq 'running') {
|
||||
Write-Host "SQL Server container is running"
|
||||
docker ps -a
|
||||
} else {
|
||||
Write-Host "SQL Server did not become ready in time. Last known status: $status"
|
||||
docker logs mssql
|
||||
exit 1
|
||||
}
|
||||
displayName: Wait for SQL Server to be ready (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||
displayName: Start SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
@@ -495,151 +522,70 @@ stages:
|
||||
# Connection string
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=Umbraco;Mode=Memory;Cache=Shared;Foreign Keys=True;Pooling=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.Sqlite
|
||||
DatabaseType: SQLite
|
||||
strategy:
|
||||
matrix:
|
||||
LinuxPart1Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTestSqlite -- --shard=1/3"
|
||||
LinuxPart2Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTestSqlite -- --shard=2/3"
|
||||
LinuxPart3Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTestSqlite -- --shard=3/3"
|
||||
WindowsPart1Of3:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTestSqlite -- --shard=1/3"
|
||||
WindowsPart2Of3:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTestSqlite -- --shard=2/3"
|
||||
WindowsPart3Of3:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTestSqlite -- --shard=3/3"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
# Setup test environment
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download NuGet artifacts
|
||||
inputs:
|
||||
artifact: nupkg
|
||||
path: $(Agent.BuildDirectory)/app/nupkg
|
||||
|
||||
- task: NodeTool@0
|
||||
displayName: Use Node.js $(nodeVersion)
|
||||
retryCountOnTaskFailure: 3
|
||||
inputs:
|
||||
versionSpec: $(nodeVersion)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
# Setup test environment Template
|
||||
- template: nightly-E2E-setup-template.yml
|
||||
parameters:
|
||||
nodeVersion: ${{ variables.nodeVersion }}
|
||||
PlaywrightUserEmail: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL }}
|
||||
PlaywrightPassword: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD }}
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
npm_config_cache: ${{ variables.npm_config_cache }}
|
||||
|
||||
- pwsh: |
|
||||
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
|
||||
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
URL=$(ASPNETCORE_URLS)
|
||||
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json" | Out-File .env
|
||||
displayName: Generate .env
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Cache and restore NPM packages
|
||||
- task: Cache@2
|
||||
displayName: Cache NPM packages
|
||||
inputs:
|
||||
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||
restoreKeys: |
|
||||
npm_e2e | "$(Agent.OS)"
|
||||
npm_e2e
|
||||
path: $(npm_config_cache)
|
||||
|
||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
displayName: Restore NPM packages
|
||||
|
||||
# Build application
|
||||
- pwsh: |
|
||||
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||
dotnet new nugetconfig
|
||||
dotnet nuget add source ./nupkg --name Local
|
||||
dotnet new install Umbraco.Templates::$cmsVersion
|
||||
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||
dotnet restore UmbracoProject
|
||||
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
|
||||
displayName: Restore project
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
- pwsh: |
|
||||
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
||||
dotnet dev-certs https
|
||||
displayName: Build application
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
condition: succeeded()
|
||||
|
||||
# Run application
|
||||
- bash: |
|
||||
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||
displayName: Run application (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
# Run application Template
|
||||
- template: nightly-E2E-run-application-template.yml
|
||||
parameters:
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
buildConfiguration: ${{ variables.buildConfiguration }}
|
||||
|
||||
- pwsh: |
|
||||
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||
displayName: Run application (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Wait for application to start responding to requests
|
||||
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
||||
displayName: Wait for application
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Install Playwright and dependencies
|
||||
- pwsh: npx playwright install chromium
|
||||
displayName: Install Playwright only with Chromium browser
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Test
|
||||
- pwsh: $(testCommand)
|
||||
displayName: Run Playwright tests
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
env:
|
||||
CI: true
|
||||
CommitId: $(Build.SourceVersion)
|
||||
AgentOs: $(Agent.OS)
|
||||
|
||||
# Stop application
|
||||
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Linux)
|
||||
condition: and(ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Windows)
|
||||
condition: and(ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Copy artifacts
|
||||
- pwsh: |
|
||||
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results/* $(Build.ArtifactStagingDirectory) -Recurse
|
||||
}
|
||||
displayName: Copy Playwright results
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Publish test artifacts
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish test artifacts
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
|
||||
|
||||
# Publish test results
|
||||
- task: PublishTestResults@2
|
||||
displayName: "Publish test results"
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
testResultsFormat: 'JUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
# Run tests Template
|
||||
- template: nightly-E2E-run-tests-template.yml
|
||||
parameters:
|
||||
testCommand: $(testCommand)
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
- job:
|
||||
displayName: E2E Tests (SQL Server)
|
||||
@@ -647,175 +593,76 @@ stages:
|
||||
# Connection string
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
DatabaseType: SQLServer
|
||||
strategy:
|
||||
matrix:
|
||||
${{ if eq(parameters.sqlServerLinuxAcceptanceTests, True) }}:
|
||||
LinuxPart1Of3:
|
||||
testCommand: "npm run smokeTest -- --shard=1/3"
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
testFolder: "DefaultConfig"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
LinuxPart2Of3:
|
||||
testCommand: "npm run smokeTest -- --shard=2/3"
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
testFolder: "DefaultConfig"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
LinuxPart3Of3:
|
||||
testCommand: "npm run smokeTest -- --shard=3/3"
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
testFolder: "DefaultConfig"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
WindowsPart1Of3:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTest -- --shard=1/3"
|
||||
WindowsPart2Of3:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTest -- --shard=2/3"
|
||||
WindowsPart3Of3:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run smokeTest -- --shard=3/3"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
# Setup test environment
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download NuGet artifacts
|
||||
inputs:
|
||||
artifact: nupkg
|
||||
path: $(Agent.BuildDirectory)/app/nupkg
|
||||
|
||||
- task: NodeTool@0
|
||||
displayName: Use Node.js $(nodeVersion)
|
||||
inputs:
|
||||
versionSpec: $(nodeVersion)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
# Setup test environment Template
|
||||
- template: nightly-E2E-setup-template.yml
|
||||
parameters:
|
||||
nodeVersion: ${{ variables.nodeVersion }}
|
||||
PlaywrightUserEmail: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL }}
|
||||
PlaywrightPassword: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD }}
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
npm_config_cache: ${{ variables.npm_config_cache }}
|
||||
|
||||
- pwsh: |
|
||||
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
|
||||
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
URL=$(ASPNETCORE_URLS)
|
||||
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json" | Out-File .env
|
||||
displayName: Generate .env
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Cache and restore NPM packages
|
||||
- task: Cache@2
|
||||
displayName: Cache NPM packages
|
||||
inputs:
|
||||
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||
restoreKeys: |
|
||||
npm_e2e | "$(Agent.OS)"
|
||||
npm_e2e
|
||||
path: $(npm_config_cache)
|
||||
|
||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
displayName: Restore NPM packages
|
||||
|
||||
# Build application
|
||||
- pwsh: |
|
||||
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||
dotnet new nugetconfig
|
||||
dotnet nuget add source ./nupkg --name Local
|
||||
dotnet new install Umbraco.Templates::$cmsVersion
|
||||
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||
dotnet restore UmbracoProject
|
||||
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
|
||||
displayName: Restore project
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
- pwsh: |
|
||||
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
||||
dotnet dev-certs https
|
||||
displayName: Build application
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
condition: succeeded()
|
||||
|
||||
# Start SQL Server
|
||||
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$(SA_PASSWORD)" mcr.microsoft.com/mssql/server:2022-latest
|
||||
displayName: Start SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
# Run application Template
|
||||
- template: nightly-E2E-run-application-template.yml
|
||||
parameters:
|
||||
SA_PASSWORD: ${{ variables.SA_PASSWORD }}
|
||||
buildConfiguration: ${{ variables.buildConfiguration }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||
displayName: Start SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Run application
|
||||
- bash: |
|
||||
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||
displayName: Run application (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
- pwsh: |
|
||||
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||
displayName: Run application (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Wait for application to start responding to requests
|
||||
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
||||
displayName: Wait for application
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Install Playwright and dependencies
|
||||
- pwsh: npx playwright install chromium
|
||||
displayName: Install Playwright only with Chromium browser
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Test
|
||||
- pwsh: $(testCommand)
|
||||
displayName: Run Playwright tests
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
env:
|
||||
CI: true
|
||||
CommitId: $(Build.SourceVersion)
|
||||
AgentOs: $(Agent.OS)
|
||||
|
||||
# Stop application
|
||||
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Linux)
|
||||
condition: and(ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Windows)
|
||||
condition: and(ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Stop SQL Server
|
||||
- pwsh: docker stop mssql
|
||||
displayName: Stop SQL Server Docker image (Linux)
|
||||
condition: eq(variables['Agent.OS'], 'Linux')
|
||||
|
||||
- pwsh: SqlLocalDB stop MSSQLLocalDB
|
||||
displayName: Stop SQL Server LocalDB (Windows)
|
||||
condition: eq(variables['Agent.OS'], 'Windows_NT')
|
||||
|
||||
# Copy artifacts
|
||||
- pwsh: |
|
||||
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results/* $(Build.ArtifactStagingDirectory) -Recurse
|
||||
}
|
||||
displayName: Copy Playwright results
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Publish test artifacts
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish test artifacts
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
|
||||
|
||||
# Publish test results
|
||||
- task: PublishTestResults@2
|
||||
displayName: "Publish test results"
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
testResultsFormat: 'JUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
# Run tests Template
|
||||
- template: nightly-E2E-run-tests-template.yml
|
||||
parameters:
|
||||
testCommand: $(testCommand)
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
###############################################
|
||||
## Release
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
parameters:
|
||||
- name: testFolder
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: additionalEnvironmentVariables
|
||||
type: boolean
|
||||
default: False
|
||||
|
||||
steps:
|
||||
- pwsh: |
|
||||
dotnet restore UmbracoProject
|
||||
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||
displayName: Restore project
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Update application to use necessary app settings
|
||||
- pwsh: |
|
||||
$sourcePath = "$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/tests/${{ parameters.testFolder }}/AdditionalSetup"
|
||||
$destinationPath = "UmbracoProject"
|
||||
$jsonFiles = Get-ChildItem -Path $sourcePath -Filter "*.json"
|
||||
if ($jsonFiles) {
|
||||
$jsonFiles | ForEach-Object {
|
||||
Write-Host "Copying: $($_.FullName)"
|
||||
Copy-Item -Path $_.FullName -Destination $destinationPath -Force
|
||||
}
|
||||
} else {
|
||||
Write-Host "No JSON files found."
|
||||
}
|
||||
displayName: Update application to use necessary app settings
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Update application to use necessary App_Plugins
|
||||
- pwsh: |
|
||||
$sourcePath = "$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/tests/${{ parameters.testFolder }}/AdditionalSetup"
|
||||
$destinationPath = "UmbracoProject"
|
||||
$appPluginsFolders = Get-ChildItem -Path $sourcePath -Directory -Filter "App_Plugins"
|
||||
if ($appPluginsFolders) {
|
||||
foreach ($folder in $appPluginsFolders) {
|
||||
Write-Host "Copying folder: $($folder.FullName)"
|
||||
Copy-Item -Path $folder.FullName -Destination $destinationPath -Recurse -Force
|
||||
}
|
||||
} else {
|
||||
Write-Host "No App_Plugins found."
|
||||
}
|
||||
displayName: Update application to use necessary app plugins
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Update application to use necessary classes
|
||||
- pwsh: |
|
||||
$sourcePath = "$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/tests/${{ parameters.testFolder }}/AdditionalSetup"
|
||||
$destinationPath = "UmbracoProject"
|
||||
$csharpFiles = Get-ChildItem -Path $sourcePath -Filter "*.cs"
|
||||
if ($csharpFiles) {
|
||||
$csharpFiles | ForEach-Object {
|
||||
Write-Host "Copying: $($_.FullName)"
|
||||
Copy-Item -Path $_.FullName -Destination $destinationPath -Force
|
||||
}
|
||||
} else {
|
||||
Write-Host "No C# files found."
|
||||
}
|
||||
displayName: Update application to use necessary classes
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
- ${{ if eq(parameters.additionalEnvironmentVariables, False) }}:
|
||||
- pwsh: |
|
||||
dotnet build UmbracoProject --configuration ${{ parameters.buildConfiguration }} --no-restore
|
||||
dotnet dev-certs https
|
||||
displayName: Build application
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
condition: succeeded()
|
||||
@@ -0,0 +1,47 @@
|
||||
parameters:
|
||||
- name: SA_PASSWORD
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: buildConfiguration
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: additionalEnvironmentVariables
|
||||
type: boolean
|
||||
default: False
|
||||
|
||||
- name: DatabaseType
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
steps:
|
||||
# Skips the SQLServer setup if the databaseType does not match
|
||||
- ${{ if eq(parameters.DatabaseType, 'SQLServer') }}:
|
||||
# Start SQL Server Linux
|
||||
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=${{ parameters.SA_PASSWORD }}" mcr.microsoft.com/mssql/server:2022-latest
|
||||
displayName: Start SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
# Start SQL Server LocalDB Windows
|
||||
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||
displayName: Start SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# If we want to add additional environment variables to the run step, then we will skip these
|
||||
- ${{ if eq(parameters.additionalEnvironmentVariables, False) }}:
|
||||
# Run application for Linux
|
||||
- bash: |
|
||||
nohup dotnet run --project UmbracoProject --configuration ${{ parameters.buildConfiguration }} --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||
displayName: Run application (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Run application for Windows
|
||||
- pwsh: |
|
||||
$process = Start-Process dotnet "run --project UmbracoProject --configuration ${{ parameters.buildConfiguration }} --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||
displayName: Run application (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
@@ -0,0 +1,105 @@
|
||||
parameters:
|
||||
- name: ASPNETCORE_URLS
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: testCommand
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: port
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: AZUREB2CTESTUSEREMAIL
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: AZUREB2CTESTUSERPASSWORD
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: DatabaseType
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
steps:
|
||||
# Ensures we have the package wait-on installed
|
||||
- pwsh: npm install wait-on
|
||||
displayName: Install wait-on package
|
||||
|
||||
# Wait for either the port of the aspnetcore url
|
||||
- pwsh: |
|
||||
$Port = "${{ parameters.port }}"
|
||||
$Url = "${{ parameters.ASPNETCORE_URLS }}"
|
||||
|
||||
if ($Port -ne "") {
|
||||
Write-Host "Waiting on TCP port $Port"
|
||||
npx wait-on -v --interval 1000 --timeout 120000 "tcp:$Port"
|
||||
} else {
|
||||
Write-Host "Waiting on URL $Url"
|
||||
npx wait-on -v --interval 1000 --timeout 120000 "$Url"
|
||||
}
|
||||
displayName: Wait for application
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Install Playwright and dependencies
|
||||
- pwsh: npx playwright install chromium
|
||||
displayName: Install Playwright only with Chromium browser
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Test
|
||||
- pwsh: ${{ parameters.testCommand }}
|
||||
displayName: Run Playwright tests
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
env:
|
||||
CI: true
|
||||
CommitId: $(Build.SourceVersion)
|
||||
AgentOs: $(Agent.OS)
|
||||
AZUREADB2CTESTUSEREMAIL: ${{ parameters.AZUREB2CTESTUSEREMAIL }}
|
||||
AZUREADB2CTESTUSERPASSWORD: ${{ parameters.AZUREB2CTESTUSERPASSWORD }}
|
||||
|
||||
# Stop application
|
||||
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Linux)
|
||||
condition: and(succeededOrFailed(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Windows)
|
||||
condition: and(succeededOrFailed(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
- ${{ if eq(parameters.DatabaseType, 'SQLServer') }}:
|
||||
# Stop SQL Server
|
||||
- pwsh: docker stop mssql
|
||||
displayName: Stop SQL Server Docker image (Linux)
|
||||
condition: and(succeededOrFailed(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: SqlLocalDB stop MSSQLLocalDB
|
||||
displayName: Stop SQL Server LocalDB (Windows)
|
||||
condition: and(succeededOrFailed(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Copy artifacts
|
||||
- pwsh: |
|
||||
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results/* $(Build.ArtifactStagingDirectory) -Recurse
|
||||
}
|
||||
displayName: Copy Playwright results
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Publish
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish test artifacts
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
|
||||
|
||||
# Publish test results
|
||||
- task: PublishTestResults@2
|
||||
displayName: "Publish test results"
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
testResultsFormat: 'JUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
@@ -0,0 +1,69 @@
|
||||
parameters:
|
||||
- name: nodeVersion
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: PlaywrightUserEmail
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: PlaywrightPassword
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: ASPNETCORE_URLS
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
- name: npm_config_cache
|
||||
type: string
|
||||
default: ''
|
||||
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download NuGet artifacts
|
||||
inputs:
|
||||
artifact: nupkg
|
||||
path: $(Agent.BuildDirectory)/app/nupkg
|
||||
|
||||
- task: NodeTool@0
|
||||
displayName: Use Node.js $(nodeVersion)
|
||||
inputs:
|
||||
versionSpec: $(nodeVersion)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
|
||||
- pwsh: |
|
||||
"UMBRACO_USER_LOGIN=${{ parameters.PlaywrightUserEmail }}
|
||||
UMBRACO_USER_PASSWORD=${{ parameters.PlaywrightPassword }}
|
||||
URL=${{ parameters.ASPNETCORE_URLS }}
|
||||
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json" | Out-File .env
|
||||
displayName: Generate .env
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Cache and restore NPM packages
|
||||
- task: Cache@2
|
||||
displayName: Cache NPM packages
|
||||
inputs:
|
||||
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||
restoreKeys: |
|
||||
npm_e2e | "$(Agent.OS)"
|
||||
npm_e2e
|
||||
path: ${{ parameters.npm_config_cache }}
|
||||
|
||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
displayName: Restore NPM packages
|
||||
|
||||
# Install Template
|
||||
- pwsh: |
|
||||
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||
dotnet new nugetconfig
|
||||
dotnet nuget add source ./nupkg --name Local
|
||||
dotnet new install Umbraco.Templates::$cmsVersion
|
||||
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||
displayName: Install Template
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
@@ -3,13 +3,29 @@ name: Nightly_E2E_Test_$(TeamProject)_$(Build.DefinitionName)_$(SourceBranchName
|
||||
pr: none
|
||||
trigger: none
|
||||
|
||||
schedules:
|
||||
- cron: '0 0 * * *'
|
||||
displayName: Daily midnight build
|
||||
branches:
|
||||
include:
|
||||
- v14/dev
|
||||
- v15/dev
|
||||
# schedules:
|
||||
# - cron: '0 0 * * *'
|
||||
# displayName: Daily midnight build
|
||||
# branches:
|
||||
# include:
|
||||
# - v14/dev
|
||||
# - v15/dev
|
||||
|
||||
parameters:
|
||||
- name: differentAppSettingsAcceptanceTests
|
||||
displayName: Run acceptance tests with different app settings
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: skipDefaultConfigAcceptanceTests
|
||||
displayName: Skip tests with DefaultConfig
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
- name: skipIntegrationTests
|
||||
displayName: Skip integration tests
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
variables:
|
||||
nodeVersion: 20
|
||||
@@ -32,25 +48,17 @@ stages:
|
||||
- job: A
|
||||
displayName: Build Umbraco CMS
|
||||
pool:
|
||||
vmImage: 'ubuntu-latest'
|
||||
vmImage: "windows-latest"
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 0
|
||||
submodules: true
|
||||
submodules: false
|
||||
lfs: false,
|
||||
fetchDepth: 500
|
||||
- template: templates/backoffice-install.yml
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
- template: templates/backoffice-install.yml
|
||||
- script: npm run build:for:cms
|
||||
displayName: Run build (Bellissima)
|
||||
workingDirectory: src/Umbraco.Web.UI.Client
|
||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||
displayName: Run npm ci (Login)
|
||||
workingDirectory: src/Umbraco.Web.UI.Login
|
||||
- script: npm run build
|
||||
displayName: Run npm build (Login)
|
||||
workingDirectory: src/Umbraco.Web.UI.Login
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Run dotnet restore
|
||||
inputs:
|
||||
@@ -62,7 +70,7 @@ stages:
|
||||
inputs:
|
||||
command: build
|
||||
projects: $(solution)
|
||||
arguments: '--configuration $(buildConfiguration) --no-restore --property:ContinuousIntegrationBuild=true --property:GeneratePackageOnBuild=true --property:PackageOutputPath=$(Build.ArtifactStagingDirectory)/nupkg'
|
||||
arguments: "--configuration $(buildConfiguration) --no-restore --property:ContinuousIntegrationBuild=true --property:GeneratePackageOnBuild=true --property:PackageOutputPath=$(Build.ArtifactStagingDirectory)/nupkg"
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish nupkg
|
||||
inputs:
|
||||
@@ -74,8 +82,237 @@ stages:
|
||||
targetPath: $(Build.SourcesDirectory)
|
||||
artifactName: build_output
|
||||
|
||||
- stage: E2E
|
||||
displayName: E2E Tests
|
||||
- job: B
|
||||
displayName: Build Bellissima Package
|
||||
pool:
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: false
|
||||
lfs: false,
|
||||
fetchDepth: 500
|
||||
- template: templates/backoffice-install.yml
|
||||
- script: npm run build:for:npm
|
||||
displayName: Run build:for:npm
|
||||
workingDirectory: src/Umbraco.Web.UI.Client
|
||||
- bash: |
|
||||
echo "##[command]Running npm pack"
|
||||
echo "##[debug]Output directory: $(Build.ArtifactStagingDirectory)"
|
||||
mkdir $(Build.ArtifactStagingDirectory)/npm
|
||||
npm pack --pack-destination $(Build.ArtifactStagingDirectory)/npm
|
||||
mv .npmrc $(Build.ArtifactStagingDirectory)/npm/
|
||||
displayName: Run npm pack
|
||||
workingDirectory: src/Umbraco.Web.UI.Client
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish Bellissima npm artifact
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)/npm
|
||||
artifactName: npm
|
||||
- stage: Integration
|
||||
displayName: Integration Tests
|
||||
dependsOn: Build
|
||||
condition: ${{ eq(parameters.skipIntegrationTests, false) }}
|
||||
jobs:
|
||||
# Integration Tests (SQLite)
|
||||
- job:
|
||||
timeoutInMinutes: 180
|
||||
displayName: Integration Tests (SQLite)
|
||||
strategy:
|
||||
matrix:
|
||||
# Windows:
|
||||
# vmImage: 'windows-latest'
|
||||
# We split the tests into 4 parts for each OS to reduce the time it takes to run them on the pipeline
|
||||
LinuxPart1Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
||||
LinuxPart2Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
||||
LinuxPart3Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace. So this will run all tests that are not part of the Umbraco.Infrastructure namespace
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
LinuxPart4Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
# Filter tests that are part of the ManagementApi namespace
|
||||
testFilter: "(FullyQualifiedName~ManagementApi)"
|
||||
macOSPart1Of4:
|
||||
vmImage: "macOS-latest"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
||||
macOSPart2Of4:
|
||||
vmImage: "macOS-latest"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
||||
macOSPart3Of4:
|
||||
vmImage: "macOS-latest"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace.
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
macOSPart4Of4:
|
||||
vmImage: "macOS-latest"
|
||||
# Filter tests that are part of the ManagementApi namespace.
|
||||
testFilter: "(FullyQualifiedName~ManagementApi)"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
variables:
|
||||
Tests__Database__DatabaseType: "Sqlite"
|
||||
steps:
|
||||
- checkout: self
|
||||
submodules: false
|
||||
lfs: false,
|
||||
fetchDepth: 1
|
||||
fetchFilter: tree:0
|
||||
# Setup test environment
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download build artifacts
|
||||
inputs:
|
||||
artifact: build_output
|
||||
path: $(Build.SourcesDirectory)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
|
||||
# Test
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Run dotnet test
|
||||
inputs:
|
||||
command: test
|
||||
projects: "tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj"
|
||||
testRunTitle: Integration Tests SQLite - $(Agent.OS)
|
||||
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build'
|
||||
|
||||
# Integration Tests (SQL Server)
|
||||
- job:
|
||||
timeoutInMinutes: 180
|
||||
displayName: Integration Tests (SQL Server)
|
||||
variables:
|
||||
SA_PASSWORD: UmbracoAcceptance123!
|
||||
strategy:
|
||||
matrix:
|
||||
# We split the tests into 4 parts for each OS to reduce the time it takes to run them on the pipeline
|
||||
WindowsPart1Of4:
|
||||
vmImage: "windows-latest"
|
||||
Tests__Database__DatabaseType: LocalDb
|
||||
Tests__Database__SQLServerMasterConnectionString: N/A
|
||||
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
||||
WindowsPart2Of4:
|
||||
vmImage: "windows-latest"
|
||||
Tests__Database__DatabaseType: LocalDb
|
||||
Tests__Database__SQLServerMasterConnectionString: N/A
|
||||
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
||||
WindowsPart3Of4:
|
||||
vmImage: "windows-latest"
|
||||
Tests__Database__DatabaseType: LocalDb
|
||||
Tests__Database__SQLServerMasterConnectionString: N/A
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace.
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
WindowsPart4Of4:
|
||||
vmImage: "windows-latest"
|
||||
Tests__Database__DatabaseType: LocalDb
|
||||
Tests__Database__SQLServerMasterConnectionString: N/A
|
||||
# Filter tests that are part of the ManagementApi namespace.
|
||||
testFilter: "(FullyQualifiedName~ManagementApi)"
|
||||
LinuxPart1Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
Tests__Database__DatabaseType: SqlServer
|
||||
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure namespace but not part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure) & (FullyQualifiedName!~Umbraco.Infrastructure.Service)"
|
||||
LinuxPart2Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
Tests__Database__DatabaseType: SqlServer
|
||||
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
|
||||
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
|
||||
LinuxPart3Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
Tests__Database__DatabaseType: SqlServer
|
||||
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
# Filter tests that are not part of the Umbraco.Infrastructure and ManagementApi namespace.
|
||||
testFilter: "(FullyQualifiedName!~Umbraco.Infrastructure) & (FullyQualifiedName!~ManagementApi)"
|
||||
LinuxPart4Of4:
|
||||
vmImage: "ubuntu-latest"
|
||||
Tests__Database__DatabaseType: SqlServer
|
||||
Tests__Database__SQLServerMasterConnectionString: "Server=(local);User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
# Filter tests that are part of the ManagementApi namespace.
|
||||
testFilter: "(FullyQualifiedName~ManagementApi)"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
# Setup test environment
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download build artifacts
|
||||
inputs:
|
||||
artifact: build_output
|
||||
path: $(Build.SourcesDirectory)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
|
||||
# Start SQL Server
|
||||
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$(SA_PASSWORD)" mcr.microsoft.com/mssql/server:2022-latest
|
||||
displayName: Start SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- powershell: |
|
||||
$maxAttempts = 12
|
||||
$attempt = 0
|
||||
$status = ""
|
||||
|
||||
while (($status -ne 'running') -and ($attempt -lt $maxAttempts)) {
|
||||
Start-Sleep -Seconds 5
|
||||
# We use the docker inspect command to check the status of the container. If the container is not running, we wait 5 seconds and try again. And if reaches 12 attempts, we fail the build.
|
||||
$status = docker inspect -f '{{.State.Status}}' mssql
|
||||
|
||||
if ($status -ne 'running') {
|
||||
Write-Host "Waiting for SQL Server to be ready... Attempt $($attempt + 1)"
|
||||
$attempt++
|
||||
}
|
||||
}
|
||||
|
||||
if ($status -eq 'running') {
|
||||
Write-Host "SQL Server container is running"
|
||||
docker ps -a
|
||||
} else {
|
||||
Write-Host "SQL Server did not become ready in time. Last known status: $status"
|
||||
docker logs mssql
|
||||
exit 1
|
||||
}
|
||||
displayName: Wait for SQL Server to be ready (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||
displayName: Start SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Test
|
||||
- task: DotNetCoreCLI@2
|
||||
displayName: Run dotnet test
|
||||
inputs:
|
||||
command: test
|
||||
projects: "tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj"
|
||||
testRunTitle: Integration Tests SQL Server - $(Agent.OS)
|
||||
arguments: '--filter "$(testFilter)" --configuration $(buildConfiguration) --no-build'
|
||||
|
||||
# Stop SQL Server
|
||||
- pwsh: docker stop mssql
|
||||
displayName: Stop SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: SqlLocalDB stop MSSQLLocalDB
|
||||
displayName: Stop SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
- stage: DefaultConfigE2E
|
||||
displayName: Default Config E2E Tests
|
||||
dependsOn: Build
|
||||
variables:
|
||||
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
||||
@@ -103,338 +340,290 @@ stages:
|
||||
- job:
|
||||
displayName: E2E Tests (SQLite)
|
||||
timeoutInMinutes: 180
|
||||
condition: ${{ eq(parameters.skipDefaultConfigAcceptanceTests, false) }}
|
||||
variables:
|
||||
# Connection string
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=Umbraco;Mode=Memory;Cache=Shared;Foreign Keys=True;Pooling=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.Sqlite
|
||||
DatabaseType: SQLite
|
||||
strategy:
|
||||
matrix:
|
||||
LinuxPart1Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
testCommand: "npm run test -- --shard=1/3"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run testSqlite -- --shard=1/3"
|
||||
LinuxPart2Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
testCommand: "npm run test -- --shard=2/3"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run testSqlite -- --shard=2/3"
|
||||
LinuxPart3Of3:
|
||||
vmImage: "ubuntu-latest"
|
||||
testCommand: "npm run test -- --shard=3/3"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run testSqlite -- --shard=3/3"
|
||||
WindowsPart1Of3:
|
||||
vmImage: "windows-latest"
|
||||
testCommand: "npm run test -- --shard=1/3"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run testSqlite -- --shard=1/3"
|
||||
WindowsPart2Of3:
|
||||
vmImage: "windows-latest"
|
||||
testCommand: "npm run test -- --shard=2/3"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run testSqlite -- --shard=2/3"
|
||||
WindowsPart3Of3:
|
||||
vmImage: "windows-latest"
|
||||
testCommand: "npm run test -- --shard=3/3"
|
||||
testFolder: "DefaultConfig"
|
||||
testCommand: "npm run testSqlite -- --shard=3/3"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
# Setup test environment
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download NuGet artifacts
|
||||
inputs:
|
||||
artifact: nupkg
|
||||
path: $(Agent.BuildDirectory)/app/nupkg
|
||||
|
||||
- task: NodeTool@0
|
||||
displayName: Use Node.js $(nodeVersion)
|
||||
retryCountOnTaskFailure: 3
|
||||
inputs:
|
||||
versionSpec: $(nodeVersion)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
# Setup test environment Template
|
||||
- template: nightly-E2E-setup-template.yml
|
||||
parameters:
|
||||
nodeVersion: ${{ variables.nodeVersion }}
|
||||
PlaywrightUserEmail: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL }}
|
||||
PlaywrightPassword: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD }}
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
npm_config_cache: ${{ variables.npm_config_cache }}
|
||||
|
||||
- pwsh: |
|
||||
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
|
||||
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
URL=$(ASPNETCORE_URLS)
|
||||
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json" | Out-File .env
|
||||
displayName: Generate .env
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Cache and restore NPM packages
|
||||
- task: Cache@2
|
||||
displayName: Cache NPM packages
|
||||
inputs:
|
||||
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||
restoreKeys: |
|
||||
npm_e2e | "$(Agent.OS)"
|
||||
npm_e2e
|
||||
path: $(npm_config_cache)
|
||||
|
||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
displayName: Restore NPM packages
|
||||
|
||||
# Build application
|
||||
- pwsh: |
|
||||
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||
dotnet new nugetconfig
|
||||
dotnet nuget add source ./nupkg --name Local
|
||||
dotnet new install Umbraco.Templates::$cmsVersion
|
||||
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||
dotnet restore UmbracoProject
|
||||
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
|
||||
displayName: Restore project
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
- pwsh: |
|
||||
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
||||
dotnet dev-certs https
|
||||
displayName: Build application
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
condition: succeeded()
|
||||
|
||||
# Run application
|
||||
- bash: |
|
||||
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||
displayName: Run application (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
# Run application Template
|
||||
- template: nightly-E2E-run-application-template.yml
|
||||
parameters:
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
buildConfiguration: ${{ variables.buildConfiguration }}
|
||||
|
||||
- pwsh: |
|
||||
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||
displayName: Run application (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Ensures we have the package wait-on installed
|
||||
- pwsh: npm install wait-on
|
||||
displayName: Install wait-on package
|
||||
|
||||
# Wait for application to start responding to requests
|
||||
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
||||
displayName: Wait for application
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Install Playwright and dependencies
|
||||
- pwsh: npx playwright install --with-deps
|
||||
displayName: Install Playwright
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Test
|
||||
- pwsh: $(testCommand)
|
||||
displayName: Run Playwright tests
|
||||
continueOnError: true
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
env:
|
||||
CI: true
|
||||
CommitId: $(Build.SourceVersion)
|
||||
AgentOs: $(Agent.OS)
|
||||
|
||||
# Stop application
|
||||
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Linux)
|
||||
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Windows)
|
||||
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Copy artifacts
|
||||
- pwsh: |
|
||||
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results/* $(Build.ArtifactStagingDirectory) -Recurse
|
||||
}
|
||||
displayName: Copy Playwright results
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Publish
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish test artifacts
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
|
||||
|
||||
# Publish test results
|
||||
- task: PublishTestResults@2
|
||||
displayName: "Publish test results"
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
testResultsFormat: 'JUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
# Run tests Template
|
||||
- template: nightly-E2E-run-tests-template.yml
|
||||
parameters:
|
||||
testCommand: $(testCommand)
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
- job:
|
||||
displayName: E2E Tests (SQL Server)
|
||||
timeoutInMinutes: 180
|
||||
condition: ${{ eq(parameters.skipDefaultConfigAcceptanceTests, false) }}
|
||||
variables:
|
||||
# Connection string
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
||||
DatabaseType: SQLServer
|
||||
SA_PASSWORD: UmbracoAcceptance123!
|
||||
strategy:
|
||||
matrix:
|
||||
LinuxPart1Of3:
|
||||
testCommand: "npm run testSqlite -- --shard=1/3"
|
||||
testCommand: "npm run test -- --shard=1/3"
|
||||
testFolder: "DefaultConfig"
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
LinuxPart2Of3:
|
||||
testCommand: "npm run testSqlite -- --shard=2/3"
|
||||
testCommand: "npm run test -- --shard=2/3"
|
||||
testFolder: "DefaultConfig"
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
LinuxPart3Of3:
|
||||
testCommand: "npm run testSqlite -- --shard=3/3"
|
||||
testCommand: "npm run test -- --shard=3/3"
|
||||
testFolder: "DefaultConfig"
|
||||
vmImage: "ubuntu-latest"
|
||||
SA_PASSWORD: $(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);TrustServerCertificate=True"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: "Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True"
|
||||
WindowsPart1Of3:
|
||||
testCommand: "npm run test -- --shard=1/3"
|
||||
testFolder: "DefaultConfig"
|
||||
vmImage: "windows-latest"
|
||||
testCommand: "npm run testSqlite -- --shard=1/3"
|
||||
WindowsPart2Of3:
|
||||
testCommand: "npm run test -- --shard=2/3"
|
||||
testFolder: "DefaultConfig"
|
||||
vmImage: "windows-latest"
|
||||
testCommand: "npm run testSqlite -- --shard=2/3"
|
||||
WindowsPart3Of3:
|
||||
testCommand: "npm run test -- --shard=3/3"
|
||||
testFolder: "DefaultConfig"
|
||||
vmImage: "windows-latest"
|
||||
testCommand: "npm run testSqlite -- --shard=3/3"
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
# Setup test environment
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download NuGet artifacts
|
||||
inputs:
|
||||
artifact: nupkg
|
||||
path: $(Agent.BuildDirectory)/app/nupkg
|
||||
|
||||
- task: NodeTool@0
|
||||
displayName: Use Node.js $(nodeVersion)
|
||||
inputs:
|
||||
versionSpec: $(nodeVersion)
|
||||
|
||||
- task: UseDotNet@2
|
||||
displayName: Use .NET SDK from global.json
|
||||
inputs:
|
||||
useGlobalJson: true
|
||||
# Setup test environment Template
|
||||
- template: nightly-E2E-setup-template.yml
|
||||
parameters:
|
||||
nodeVersion: ${{ variables.nodeVersion }}
|
||||
PlaywrightUserEmail: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL }}
|
||||
PlaywrightPassword: ${{ variables.UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD }}
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
npm_config_cache: ${{ variables.npm_config_cache }}
|
||||
|
||||
- pwsh: |
|
||||
"UMBRACO_USER_LOGIN=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSEREMAIL)
|
||||
UMBRACO_USER_PASSWORD=$(UMBRACO__CMS__UNATTENDED__UNATTENDEDUSERPASSWORD)
|
||||
URL=$(ASPNETCORE_URLS)
|
||||
STORAGE_STAGE_PATH=$(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/playwright/.auth/user.json" | Out-File .env
|
||||
displayName: Generate .env
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Cache and restore NPM packages
|
||||
- task: Cache@2
|
||||
displayName: Cache NPM packages
|
||||
inputs:
|
||||
key: 'npm_e2e | "$(Agent.OS)" | $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest/package-lock.json'
|
||||
restoreKeys: |
|
||||
npm_e2e | "$(Agent.OS)"
|
||||
npm_e2e
|
||||
path: $(npm_config_cache)
|
||||
|
||||
- script: npm ci --no-fund --no-audit --prefer-offline
|
||||
workingDirectory: $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest
|
||||
displayName: Restore NPM packages
|
||||
|
||||
# Build application
|
||||
- pwsh: |
|
||||
$cmsVersion = "$(Build.BuildNumber)" -replace "\+",".g"
|
||||
dotnet new nugetconfig
|
||||
dotnet nuget add source ./nupkg --name Local
|
||||
dotnet new install Umbraco.Templates::$cmsVersion
|
||||
dotnet new umbraco --name UmbracoProject --version $cmsVersion --exclude-gitignore --no-restore --no-update-check
|
||||
dotnet restore UmbracoProject
|
||||
cp $(Build.SourcesDirectory)/tests/Umbraco.Tests.AcceptanceTest.UmbracoProject/*.cs UmbracoProject
|
||||
dotnet build UmbracoProject --configuration $(buildConfiguration) --no-restore
|
||||
displayName: Restore project
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
- pwsh: |
|
||||
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
||||
dotnet dev-certs https
|
||||
displayName: Build application
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
condition: succeeded()
|
||||
|
||||
# Start SQL Server
|
||||
- powershell: docker run --name mssql -d -p 1433:1433 -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=$(SA_PASSWORD)" mcr.microsoft.com/mssql/server:2022-latest
|
||||
displayName: Start SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
# Run application Template
|
||||
- template: nightly-E2E-run-application-template.yml
|
||||
parameters:
|
||||
SA_PASSWORD: ${{ variables.SA_PASSWORD }}
|
||||
buildConfiguration: ${{ variables.buildConfiguration }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
- pwsh: SqlLocalDB start MSSQLLocalDB
|
||||
displayName: Start SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
# Run tests Template
|
||||
- template: nightly-E2E-run-tests-template.yml
|
||||
parameters:
|
||||
testCommand: $(testCommand)
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
# Run application
|
||||
- stage: AdditionalConfigE2E
|
||||
displayName: Additional Config E2E Tests
|
||||
dependsOn: Build
|
||||
variables:
|
||||
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
|
||||
ASPNETCORE_URLS: https://localhost:44331
|
||||
PlaywrightPassword: UmbracoAcceptance123!
|
||||
PlaywrightUserEmail: playwright@umbraco.com
|
||||
jobs:
|
||||
- job:
|
||||
displayName: E2E Tests with Different App settings (SQL Server)
|
||||
condition: ${{ eq(parameters.differentAppSettingsAcceptanceTests, true) }}
|
||||
timeoutInMinutes: 180
|
||||
variables:
|
||||
SA_PASSWORD: UmbracoAcceptance123!
|
||||
DatabaseType: SQLServer
|
||||
strategy:
|
||||
matrix:
|
||||
# UnattendedInstallConfig
|
||||
WindowsUnattendedInstallConfig:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "UnattendedInstallConfig"
|
||||
testCommand: "npx playwright test --project=unattendedInstallConfig --grep=InstallSQLServer"
|
||||
port: 44331
|
||||
additionalEnvironmentVariables: false
|
||||
# DeliveryApiConfig
|
||||
WindowsDeliveryApiConfig:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "DeliveryApi"
|
||||
port: ''
|
||||
testCommand: "npx playwright test --project=deliveryApi"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
||||
additionalEnvironmentVariables: false
|
||||
LinuxDeliveryApiConfig:
|
||||
vmImage: "ubuntu-latest"
|
||||
testFolder: "DeliveryApi"
|
||||
port: ''
|
||||
testCommand: "npx playwright test --project=deliveryApi"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Server=(local);Database=Umbraco;User Id=sa;Password=$(SA_PASSWORD);Encrypt=True;TrustServerCertificate=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
||||
additionalEnvironmentVariables: false
|
||||
# ExternalLogin AzureADB2C
|
||||
WindowsExternalLoginAzureADB2C:
|
||||
vmImage: "windows-latest"
|
||||
testFolder: "ExternalLogin\\AzureADB2C"
|
||||
testCommand: "npx playwright test --project=externalLoginAzureADB2C"
|
||||
port: 44331
|
||||
packageName: "Microsoft.AspNetCore.Authentication.OpenIdConnect"
|
||||
packageVersion: "9.0.8"
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN: Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Umbraco.mdf;Integrated Security=True
|
||||
CONNECTIONSTRINGS__UMBRACODBDSN_PROVIDERNAME: Microsoft.Data.SqlClient
|
||||
additionalEnvironmentVariables: true
|
||||
pool:
|
||||
vmImage: $(vmImage)
|
||||
steps:
|
||||
# Setup test environment Template
|
||||
- template: nightly-E2E-setup-template.yml
|
||||
parameters:
|
||||
nodeVersion: ${{ variables.nodeVersion }}
|
||||
PlaywrightUserEmail: ${{ variables.PlaywrightUserEmail }}
|
||||
PlaywrightPassword: ${{ variables.PlaywrightPassword }}
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
npm_config_cache: ${{ variables.npm_config_cache }}
|
||||
|
||||
# Install NuGet package if specified in the matrix
|
||||
- pwsh: |
|
||||
Write-Host "Installing package $(packageName) version $(packageVersion)"
|
||||
dotnet add package $(packageName) --version $(packageVersion)
|
||||
displayName: "Install NuGet package: $(packageName)"
|
||||
workingDirectory: $(Agent.BuildDirectory)/app/UmbracoProject
|
||||
condition: and(succeeded(), ne(variables['packageName'], ''), ne(variables['packageVersion'], ''))
|
||||
|
||||
# Build application Template
|
||||
- template: nightly-E2E-build-template.yml
|
||||
parameters:
|
||||
testFolder: $(testFolder)
|
||||
buildConfiguration: ${{ variables.buildConfiguration }}
|
||||
additionalEnvironmentVariables: ${{ eq(variables['additionalEnvironmentVariables'], true) }}
|
||||
|
||||
# Build application for AzureADB2C
|
||||
- pwsh: |
|
||||
dotnet build UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-restore
|
||||
dotnet dev-certs https
|
||||
displayName: Build application for AzureADB2C
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
env:
|
||||
AZUREADB2CDOMAIN: $(AZUREB2CDOMAIN)
|
||||
AZUREADB2CTENANT: $(AZUREB2CTENANT)
|
||||
AZUREADB2CPOLICY: $(AZUREB2CPOLICY)
|
||||
AZUREADB2CCLIENTID: $(AZUREB2CCLIENTID)
|
||||
AZUREADB2CCLIENTSECRET: $(AZUREB2CCLIENTSECRET)
|
||||
condition: and(succeeded(), eq(variables['testFolder'], 'ExternalLogin\AzureADB2C'))
|
||||
|
||||
# Run application Template
|
||||
- template: nightly-E2E-run-application-template.yml
|
||||
parameters:
|
||||
SA_PASSWORD: ${{ variables.SA_PASSWORD }}
|
||||
additionalEnvironmentVariables: ${{ eq(variables['additionalEnvironmentVariables'], true ) }}
|
||||
buildConfiguration: ${{ variables.buildConfiguration }}
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
# Run application for Linux with additional Environment Variables for Azure AD
|
||||
- bash: |
|
||||
nohup dotnet run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||
nohup dotnet run --project UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-build --no-launch-profile > $(Build.ArtifactStagingDirectory)/playwright.log 2>&1 &
|
||||
echo "##vso[task.setvariable variable=AcceptanceTestProcessId]$!"
|
||||
displayName: Run application (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'), eq(variables['testFolder'], 'ExternalLogin\AzureADB2C'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
env:
|
||||
AZUREADB2CDOMAIN: $(AZUREB2CDOMAIN)
|
||||
AZUREADB2CTENANT: $(AZUREB2CTENANT)
|
||||
AZUREADB2CPOLICY: $(AZUREB2CPOLICY)
|
||||
AZUREADB2CCLIENTID: $(AZUREB2CCLIENTID)
|
||||
AZUREADB2CCLIENTSECRET: $(AZUREB2CCLIENTSECRET)
|
||||
|
||||
# Run application for Windows with additional Environment Variables for Azure AD
|
||||
- pwsh: |
|
||||
$process = Start-Process dotnet "run --project UmbracoProject --configuration $(buildConfiguration) --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||
$process = Start-Process dotnet "run --project UmbracoProject --configuration ${{ variables.buildConfiguration }} --no-build --no-launch-profile 2>&1" -PassThru -NoNewWindow -RedirectStandardOutput $(Build.ArtifactStagingDirectory)/playwright.log
|
||||
Write-Host "##vso[task.setvariable variable=AcceptanceTestProcessId]$($process.Id)"
|
||||
displayName: Run application (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'), eq(variables['testFolder'], 'ExternalLogin\AzureADB2C'))
|
||||
workingDirectory: $(Agent.BuildDirectory)/app
|
||||
|
||||
# Ensures we have the package wait-on installed
|
||||
- pwsh: npm install wait-on
|
||||
displayName: Install wait-on package
|
||||
|
||||
# Wait for application to start responding to requests
|
||||
- pwsh: npx wait-on -v --interval 1000 --timeout 120000 $(ASPNETCORE_URLS)
|
||||
displayName: Wait for application
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Install Playwright and dependencies
|
||||
- pwsh: npx playwright install --with-deps
|
||||
displayName: Install Playwright
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
|
||||
# Test
|
||||
- pwsh: $(testCommand)
|
||||
displayName: Run Playwright tests
|
||||
continueOnError: true
|
||||
workingDirectory: tests/Umbraco.Tests.AcceptanceTest
|
||||
env:
|
||||
CI: true
|
||||
CommitId: $(Build.SourceVersion)
|
||||
AgentOs: $(Agent.OS)
|
||||
AZUREADB2CDOMAIN: $(AZUREB2CDOMAIN)
|
||||
AZUREADB2CTENANT: $(AZUREB2CTENANT)
|
||||
AZUREADB2CPOLICY: $(AZUREB2CPOLICY)
|
||||
AZUREADB2CCLIENTID: $(AZUREB2CCLIENTID)
|
||||
AZUREADB2CCLIENTSECRET: $(AZUREB2CCLIENTSECRET)
|
||||
|
||||
# Stop application
|
||||
- bash: kill -15 $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Linux)
|
||||
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: Stop-Process -Id $(AcceptanceTestProcessId)
|
||||
displayName: Stop application (Windows)
|
||||
condition: and(succeeded(), ne(variables.AcceptanceTestProcessId, ''), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Stop SQL Server
|
||||
- pwsh: docker stop mssql
|
||||
displayName: Stop SQL Server Docker image (Linux)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
|
||||
|
||||
- pwsh: SqlLocalDB stop MSSQLLocalDB
|
||||
displayName: Stop SQL Server LocalDB (Windows)
|
||||
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
|
||||
|
||||
# Copy artifacts
|
||||
- pwsh: |
|
||||
if (Test-Path tests/Umbraco.Tests.AcceptanceTest/results/*) {
|
||||
Copy-Item tests/Umbraco.Tests.AcceptanceTest/results/* $(Build.ArtifactStagingDirectory) -Recurse
|
||||
}
|
||||
displayName: Copy Playwright results
|
||||
condition: succeededOrFailed()
|
||||
|
||||
# Publish
|
||||
- task: PublishPipelineArtifact@1
|
||||
displayName: Publish test artifacts
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
artifact: "Acceptance Test Results - $(Agent.JobName) - Attempt #$(System.JobAttempt)"
|
||||
|
||||
# Publish test results
|
||||
- task: PublishTestResults@2
|
||||
displayName: "Publish test results"
|
||||
condition: succeededOrFailed()
|
||||
inputs:
|
||||
testResultsFormat: 'JUnit'
|
||||
testResultsFiles: '*.xml'
|
||||
searchFolder: "tests/Umbraco.Tests.AcceptanceTest/results"
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
# Run tests Template
|
||||
- template: nightly-E2E-run-tests-template.yml
|
||||
parameters:
|
||||
testCommand: $(testCommand)
|
||||
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
|
||||
port: $(port)
|
||||
AZUREB2CTESTUSEREMAIL: $(AZUREB2CTESTUSEREMAIL)
|
||||
AZUREB2CTESTUSERPASSWORD: $(AZUREB2CTESTUSERPASSWORD)
|
||||
DatabaseType: ${{ variables.DatabaseType }}
|
||||
|
||||
@@ -18,7 +18,12 @@ internal sealed class DeliveryApiOutputCachePolicy : IOutputCachePolicy
|
||||
.RequestServices
|
||||
.GetRequiredService<IRequestPreviewService>();
|
||||
|
||||
context.EnableOutputCaching = requestPreviewService.IsPreview() is false;
|
||||
IApiAccessService apiAccessService = context
|
||||
.HttpContext
|
||||
.RequestServices
|
||||
.GetRequiredService<IApiAccessService>();
|
||||
|
||||
context.EnableOutputCaching = requestPreviewService.IsPreview() is false && apiAccessService.HasPublicAccess();
|
||||
context.ResponseExpirationTimeSpan = _duration;
|
||||
|
||||
return ValueTask.CompletedTask;
|
||||
|
||||
@@ -127,10 +127,16 @@ internal class EFCoreScope<TDbContext> : CoreScope, IEfCoreScope<TDbContext>
|
||||
|
||||
Locks.ClearLocks(InstanceId);
|
||||
|
||||
if (ParentScope is null)
|
||||
// Since we can nest EFCoreScopes in other scopes derived from CoreScope, we should check whether our ParentScope OR the base ParentScope exists.
|
||||
// Only if neither do do we take responsibility for ensuring the locks are cleared.
|
||||
// Eventually the highest parent will clear the locks.
|
||||
// Further, these locks are a reference to the locks of the highest parent anyway (see the constructor of CoreScope).
|
||||
#pragma warning disable SA1100 // Do not prefix calls with base unless local implementation exists (justification: provides additional clarify here that this is defined on the base class).
|
||||
if (ParentScope is null && base.HasParentScope is false)
|
||||
{
|
||||
Locks.EnsureLocksCleared(InstanceId);
|
||||
}
|
||||
#pragma warning restore SA1100 // Do not prefix calls with base unless local implementation exists
|
||||
|
||||
_efCoreScopeProvider.PopAmbientScope();
|
||||
|
||||
|
||||
@@ -5,14 +5,17 @@ namespace Umbraco.Extensions;
|
||||
public static class ContentSettingsExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Determines if file extension is allowed for upload based on (optional) white list and black list
|
||||
/// held in settings.
|
||||
/// Allow upload if extension is whitelisted OR if there is no whitelist and extension is NOT blacklisted.
|
||||
/// Determines if file extension is allowed for upload based on (optional) allow list and deny list held in settings.
|
||||
/// Disallowed file extensions are only considered if there are no allowed file extensions.
|
||||
/// </summary>
|
||||
public static bool IsFileAllowedForUpload(this ContentSettings contentSettings, string extension) =>
|
||||
contentSettings.AllowedUploadedFileExtensions.Any(x => x.InvariantEquals(extension)) ||
|
||||
(contentSettings.AllowedUploadedFileExtensions.Any() == false &&
|
||||
contentSettings.DisallowedUploadedFileExtensions.Any(x => x.InvariantEquals(extension)) == false);
|
||||
/// <param name="contentSettings">The content settings.</param>
|
||||
/// <param name="extension">The file extension.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the file extension is allowed for upload; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public static bool IsFileAllowedForUpload(this ContentSettings contentSettings, string extension)
|
||||
=> contentSettings.AllowedUploadedFileExtensions.Any(x => x.InvariantEquals(extension.Trim())) ||
|
||||
(contentSettings.AllowedUploadedFileExtensions.Any() == false && contentSettings.DisallowedUploadedFileExtensions.Any(x => x.InvariantEquals(extension.Trim())) == false);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the auto-fill configuration for a specified property alias.
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Editors;
|
||||
|
||||
@@ -12,14 +15,27 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
// TODO: We could further reduce circular dependencies with PropertyEditorCollection by not having IDataValueReference implemented
|
||||
// by property editors and instead just use the already built in IDataValueReferenceFactory and/or refactor that into a more normal collection
|
||||
|
||||
private readonly ILogger<DataValueReferenceFactoryCollection> _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataValueReferenceFactoryCollection" /> class.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
[Obsolete("Please use the constructor taking all parameters. Scheduled for removal in Umbraco 17.")]
|
||||
public DataValueReferenceFactoryCollection(Func<IEnumerable<IDataValueReferenceFactory>> items)
|
||||
: base(items)
|
||||
: this(
|
||||
items,
|
||||
StaticServiceProvider.Instance.GetRequiredService<ILogger<DataValueReferenceFactoryCollection>>())
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DataValueReferenceFactoryCollection" /> class.
|
||||
/// </summary>
|
||||
/// <param name="items">The items.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public DataValueReferenceFactoryCollection(Func<IEnumerable<IDataValueReferenceFactory>> items, ILogger<DataValueReferenceFactoryCollection> logger)
|
||||
: base(items) => _logger = logger;
|
||||
|
||||
/// <summary>
|
||||
/// Gets all unique references from the specified properties.
|
||||
/// </summary>
|
||||
@@ -33,7 +49,7 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
var references = new HashSet<UmbracoEntityReference>();
|
||||
|
||||
// Group by property editor alias to avoid duplicate lookups and optimize value parsing
|
||||
foreach (var propertyValuesByPropertyEditorAlias in properties.GroupBy(x => x.PropertyType.PropertyEditorAlias, x => x.Values))
|
||||
foreach (IGrouping<string, IReadOnlyCollection<IPropertyValue>> propertyValuesByPropertyEditorAlias in properties.GroupBy(x => x.PropertyType.PropertyEditorAlias, x => x.Values))
|
||||
{
|
||||
if (!propertyEditors.TryGet(propertyValuesByPropertyEditorAlias.Key, out IDataEditor? dataEditor))
|
||||
{
|
||||
@@ -48,7 +64,7 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
values.Add(propertyValue.PublishedValue);
|
||||
}
|
||||
|
||||
references.UnionWith(GetReferences(dataEditor, values));
|
||||
references.UnionWith(GetReferences(dataEditor, values, propertyValuesByPropertyEditorAlias.Key));
|
||||
}
|
||||
|
||||
return references;
|
||||
@@ -74,14 +90,18 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
/// The references.
|
||||
/// </returns>
|
||||
public ISet<UmbracoEntityReference> GetReferences(IDataEditor dataEditor, IEnumerable<object?> values) =>
|
||||
GetReferencesEnumerable(dataEditor, values).ToHashSet();
|
||||
private IEnumerable<UmbracoEntityReference> GetReferencesEnumerable(IDataEditor dataEditor, IEnumerable<object?> values)
|
||||
GetReferencesEnumerable(dataEditor, values, null).ToHashSet();
|
||||
|
||||
private ISet<UmbracoEntityReference> GetReferences(IDataEditor dataEditor, IEnumerable<object?> values, string propertyEditorAlias) =>
|
||||
GetReferencesEnumerable(dataEditor, values, propertyEditorAlias).ToHashSet();
|
||||
|
||||
private IEnumerable<UmbracoEntityReference> GetReferencesEnumerable(IDataEditor dataEditor, IEnumerable<object?> values, string? propertyEditorAlias)
|
||||
{
|
||||
// TODO: We will need to change this once we support tracking via variants/segments
|
||||
// for now, we are tracking values from ALL variants
|
||||
if (dataEditor.GetValueEditor() is IDataValueReference dataValueReference)
|
||||
{
|
||||
foreach (UmbracoEntityReference reference in values.SelectMany(dataValueReference.GetReferences))
|
||||
foreach (UmbracoEntityReference reference in GetReferencesFromPropertyValues(values, dataValueReference, propertyEditorAlias))
|
||||
{
|
||||
yield return reference;
|
||||
}
|
||||
@@ -107,6 +127,38 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<UmbracoEntityReference> GetReferencesFromPropertyValues(IEnumerable<object?> values, IDataValueReference dataValueReference, string? propertyEditorAlias)
|
||||
{
|
||||
var result = new List<UmbracoEntityReference>();
|
||||
foreach (var value in values)
|
||||
{
|
||||
// When property editors on data types are changed, we could have values that are incompatible with the new editor.
|
||||
// Leading to issues such as:
|
||||
// - https://github.com/umbraco/Umbraco-CMS/issues/17628
|
||||
// - https://github.com/umbraco/Umbraco-CMS/issues/17725
|
||||
// Although some changes like this are not intended to be compatible, we should handle them gracefully and not
|
||||
// error in retrieving references, which would prevent manipulating or deleting the content that uses the data type.
|
||||
try
|
||||
{
|
||||
IEnumerable<UmbracoEntityReference> references = dataValueReference.GetReferences(value);
|
||||
result.AddRange(references);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Log the exception but don't throw, continue with the next value.
|
||||
_logger.LogError(
|
||||
ex,
|
||||
"Error getting references from value {Value} with data editor {DataEditor} and property editor alias {PropertyEditorAlias}.",
|
||||
value,
|
||||
dataValueReference.GetType().FullName,
|
||||
propertyEditorAlias ?? "n/a");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all relation type aliases that are automatically tracked.
|
||||
/// </summary>
|
||||
@@ -117,6 +169,7 @@ public class DataValueReferenceFactoryCollection : BuilderCollectionBase<IDataVa
|
||||
[Obsolete("Use GetAllAutomaticRelationTypesAliases. This will be removed in Umbraco 15.")]
|
||||
public ISet<string> GetAutomaticRelationTypesAliases(PropertyEditorCollection propertyEditors) =>
|
||||
GetAllAutomaticRelationTypesAliases(propertyEditors);
|
||||
|
||||
public ISet<string> GetAllAutomaticRelationTypesAliases(PropertyEditorCollection propertyEditors)
|
||||
{
|
||||
// Always add default automatic relation types
|
||||
|
||||
@@ -101,7 +101,7 @@ public interface IPublishedCache
|
||||
/// </summary>
|
||||
/// <param name="id">The content type unique identifier.</param>
|
||||
/// <returns>The content type, or null.</returns>
|
||||
[Obsolete("Please use the IContentTypeCacheService instead, scheduled for removal in V16")]
|
||||
[Obsolete("Please use the IPublishedContentTypeCache instead, scheduled for removal in V16")]
|
||||
IPublishedContentType? GetContentType(int id);
|
||||
|
||||
/// <summary>
|
||||
@@ -110,7 +110,7 @@ public interface IPublishedCache
|
||||
/// <param name="alias">The content type alias.</param>
|
||||
/// <returns>The content type, or null.</returns>
|
||||
/// <remarks>The alias is case-insensitive.</remarks>
|
||||
[Obsolete("Please use the IContentTypeCacheService instead, scheduled for removal in V16")]
|
||||
[Obsolete("Please use the IPublishedContentTypeCache instead, scheduled for removal in V16")]
|
||||
IPublishedContentType? GetContentType(string alias);
|
||||
|
||||
/// <summary>
|
||||
@@ -126,6 +126,6 @@ public interface IPublishedCache
|
||||
/// </summary>
|
||||
/// <param name="key">The content type key.</param>
|
||||
/// <returns>The content type, or null.</returns>
|
||||
[Obsolete("Please use the IContentTypeCacheService instead, scheduled for removal in V16")]
|
||||
[Obsolete("Please use the IPublishedContentTypeCache instead, scheduled for removal in V16")]
|
||||
IPublishedContentType? GetContentType(Guid key);
|
||||
}
|
||||
|
||||
@@ -250,6 +250,8 @@ public class CoreScope : ICoreScope
|
||||
_parentScope = coreScope;
|
||||
}
|
||||
|
||||
protected bool HasParentScope => _parentScope is not null;
|
||||
|
||||
protected void HandleScopedNotifications() => _notificationPublisher?.ScopeExit(Completed.HasValue && Completed.Value);
|
||||
|
||||
private void EnsureNotDisposed()
|
||||
|
||||
@@ -44,26 +44,51 @@ public class DocumentUrlService : IDocumentUrlService
|
||||
/// <summary>
|
||||
/// Model used to cache a single published document along with all it's URL segments.
|
||||
/// </summary>
|
||||
private class PublishedDocumentUrlSegments
|
||||
/// <remarks>Internal for the purpose of unit and benchmark testing.</remarks>
|
||||
internal class PublishedDocumentUrlSegments
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the document key.
|
||||
/// </summary>
|
||||
public required Guid DocumentKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the language Id.
|
||||
/// </summary>
|
||||
public required int LanguageId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the collection of <see cref="UrlSegment"/> for the document, language and state.
|
||||
/// </summary>
|
||||
public required IList<UrlSegment> UrlSegments { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the document is a draft version or not.
|
||||
/// </summary>
|
||||
public required bool IsDraft { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Model used to represent a URL segment for a document in the cache.
|
||||
/// </summary>
|
||||
public class UrlSegment
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UrlSegment"/> class.
|
||||
/// </summary>
|
||||
public UrlSegment(string segment, bool isPrimary)
|
||||
{
|
||||
Segment = segment;
|
||||
IsPrimary = isPrimary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the URL segment string.
|
||||
/// </summary>
|
||||
public string Segment { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this URL segment is the primary one for the document, language and state.
|
||||
/// </summary>
|
||||
public bool IsPrimary { get; }
|
||||
}
|
||||
}
|
||||
@@ -168,45 +193,40 @@ public class DocumentUrlService : IDocumentUrlService
|
||||
scope.Complete();
|
||||
}
|
||||
|
||||
private static IEnumerable<PublishedDocumentUrlSegments> ConvertToCacheModel(IEnumerable<PublishedDocumentUrlSegment> publishedDocumentUrlSegments)
|
||||
/// <summary>
|
||||
/// Converts a collection of <see cref="PublishedDocumentUrlSegment"/> to a collection of <see cref="PublishedDocumentUrlSegments"/> for caching purposes.
|
||||
/// </summary>
|
||||
/// <param name="publishedDocumentUrlSegments">The collection of <see cref="PublishedDocumentUrlSegment"/> retrieved from the database on startup.</param>
|
||||
/// <returns>The collection of cache models.</returns>
|
||||
/// <remarks>Internal for the purpose of unit and benchmark testing.</remarks>
|
||||
internal static IEnumerable<PublishedDocumentUrlSegments> ConvertToCacheModel(IEnumerable<PublishedDocumentUrlSegment> publishedDocumentUrlSegments)
|
||||
{
|
||||
var cacheModels = new List<PublishedDocumentUrlSegments>();
|
||||
var cacheModels = new Dictionary<(Guid DocumentKey, int LanguageId, bool IsDraft), PublishedDocumentUrlSegments>();
|
||||
|
||||
foreach (PublishedDocumentUrlSegment model in publishedDocumentUrlSegments)
|
||||
{
|
||||
PublishedDocumentUrlSegments? existingCacheModel = GetModelFromCache(cacheModels, model);
|
||||
if (existingCacheModel is null)
|
||||
(Guid DocumentKey, int LanguageId, bool IsDraft) key = (model.DocumentKey, model.LanguageId, model.IsDraft);
|
||||
|
||||
if (!cacheModels.TryGetValue(key, out PublishedDocumentUrlSegments? existingCacheModel))
|
||||
{
|
||||
cacheModels.Add(new PublishedDocumentUrlSegments
|
||||
cacheModels[key] = new PublishedDocumentUrlSegments
|
||||
{
|
||||
DocumentKey = model.DocumentKey,
|
||||
LanguageId = model.LanguageId,
|
||||
UrlSegments = [new PublishedDocumentUrlSegments.UrlSegment(model.UrlSegment, model.IsPrimary)],
|
||||
IsDraft = model.IsDraft,
|
||||
});
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
existingCacheModel.UrlSegments = GetUpdatedUrlSegments(existingCacheModel.UrlSegments, model.UrlSegment, model.IsPrimary);
|
||||
if (existingCacheModel.UrlSegments.Any(x => x.Segment == model.UrlSegment) is false)
|
||||
{
|
||||
existingCacheModel.UrlSegments.Add(new PublishedDocumentUrlSegments.UrlSegment(model.UrlSegment, model.IsPrimary));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cacheModels;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static PublishedDocumentUrlSegments? GetModelFromCache(List<PublishedDocumentUrlSegments> cacheModels, PublishedDocumentUrlSegment model)
|
||||
=> cacheModels
|
||||
.SingleOrDefault(x => x.DocumentKey == model.DocumentKey && x.LanguageId == model.LanguageId && x.IsDraft == model.IsDraft);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static IList<PublishedDocumentUrlSegments.UrlSegment> GetUpdatedUrlSegments(IList<PublishedDocumentUrlSegments.UrlSegment> urlSegments, string segment, bool isPrimary)
|
||||
{
|
||||
if (urlSegments.FirstOrDefault(x => x.Segment == segment) is null)
|
||||
{
|
||||
urlSegments.Add(new PublishedDocumentUrlSegments.UrlSegment(segment, isPrimary));
|
||||
}
|
||||
|
||||
return urlSegments;
|
||||
return cacheModels.Values;
|
||||
}
|
||||
|
||||
private void RemoveFromCache(IScopeContext scopeContext, Guid documentKey, string isoCode, bool isDraft)
|
||||
|
||||
@@ -99,17 +99,17 @@ public abstract class BlockValuePropertyValueEditorBase<TValue, TLayout> : DataV
|
||||
continue;
|
||||
}
|
||||
|
||||
var districtValues = valuesByPropertyEditorAlias.Distinct().ToArray();
|
||||
var distinctValues = valuesByPropertyEditorAlias.Distinct().ToArray();
|
||||
|
||||
if (dataEditor.GetValueEditor() is IDataValueReference reference)
|
||||
{
|
||||
foreach (UmbracoEntityReference value in districtValues.SelectMany(reference.GetReferences))
|
||||
foreach (UmbracoEntityReference value in distinctValues.SelectMany(reference.GetReferences))
|
||||
{
|
||||
result.Add(value);
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerable<UmbracoEntityReference> references = _dataValueReferenceFactoryCollection.GetReferences(dataEditor, districtValues);
|
||||
IEnumerable<UmbracoEntityReference> references = _dataValueReferenceFactoryCollection.GetReferences(dataEditor, distinctValues);
|
||||
|
||||
foreach (UmbracoEntityReference value in references)
|
||||
{
|
||||
|
||||
@@ -126,6 +126,7 @@ export class UmbDropzoneMediaElement extends UmbInputDropzoneElement {
|
||||
z-index: 100;
|
||||
border-radius: var(--uui-border-radius);
|
||||
border: 1px solid var(--uui-color-focus);
|
||||
box-sizing:border-box;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
+5
-4
@@ -8,7 +8,7 @@
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@umbraco/json-models-builders": "^2.0.33",
|
||||
"@umbraco/playwright-testhelpers": "^15.0.49",
|
||||
"@umbraco/playwright-testhelpers": "^15.0.56",
|
||||
"camelize": "^1.0.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"node-fetch": "^2.6.7"
|
||||
@@ -66,9 +66,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@umbraco/playwright-testhelpers": {
|
||||
"version": "15.0.49",
|
||||
"resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.49.tgz",
|
||||
"integrity": "sha512-1At/e057u6rB3T3iH8tR6SLXnYRZJsCVjmm8jm+6sftJDvgB0Q5kXKaSDyLTU6wVuLALiDNUuNuJ86FgOOdUJw==",
|
||||
"version": "15.0.56",
|
||||
"resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.56.tgz",
|
||||
"integrity": "sha512-QPLNLnS96QvkCPpumpOwn9ufgIWgsv4W0UQENTU63pMniHPYfaflFMafI4qjM/euwMyXHH7k9+c4k/tGew2EQA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@umbraco/json-models-builders": "2.0.33",
|
||||
"node-fetch": "^2.6.7"
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@umbraco/json-models-builders": "^2.0.33",
|
||||
"@umbraco/playwright-testhelpers": "^15.0.49",
|
||||
"@umbraco/playwright-testhelpers": "^15.0.56",
|
||||
"camelize": "^1.0.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"node-fetch": "^2.6.7"
|
||||
|
||||
@@ -43,14 +43,43 @@ export default defineConfig({
|
||||
testMatch: '**/*.setup.ts',
|
||||
},
|
||||
{
|
||||
name: 'chromium',
|
||||
name: 'defaultConfig',
|
||||
testMatch: 'DefaultConfig/**',
|
||||
dependencies: ['setup'],
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
// Use prepared auth state.
|
||||
ignoreHTTPSErrors: true,
|
||||
storageState: STORAGE_STATE,
|
||||
storageState: STORAGE_STATE
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'deliveryApi',
|
||||
testMatch: 'DeliveryApi/**',
|
||||
dependencies: ['setup'],
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
// Use prepared auth state.
|
||||
ignoreHTTPSErrors: true,
|
||||
storageState: STORAGE_STATE
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'externalLoginAzureADB2C',
|
||||
testMatch: 'ExternalLogin/AzureADB2C/**',
|
||||
use: {
|
||||
...devices['Desktop Chrome'],
|
||||
// Use prepared auth state.
|
||||
ignoreHTTPSErrors: true,
|
||||
}
|
||||
},
|
||||
// This project is used to test the install steps, for that we do not need to authenticate.
|
||||
{
|
||||
name: 'unattendedInstallConfig',
|
||||
testMatch: 'UnattendedInstallConfig/**',
|
||||
use: {
|
||||
...devices['Desktop Chrome']
|
||||
}
|
||||
}
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,105 +0,0 @@
|
||||
import {test} from "@umbraco/playwright-testhelpers";
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('DataType tests', () => {
|
||||
let dataTypeId = '';
|
||||
let dataTypeFolderId = '';
|
||||
let copiedDataTypeId = '';
|
||||
|
||||
const dataTypeName = 'TestDataType';
|
||||
const folderName = 'TestDataTypeFolder';
|
||||
const editorAlias = 'Umbraco.DateTime';
|
||||
const editorUiAlias = 'Umb.PropertyEditorUi.DatePicker';
|
||||
const dataTypeData = [
|
||||
{
|
||||
"alias": "tester",
|
||||
"value": "Howdy"
|
||||
}
|
||||
];
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.dataType.ensureNameNotExists(dataTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.dataType.ensureNameNotExists(dataTypeName);
|
||||
if (dataTypeFolderId != '') {
|
||||
await umbracoApi.dataType.ensureNameNotExists(folderName);
|
||||
}
|
||||
});
|
||||
|
||||
test('can create dataType', async ({umbracoApi}) => {
|
||||
// Act
|
||||
dataTypeId = await umbracoApi.dataType.create(dataTypeName, editorAlias, editorUiAlias, dataTypeData);
|
||||
|
||||
// Assert
|
||||
expect(umbracoApi.dataType.doesExist(dataTypeId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update dataType', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
dataTypeId = await umbracoApi.dataType.create(dataTypeName, editorAlias, editorUiAlias, []);
|
||||
const dataType = await umbracoApi.dataType.get(dataTypeId);
|
||||
dataType.values = dataTypeData;
|
||||
|
||||
// Act
|
||||
await umbracoApi.dataType.update(dataTypeId, dataType);
|
||||
|
||||
// Assert
|
||||
// Checks if the data type was updated
|
||||
const updatedDataType = await umbracoApi.dataType.get(dataTypeId);
|
||||
expect(updatedDataType.values).toEqual(dataTypeData);
|
||||
});
|
||||
|
||||
test('can delete dataType', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
dataTypeId = await umbracoApi.dataType.create(dataTypeName, editorAlias, editorUiAlias, dataTypeData);
|
||||
expect(await umbracoApi.dataType.doesExist(dataTypeId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.dataType.delete(dataTypeId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.dataType.doesExist(dataTypeId)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can move a dataType to a folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.dataType.ensureNameNotExists(folderName);
|
||||
dataTypeId = await umbracoApi.dataType.create(dataTypeName, editorAlias, editorUiAlias, dataTypeData);
|
||||
expect(await umbracoApi.dataType.doesNameExist(dataTypeName)).toBeTruthy();
|
||||
dataTypeFolderId = await umbracoApi.dataType.createFolder(folderName);
|
||||
expect(await umbracoApi.dataType.doesFolderExist(dataTypeFolderId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.dataType.moveToFolder(dataTypeId, dataTypeFolderId);
|
||||
|
||||
// Assert
|
||||
// Checks if the datatype has the parentId of the folder
|
||||
const dataTypeInFolder = await umbracoApi.dataType.getChildren(dataTypeFolderId);
|
||||
expect(dataTypeInFolder[0].parent.id).toEqual(dataTypeFolderId);
|
||||
});
|
||||
|
||||
test('can copy a dataType to a folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.dataType.ensureNameNotExists(folderName);
|
||||
dataTypeId = await umbracoApi.dataType.create(dataTypeName, editorAlias, editorUiAlias, dataTypeData);
|
||||
dataTypeFolderId = await umbracoApi.dataType.createFolder(folderName);
|
||||
|
||||
const dataType = await umbracoApi.dataType.get(dataTypeId);
|
||||
const dataTypeFolder = await umbracoApi.dataType.getFolder(dataTypeFolderId);
|
||||
|
||||
// Act
|
||||
copiedDataTypeId = await umbracoApi.dataType.copyToFolder(dataType.id, dataTypeFolder.id);
|
||||
|
||||
// Assert
|
||||
const copiedDataType = await umbracoApi.dataType.get(copiedDataTypeId);
|
||||
expect(copiedDataType.name).toEqual(dataTypeName + ' (copy)');
|
||||
// Checks if both dataTypes exists
|
||||
expect(await umbracoApi.dataType.doesExist(dataTypeId)).toBeTruthy();
|
||||
expect(await umbracoApi.dataType.doesExist(copiedDataTypeId)).toBeTruthy();
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.delete(copiedDataTypeId);
|
||||
});
|
||||
});
|
||||
@@ -1,50 +0,0 @@
|
||||
import {test} from "@umbraco/playwright-testhelpers";
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('DataTypeFolder tests', () => {
|
||||
let dataTypeFolderId = '';
|
||||
const dataTypeFolderName = 'TestDataTypeFolder';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.dataType.ensureNameNotExists(dataTypeFolderName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.dataType.ensureNameNotExists(dataTypeFolderName);
|
||||
});
|
||||
|
||||
test('can create a dataType folder', async ({umbracoApi}) => {
|
||||
// Act
|
||||
dataTypeFolderId = await umbracoApi.dataType.createFolder(dataTypeFolderName);
|
||||
|
||||
// Assert
|
||||
expect(umbracoApi.dataType.doesFolderExist(dataTypeFolderId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can rename a dataType folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongDataTypeFolderName = 'WrongFolderName';
|
||||
dataTypeFolderId = await umbracoApi.dataType.createFolder(wrongDataTypeFolderName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.dataType.renameFolder(dataTypeFolderId, dataTypeFolderName);
|
||||
|
||||
// Assert
|
||||
expect(umbracoApi.dataType.doesFolderExist(dataTypeFolderId)).toBeTruthy();
|
||||
// Checks if the dataType folder was updated
|
||||
const newDataTypeFolderName = await umbracoApi.dataType.getFolder(dataTypeFolderId);
|
||||
expect(newDataTypeFolderName.name).toEqual(dataTypeFolderName);
|
||||
});
|
||||
|
||||
test('can delete a dataType folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.dataType.createFolder(dataTypeFolderName);
|
||||
expect(umbracoApi.dataType.doesFolderExist(dataTypeFolderId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.dataType.delete(dataTypeFolderId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.dataType.doesFolderExist(dataTypeFolderId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,106 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
test.describe('Dictionary tests', () => {
|
||||
let dictionaryId = '';
|
||||
const dictionaryName = 'TestDictionary';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.dictionary.ensureNameNotExists(dictionaryName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.dictionary.ensureNameNotExists(dictionaryName);
|
||||
});
|
||||
|
||||
test('can create a dictionary', async ({umbracoApi}) => {
|
||||
// Act
|
||||
dictionaryId = await umbracoApi.dictionary.createDefaultDictionary(dictionaryName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.dictionary.doesExist(dictionaryId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a dictionary', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongDictionaryName = 'WrongTestDictionary';
|
||||
dictionaryId = await umbracoApi.dictionary.createDefaultDictionary(wrongDictionaryName);
|
||||
expect(await umbracoApi.dictionary.doesNameExist(wrongDictionaryName)).toBeTruthy();
|
||||
const dictionary = await umbracoApi.dictionary.get(dictionaryId);
|
||||
|
||||
// Act
|
||||
dictionary.name = dictionaryName;
|
||||
await umbracoApi.dictionary.update(dictionaryId, dictionary);
|
||||
|
||||
// Assert
|
||||
// Checks if the dictionary was updated
|
||||
const newDictionary = await umbracoApi.dictionary.get(dictionaryId);
|
||||
expect(newDictionary.name).toEqual(dictionaryName);
|
||||
expect(await umbracoApi.dictionary.doesExist(dictionaryId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete a dictionary', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
dictionaryId = await umbracoApi.dictionary.create(dictionaryName);
|
||||
expect(await umbracoApi.dictionary.doesExist(dictionaryId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.dictionary.delete(dictionaryId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.dictionary.doesExist(dictionaryId)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can create a dictionary item in a dictionary', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childDictionaryName = 'ChildDictionary';
|
||||
await umbracoApi.dictionary.ensureNameNotExists(dictionaryName);
|
||||
dictionaryId = await umbracoApi.dictionary.create(dictionaryName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.dictionary.create(childDictionaryName, [], dictionaryId);
|
||||
|
||||
// Assert
|
||||
// Checks if the parent dictionary contains the child dictionary
|
||||
const dictionaryChildren = await umbracoApi.dictionary.getChildren(dictionaryId);
|
||||
expect(dictionaryChildren[0].name).toEqual(childDictionaryName);
|
||||
});
|
||||
|
||||
test('can export a dictionary', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
dictionaryId = await umbracoApi.dictionary.create(dictionaryName);
|
||||
expect(await umbracoApi.dictionary.doesExist(dictionaryId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
const exportResponse = await umbracoApi.dictionary.export(dictionaryId, false);
|
||||
|
||||
// Assert
|
||||
// Checks if the .udt file is exported
|
||||
expect(exportResponse.headers()['content-disposition']).toContain(".udt");
|
||||
});
|
||||
|
||||
test('can import a dictionary', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const temporaryFileId = crypto.randomUUID();
|
||||
const fileName = 'TestSingleDictionary.udt';
|
||||
const mimeType = 'application/octet-stream';
|
||||
const filePath = './fixtures/dictionary/TestSingleDictionary.udt';
|
||||
// This variable must not be changed as it is declared in the file TestDictionary.udt
|
||||
const importDictionaryName = 'TestImportDictionary';
|
||||
|
||||
// Create temporary file
|
||||
await umbracoApi.temporaryFile.create(temporaryFileId, fileName, mimeType, filePath);
|
||||
expect(await umbracoApi.temporaryFile.doesExist(temporaryFileId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
const importResponse = await umbracoApi.dictionary.import(temporaryFileId, null);
|
||||
|
||||
// Assert
|
||||
expect(importResponse.status).toBeTruthy();
|
||||
expect(await umbracoApi.dictionary.doesNameExist(importDictionaryName)).toBeTruthy();
|
||||
|
||||
// Clean
|
||||
await umbracoApi.temporaryFile.delete(temporaryFileId);
|
||||
});
|
||||
});
|
||||
@@ -1,55 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Documents tests', () => {
|
||||
let documentTypeId = '';
|
||||
let documentId = '';
|
||||
const documentName = 'TestDocument';
|
||||
const documentTypeName = 'TestDocumentType';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
documentTypeId = await umbracoApi.documentType.createDefaultDocumentTypeWithAllowAsRoot(documentTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(documentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
});
|
||||
|
||||
test('can create a document', async ({umbracoApi}) => {
|
||||
// Act
|
||||
await umbracoApi.document.createDefaultDocument(documentName, documentTypeId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.document.doesNameExist(documentName)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete a document', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
documentId = await umbracoApi.document.createDefaultDocument(documentName, documentTypeId);
|
||||
expect(umbracoApi.document.doesExist(documentId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.document.delete(documentId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.document.doesNameExist(documentName)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can update a document', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongName = 'WrongDocument';
|
||||
documentId = await umbracoApi.document.createDefaultDocument(wrongName, documentTypeId);
|
||||
expect(await umbracoApi.document.doesNameExist(wrongName)).toBeTruthy();
|
||||
let documentData = await umbracoApi.document.get(documentId);
|
||||
documentData.variants[0].name = documentName;
|
||||
|
||||
// Act
|
||||
await umbracoApi.document.update(documentData.id, documentData);
|
||||
|
||||
// Assert
|
||||
const updatedDocumentData = await umbracoApi.document.get(documentId);
|
||||
expect(updatedDocumentData.variants[0].name).toEqual(documentName);
|
||||
});
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Language tests', () => {
|
||||
const languageNameDanish = 'Dansk';
|
||||
const isoCodeDanish = 'da-DK';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.language.ensureNameNotExists(languageNameDanish);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.language.ensureNameNotExists(languageNameDanish);
|
||||
});
|
||||
|
||||
test('can create a language', async ({umbracoApi}) => {
|
||||
// Act
|
||||
await umbracoApi.language.create(languageNameDanish, false, false, isoCodeDanish);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.language.doesExist(isoCodeDanish)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a language', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongLanguageName = 'densk';
|
||||
await umbracoApi.language.create(wrongLanguageName, false, false, isoCodeDanish);
|
||||
const language = await umbracoApi.language.get(isoCodeDanish);
|
||||
|
||||
// Act
|
||||
language.name = languageNameDanish;
|
||||
await umbracoApi.language.update(isoCodeDanish, language);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.language.doesExist(isoCodeDanish)).toBeTruthy();
|
||||
// Checks if the language name was updated
|
||||
const updatedLanguage = await umbracoApi.language.get(isoCodeDanish);
|
||||
expect(updatedLanguage.name).toEqual(languageNameDanish);
|
||||
});
|
||||
|
||||
test('can delete a language', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.language.create(languageNameDanish, false, false, isoCodeDanish);
|
||||
expect(await umbracoApi.language.doesExist(isoCodeDanish)).toBeTruthy();
|
||||
|
||||
//Act
|
||||
await umbracoApi.language.delete(isoCodeDanish);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.language.doesExist(isoCodeDanish)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,45 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Member tests', () => {
|
||||
let memberId = '';
|
||||
let memberTypeId = '';
|
||||
const memberName = 'TestMember';
|
||||
const memberTypeName = 'TestMemberType';
|
||||
const username = 'testmember';
|
||||
const email = 'testmember@acceptance.test';
|
||||
const password = '0123456789';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.memberType.ensureNameNotExists(memberTypeName);
|
||||
await umbracoApi.member.ensureNameNotExists(memberName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.memberType.ensureNameNotExists(memberTypeName);
|
||||
await umbracoApi.member.ensureNameNotExists(memberName);
|
||||
});
|
||||
|
||||
test('can create a member', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName);
|
||||
|
||||
// Act
|
||||
memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.member.doesExist(memberId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete a member', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
memberTypeId = await umbracoApi.memberType.createDefaultMemberType(memberTypeName);
|
||||
memberId = await umbracoApi.member.createDefaultMember(memberName, memberTypeId, email, username, password);
|
||||
|
||||
// Act
|
||||
await umbracoApi.member.delete(memberId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.member.doesExist(memberId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,50 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Member Group tests', () => {
|
||||
let memberGroupId = '';
|
||||
const memberGroupName = 'TestMemberGroup';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.memberGroup.ensureNameNotExists(memberGroupName);
|
||||
});
|
||||
|
||||
test('can create a member group', async ({umbracoApi}) => {
|
||||
// Act
|
||||
memberGroupId = await umbracoApi.memberGroup.create(memberGroupName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can rename a member group', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongMemberGroupName = 'Wrong Name';
|
||||
await umbracoApi.memberGroup.ensureNameNotExists(wrongMemberGroupName);
|
||||
memberGroupId = await umbracoApi.memberGroup.create(wrongMemberGroupName);
|
||||
expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.memberGroup.rename(memberGroupId, memberGroupName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.memberGroup.doesNameExist(memberGroupName)).toBeTruthy();
|
||||
expect(await umbracoApi.memberGroup.doesNameExist(wrongMemberGroupName)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can delete a member group', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
memberGroupId = await umbracoApi.memberGroup.create(memberGroupName);
|
||||
expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.memberGroup.delete(memberGroupId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.memberGroup.doesExist(memberGroupId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,50 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from '@playwright/test';
|
||||
|
||||
test.describe('Package tests', () => {
|
||||
let packageId = '';
|
||||
const packageName = 'TestName';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.package.ensureNameNotExists(packageName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.package.delete(packageId);
|
||||
});
|
||||
|
||||
test('can create a package', async ({umbracoApi}) => {
|
||||
// Act
|
||||
packageId = await umbracoApi.package.create(packageName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.package.doesExist(packageId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a package', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongPackageName = 'WrongName';
|
||||
await umbracoApi.package.ensureNameNotExists(wrongPackageName);
|
||||
|
||||
// Act
|
||||
packageId = await umbracoApi.package.create(wrongPackageName);
|
||||
const packageData = await umbracoApi.package.get(packageId);
|
||||
packageData.name = packageName;
|
||||
await umbracoApi.package.update(packageId, packageData);
|
||||
|
||||
// Assert
|
||||
const updatedPackageData = await umbracoApi.package.get(packageId);
|
||||
expect(updatedPackageData.name).toEqual(packageName);
|
||||
});
|
||||
|
||||
test('can delete a package', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
packageId = await umbracoApi.package.create(packageName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.package.delete(packageId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.package.doesExist(packageId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Partial View tests', () => {
|
||||
let partialViewPath = '';
|
||||
const partialViewName = 'partialViewName.cshtml';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.partialView.ensureNameNotExists(partialViewName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.partialView.ensureNameNotExists(partialViewName);
|
||||
});
|
||||
|
||||
test('can create a partial view', async ({umbracoApi}) => {
|
||||
// Act
|
||||
partialViewPath = await umbracoApi.partialView.create(partialViewName, 'test');
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.partialView.doesExist(partialViewPath)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a partial view', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const newContent = 'Howdy';
|
||||
partialViewPath = await umbracoApi.partialView.create(partialViewName, 'test');
|
||||
|
||||
// Act
|
||||
await umbracoApi.partialView.updateContent(partialViewPath, newContent);
|
||||
|
||||
// Assert
|
||||
const updatedPartialView = await umbracoApi.partialView.get(partialViewPath);
|
||||
expect(updatedPartialView.content).toEqual(newContent);
|
||||
});
|
||||
|
||||
test('can rename a partial view', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongPartialViewName = 'wrongPartialViewName.cshtml';
|
||||
const wrongPartialViewPath = await umbracoApi.partialView.create(wrongPartialViewName, 'test');
|
||||
|
||||
// Act
|
||||
const updatedPartialViewPath = await umbracoApi.partialView.updateName(wrongPartialViewPath, partialViewName);
|
||||
|
||||
// Assert
|
||||
const updatedPartialView = await umbracoApi.partialView.get(updatedPartialViewPath);
|
||||
expect(updatedPartialView.name).toEqual(partialViewName);
|
||||
});
|
||||
|
||||
test('can delete a partial view', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
partialViewPath = await umbracoApi.partialView.create(partialViewName, 'test');
|
||||
expect(await umbracoApi.partialView.doesExist(partialViewPath)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.partialView.delete(partialViewPath);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.partialView.doesExist(partialViewPath)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Partial View Folder tests', () => {
|
||||
let partialViewFolderPath = '';
|
||||
const partialViewFolderName = 'partialViewFolder';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.partialView.ensureNameNotExists(partialViewFolderName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.partialView.ensureNameNotExists(partialViewFolderName);
|
||||
});
|
||||
|
||||
test('can create a partial view folder', async ({umbracoApi}) => {
|
||||
// Act
|
||||
partialViewFolderPath = await umbracoApi.partialView.createFolder(partialViewFolderName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.partialView.doesFolderExist(partialViewFolderPath)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete a partial view folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
partialViewFolderPath = await umbracoApi.partialView.createFolder(partialViewFolderName);
|
||||
expect(await umbracoApi.partialView.doesFolderExist(partialViewFolderPath)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.partialView.deleteFolder(partialViewFolderPath);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.partialView.doesFolderExist(partialViewFolderPath)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can add a partial view folder in another', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
partialViewFolderPath = await umbracoApi.partialView.createFolder(partialViewFolderName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.partialView.createFolder(childFolderName, partialViewFolderPath);
|
||||
|
||||
// Assert
|
||||
const childrenData = await umbracoApi.partialView.getChildren(partialViewFolderPath);
|
||||
expect(childrenData[0].name).toEqual(childFolderName);
|
||||
});
|
||||
|
||||
test('can add a partial view folder in a folder in another folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
const childOfChildFolderName = 'childOfChildFolder';
|
||||
|
||||
// Creates parent folder
|
||||
partialViewFolderPath = await umbracoApi.partialView.createFolder(partialViewFolderName);
|
||||
|
||||
// Creates child folder in parent folder
|
||||
const childFolderPath = await umbracoApi.partialView.createFolder(childFolderName, partialViewFolderPath);
|
||||
|
||||
// Act
|
||||
// Creates childOfChild folder in child folder
|
||||
await umbracoApi.partialView.createFolder(childOfChildFolderName, childFolderPath);
|
||||
|
||||
// Assert
|
||||
// Checks if the partial views folder are in the correct folders
|
||||
const childOfParentData = await umbracoApi.partialView.getChildren(partialViewFolderPath);
|
||||
expect(childOfParentData[0].name).toEqual(childFolderName);
|
||||
const childOfChildData = await umbracoApi.partialView.getChildren(childFolderPath);
|
||||
expect(childOfChildData[0].name).toEqual(childOfChildFolderName);
|
||||
});
|
||||
});
|
||||
@@ -1,58 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Relation type tests', () => {
|
||||
const relationTypeName = 'Test Relation Type';
|
||||
const objectTypeName = 'Document';
|
||||
let relationTypeId = '';
|
||||
let objectTypeId = '';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.relationType.ensureNameNotExists(relationTypeName);
|
||||
objectTypeId = await umbracoApi.objectTypes.getIdByName(objectTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.relationType.ensureNameNotExists(relationTypeName);
|
||||
});
|
||||
|
||||
// Skip this test because there is currently no endpoint available for creating a relation type anymore.
|
||||
test.skip('can create a relation type', async ({umbracoApi}) => {
|
||||
// Act
|
||||
relationTypeId = await umbracoApi.relationType.create(relationTypeName, false, false, objectTypeId, objectTypeId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.relationType.doesExist(relationTypeId)).toBeTruthy();
|
||||
});
|
||||
|
||||
// Skip this test because there is currently no endpoint available for updating a relation type anymore.
|
||||
test.skip('can update a relation type', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const wrongRelationTypeName = 'Updated Relation Type';
|
||||
relationTypeId = await umbracoApi.relationType.create(wrongRelationTypeName, false, false, objectTypeId, objectTypeId);
|
||||
const relationTypeData = await umbracoApi.relationType.get(relationTypeId);
|
||||
|
||||
// Act
|
||||
relationTypeData.name = relationTypeName;
|
||||
await umbracoApi.relationType.update(relationTypeId, relationTypeData);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.relationType.doesExist(relationTypeId)).toBeTruthy();
|
||||
// Checks if the relation type name was updated
|
||||
const updatedRelationType = await umbracoApi.relationType.get(relationTypeId);
|
||||
expect(updatedRelationType.name).toEqual(relationTypeName);
|
||||
});
|
||||
|
||||
// Skip this test because there is currently no endpoint available for deleting a relation type anymore.
|
||||
test.skip('can delete a relation type', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
relationTypeId = await umbracoApi.relationType.create(relationTypeName, false, false, objectTypeId, objectTypeId);
|
||||
expect(await umbracoApi.relationType.doesExist(relationTypeId)).toBeTruthy();
|
||||
|
||||
//Act
|
||||
await umbracoApi.relationType.delete(relationTypeId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.relationType.doesExist(relationTypeId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,66 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Script tests', () => {
|
||||
let scriptPath = '';
|
||||
const scriptName = 'scriptName.js';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.script.ensureNameNotExists(scriptName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.script.ensureNameNotExists(scriptName);
|
||||
});
|
||||
|
||||
test('can create a script', async ({umbracoApi}) => {
|
||||
// Act
|
||||
scriptPath = await umbracoApi.script.create(scriptName, 'test');
|
||||
await umbracoApi.script.get(scriptPath);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.script.doesExist(scriptPath)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update script name', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const oldName = 'RandomScriptName.js';
|
||||
await umbracoApi.script.ensureNameNotExists(oldName);
|
||||
const oldScriptPath = await umbracoApi.script.create(oldName, 'test');
|
||||
|
||||
// Act
|
||||
scriptPath = await umbracoApi.script.updateName(oldScriptPath, scriptName);
|
||||
|
||||
// Assert
|
||||
// Checks if the content was updated for the script
|
||||
const updatedScript = await umbracoApi.script.get(scriptPath);
|
||||
expect(updatedScript.name).toEqual(scriptName);
|
||||
});
|
||||
|
||||
test('can update script content', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const newContent = 'BetterContent';
|
||||
scriptPath = await umbracoApi.script.create(scriptName, 'test');
|
||||
await umbracoApi.script.get(scriptPath);
|
||||
|
||||
// Act
|
||||
await umbracoApi.script.updateContent(scriptPath, newContent);
|
||||
|
||||
// Assert
|
||||
// Checks if the content was updated for the script
|
||||
const updatedScript = await umbracoApi.script.get(scriptPath);
|
||||
expect(updatedScript.content).toEqual(newContent);
|
||||
});
|
||||
|
||||
test('can delete a script', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
scriptPath = await umbracoApi.script.create(scriptName, 'test');
|
||||
expect(await umbracoApi.script.doesExist(scriptPath)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.script.delete(scriptPath);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.script.doesExist(scriptPath)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,70 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Script Folder tests', () => {
|
||||
const scriptFolderName = 'ScriptFolder';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.script.ensureNameNotExists(scriptFolderName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.script.ensureNameNotExists(scriptFolderName);
|
||||
});
|
||||
|
||||
test('can create a script folder', async ({umbracoApi}) => {
|
||||
// Act
|
||||
await umbracoApi.script.createFolder(scriptFolderName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.script.doesFolderExist(scriptFolderName)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete a script folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.script.createFolder(scriptFolderName);
|
||||
expect(await umbracoApi.script.doesFolderExist(scriptFolderName)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.script.deleteFolder(scriptFolderName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.script.doesFolderExist(scriptFolderName)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can add a script folder in another folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
await umbracoApi.script.createFolder(scriptFolderName);
|
||||
await umbracoApi.script.createFolder(childFolderName, scriptFolderName);
|
||||
|
||||
// Act
|
||||
const childFolder = await umbracoApi.script.getChildren(scriptFolderName);
|
||||
|
||||
// Assert
|
||||
expect(childFolder[0].name).toEqual(childFolderName);
|
||||
});
|
||||
|
||||
test('can add a script folder in a folder in another folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
const childOfChildFolderName = 'childOfChildFolder';
|
||||
const childFolderPath = scriptFolderName + '/' + childFolderName;
|
||||
|
||||
// Creates parent folder
|
||||
await umbracoApi.script.createFolder(scriptFolderName);
|
||||
// Creates child folder in parent folder
|
||||
await umbracoApi.script.createFolder(childFolderName, scriptFolderName);
|
||||
|
||||
// Act
|
||||
// Creates childOfChild folder in child folder
|
||||
await umbracoApi.script.createFolder(childOfChildFolderName, childFolderPath);
|
||||
|
||||
// Assert
|
||||
// Checks if the script folder are in the correct folders
|
||||
const childOfParent = await umbracoApi.script.getChildren(scriptFolderName);
|
||||
const childOfChild = await umbracoApi.script.getChildren(childFolderPath);
|
||||
expect(childOfParent[0].name).toEqual(childFolderName);
|
||||
expect(childOfChild[0].name).toEqual(childOfChildFolderName);
|
||||
});
|
||||
});
|
||||
@@ -1,98 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Stylesheet tests', () => {
|
||||
const stylesheetName = 'Stylesheet.css';
|
||||
const folderName = 'StyledFolder';
|
||||
let stylesheetPath = '';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(stylesheetName);
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(folderName);
|
||||
});
|
||||
|
||||
test('can create a stylesheet', async ({umbracoApi}) => {
|
||||
// Act
|
||||
stylesheetPath = await umbracoApi.stylesheet.create(stylesheetName, 'content');
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.stylesheet.doesExist(stylesheetPath)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update stylesheet name', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const oldStylesheetName = 'RandomStylesheetName.css';
|
||||
await umbracoApi.script.ensureNameNotExists(oldStylesheetName);
|
||||
const oldScriptPath = await umbracoApi.stylesheet.create(oldStylesheetName, 'content');
|
||||
|
||||
// Act
|
||||
stylesheetPath = await umbracoApi.stylesheet.updateName(oldScriptPath, stylesheetName);
|
||||
|
||||
// Assert
|
||||
// Checks if the name was updated for the stylesheet
|
||||
const updatedStylesheet = await umbracoApi.stylesheet.get(stylesheetPath);
|
||||
expect(updatedStylesheet.name).toEqual(stylesheetName);
|
||||
});
|
||||
|
||||
test('can update stylesheet content', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const newContent = 'BetterContent';
|
||||
stylesheetPath = await umbracoApi.stylesheet.create(stylesheetName, 'content');
|
||||
|
||||
// Act
|
||||
await umbracoApi.stylesheet.updateContent(stylesheetPath, newContent);
|
||||
|
||||
// Assert
|
||||
// Checks if the content was updated for the stylesheet
|
||||
const updatedStylesheet = await umbracoApi.stylesheet.get(stylesheetPath);
|
||||
expect(updatedStylesheet.content).toEqual(newContent);
|
||||
});
|
||||
|
||||
test('can delete a stylesheet', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
stylesheetPath = await umbracoApi.stylesheet.create(stylesheetName, 'content');
|
||||
expect(await umbracoApi.stylesheet.doesExist(stylesheetPath)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.stylesheet.delete(stylesheetName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.stylesheet.doesExist(stylesheetPath)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can create a stylesheet in a folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(folderName);
|
||||
const stylesheetFolderPath = await umbracoApi.stylesheet.createFolder(folderName);
|
||||
|
||||
// Act
|
||||
stylesheetPath = await umbracoApi.stylesheet.create(stylesheetName, 'content', folderName);
|
||||
|
||||
// Assert
|
||||
const child = await umbracoApi.stylesheet.getChildren(stylesheetFolderPath);
|
||||
expect(child[0].name).toEqual(stylesheetName);
|
||||
});
|
||||
|
||||
test('can delete a stylesheet from a folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(folderName);
|
||||
const stylesheetFolderPath = await umbracoApi.stylesheet.createFolder(folderName);
|
||||
stylesheetPath = await umbracoApi.stylesheet.create(stylesheetName, 'deleteMe', folderName);
|
||||
// Checks if the stylesheet was created
|
||||
const child = await umbracoApi.stylesheet.getChildren(stylesheetFolderPath);
|
||||
// Checks if the child is in the folder
|
||||
expect(child[0].name).toEqual(stylesheetName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.stylesheet.delete(stylesheetPath);
|
||||
|
||||
// Assert
|
||||
const noChild = await umbracoApi.stylesheet.getChildren(stylesheetFolderPath);
|
||||
// Checks if the children is empty
|
||||
expect(noChild[0]).toEqual(undefined);
|
||||
});
|
||||
});
|
||||
-88
@@ -1,88 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Stylesheet Folder tests', () => {
|
||||
const stylesheetFolderName = 'StylesheetFolder';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(stylesheetFolderName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.stylesheet.ensureNameNotExists(stylesheetFolderName);
|
||||
});
|
||||
|
||||
test('can create a stylesheet folder', async ({umbracoApi}) => {
|
||||
// Act
|
||||
await umbracoApi.stylesheet.createFolder(stylesheetFolderName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.stylesheet.doesFolderExist(stylesheetFolderName)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete a stylesheet folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.stylesheet.createFolder(stylesheetFolderName);
|
||||
expect(await umbracoApi.stylesheet.doesFolderExist(stylesheetFolderName)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.stylesheet.deleteFolder(stylesheetFolderName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.stylesheet.doesFolderExist(stylesheetFolderName)).toBeFalsy();
|
||||
});
|
||||
|
||||
test('can add a stylesheet folder in another folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
await umbracoApi.stylesheet.createFolder(stylesheetFolderName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.stylesheet.createFolder(childFolderName, stylesheetFolderName);
|
||||
|
||||
// Assert
|
||||
const children = await umbracoApi.stylesheet.getChildren(stylesheetFolderName);
|
||||
expect(children[0].name).toEqual(childFolderName);
|
||||
});
|
||||
|
||||
test('can add a stylesheet folder in a folder in another folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
const childOfChildFolderName = 'childOfChildFolder';
|
||||
const childFolderPath = stylesheetFolderName + '/' + childFolderName;
|
||||
// Creates parent folder
|
||||
await umbracoApi.stylesheet.createFolder(stylesheetFolderName);
|
||||
// Creates child folder in parent folder
|
||||
await umbracoApi.stylesheet.createFolder(childFolderName, stylesheetFolderName);
|
||||
|
||||
// Act
|
||||
// Creates childOfChild folder in child folder
|
||||
await umbracoApi.stylesheet.createFolder(childOfChildFolderName, childFolderPath);
|
||||
|
||||
// Assert
|
||||
// Checks if the stylesheet folder are in the correct folders
|
||||
const childOfParent = await umbracoApi.stylesheet.getChildren(stylesheetFolderName);
|
||||
const childOfChild = await umbracoApi.stylesheet.getChildren(childFolderPath);
|
||||
expect(childOfParent[0].name).toEqual(childFolderName);
|
||||
expect(childOfChild[0].name).toEqual(childOfChildFolderName);
|
||||
});
|
||||
|
||||
test('can delete a stylesheet folder from another folder', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const childFolderName = 'childFolder';
|
||||
const stylesheetParentFolderPath = await umbracoApi.stylesheet.createFolder(stylesheetFolderName);
|
||||
const stylesheetChildFolderPath = await umbracoApi.stylesheet.createFolder(childFolderName, stylesheetFolderName);
|
||||
// Checks if a child exists in the parent folder with the name
|
||||
const child = await umbracoApi.stylesheet.getChildren(stylesheetParentFolderPath);
|
||||
expect(child[0].name).toEqual(childFolderName);
|
||||
expect(child[0].isFolder).toBe(true);
|
||||
expect(await umbracoApi.stylesheet.doesFolderExist(stylesheetChildFolderPath)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.stylesheet.deleteFolder(stylesheetChildFolderPath);
|
||||
|
||||
// Assert
|
||||
const noChild = await umbracoApi.stylesheet.getChildren(stylesheetParentFolderPath);
|
||||
expect(noChild[0]).toBe(undefined);
|
||||
});
|
||||
});
|
||||
@@ -1,54 +0,0 @@
|
||||
import {AliasHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('Template tests', () => {
|
||||
let templateId = '';
|
||||
const templateName = 'TemplateTester';
|
||||
const templateAlias = AliasHelper.toAlias(templateName);
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.template.ensureNameNotExists(templateName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.template.ensureNameNotExists(templateName);
|
||||
})
|
||||
|
||||
test('can create a template', async ({umbracoApi}) => {
|
||||
// Act
|
||||
templateId = await umbracoApi.template.create(templateName, templateAlias, 'Template Stuff');
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.template.doesExist(templateId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a template', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const newTemplateAlias = 'betterAlias';
|
||||
templateId = await umbracoApi.template.create(templateName, templateAlias, 'Template Stuff');
|
||||
const templateData = await umbracoApi.template.get(templateId);
|
||||
|
||||
// Act
|
||||
// Updates the template
|
||||
templateData.alias = newTemplateAlias;
|
||||
await umbracoApi.template.update(templateId, templateData);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.template.doesExist(templateId)).toBeTruthy();
|
||||
// Checks if the template alias was updated
|
||||
const updatedTemplate = await umbracoApi.template.get(templateId);
|
||||
expect(updatedTemplate.alias).toEqual(newTemplateAlias);
|
||||
});
|
||||
|
||||
test('can delete template', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
templateId = await umbracoApi.template.create(templateName, templateAlias, 'More Template Stuff');
|
||||
expect(await umbracoApi.template.doesExist(templateId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.template.delete(templateId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.template.doesExist(templateId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
import {test} from "@umbraco/playwright-testhelpers";
|
||||
import {expect} from "@playwright/test";
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
test.describe('Temporary File tests', () => {
|
||||
const temporaryFileId = crypto.randomUUID();
|
||||
const fileName = 'Umbraco.png';
|
||||
const mimeType = 'image/png';
|
||||
const filePath = './fixtures/mediaLibrary/Umbraco.png';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.temporaryFile.delete(temporaryFileId);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.temporaryFile.delete(temporaryFileId);
|
||||
});
|
||||
|
||||
test('can create temporary file', async ({umbracoApi}) => {
|
||||
// Act
|
||||
await umbracoApi.temporaryFile.create(temporaryFileId, fileName, mimeType, filePath);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.temporaryFile.doesExist(temporaryFileId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can delete temporary file', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
await umbracoApi.temporaryFile.create(temporaryFileId, fileName, mimeType, filePath);
|
||||
expect(await umbracoApi.temporaryFile.get(temporaryFileId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.temporaryFile.delete(temporaryFileId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.temporaryFile.doesExist(temporaryFileId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,60 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('User Tests', () => {
|
||||
let userId = '';
|
||||
let userGroupId = '';
|
||||
const userEmail = 'user@acceptance.test';
|
||||
const userName = 'UserTests';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.user.ensureNameNotExists(userName);
|
||||
const userGroupData = await umbracoApi.userGroup.getByName('Writers');
|
||||
userGroupId = userGroupData.id;
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.user.ensureNameNotExists(userName);
|
||||
});
|
||||
|
||||
test('can create a user', async ({umbracoApi}) => {
|
||||
// Act
|
||||
userId = await umbracoApi.user.createDefaultUser(userName, userEmail, [userGroupId]);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.user.doesExist(userId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a user', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const anotherUserGroup = await umbracoApi.userGroup.getByName("Translators");
|
||||
userId = await umbracoApi.user.createDefaultUser(userName, userEmail, [userGroupId]);
|
||||
const userData = await umbracoApi.user.get(userId);
|
||||
const newUserGroupData = [
|
||||
userGroupId,
|
||||
anotherUserGroup.id
|
||||
];
|
||||
userData.userGroupIds = newUserGroupData;
|
||||
|
||||
// Act
|
||||
await umbracoApi.user.update(userId, userData);
|
||||
|
||||
// Assert
|
||||
await umbracoApi.user.doesExist(userId);
|
||||
// Checks if the user was updated with another userGroupID
|
||||
const updatedUser = await umbracoApi.user.get(userId);
|
||||
expect(updatedUser.userGroupIds.toString()).toEqual(newUserGroupData.toString());
|
||||
});
|
||||
|
||||
test('can delete a user', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
userId = await umbracoApi.user.createDefaultUser(userName, userEmail, [userGroupId]);
|
||||
expect(await umbracoApi.user.doesExist(userId)).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.user.delete(userId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.user.doesExist(userId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1,61 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
import * as crypto from 'crypto';
|
||||
|
||||
test.describe('User Avatar Tests', () => {
|
||||
// User
|
||||
let userId = '';
|
||||
let userGroupId = '';
|
||||
const userEmail = 'userAvatar@acceptance.test';
|
||||
const userName = 'UserAvatarTests';
|
||||
// Avatar
|
||||
const avatarFileId = crypto.randomUUID();
|
||||
const avatarName = 'Umbraco.png';
|
||||
const mimeType = 'image/png';
|
||||
const avatarFilePath = './fixtures/mediaLibrary/Umbraco.png';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.user.ensureNameNotExists(userName);
|
||||
await umbracoApi.temporaryFile.delete(avatarFileId);
|
||||
const userGroupData = await umbracoApi.userGroup.getByName('Writers');
|
||||
userGroupId = userGroupData.id;
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.user.ensureNameNotExists(userName);
|
||||
await umbracoApi.temporaryFile.delete(avatarFileId);
|
||||
});
|
||||
|
||||
test('can add an avatar to a user', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
userId = await umbracoApi.user.createDefaultUser(userName, userEmail, userGroupId);
|
||||
await umbracoApi.temporaryFile.create(avatarFileId, avatarName, mimeType, avatarFilePath);
|
||||
|
||||
// Act
|
||||
await umbracoApi.user.addAvatar(userId, avatarFileId);
|
||||
|
||||
// Assert
|
||||
// Checks if the avatar was added to the user
|
||||
const userDataWithAvatar = await umbracoApi.user.get(userId);
|
||||
expect(userDataWithAvatar.avatarUrls.length !== 0).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can remove an avatar from a user', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
userId = await umbracoApi.user.createDefaultUser(userName, userEmail, userGroupId);
|
||||
await umbracoApi.temporaryFile.create(avatarFileId, avatarName, mimeType, avatarFilePath);
|
||||
await umbracoApi.user.addAvatar(userId, avatarFileId);
|
||||
|
||||
// Checks if the avatar was added to the user
|
||||
const userDataWithAvatar = await umbracoApi.user.get(userId);
|
||||
expect(userDataWithAvatar.avatarUrls.length !== 0).toBeTruthy();
|
||||
|
||||
// Act
|
||||
await umbracoApi.user.removeAvatar(userId);
|
||||
|
||||
// Assert
|
||||
// Checks if the avatar was removed from the user
|
||||
const userDataWithoutAvatar = await umbracoApi.user.get(userId);
|
||||
expect(userDataWithoutAvatar.avatarUrls.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
@@ -1,48 +0,0 @@
|
||||
import {test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
test.describe('User Group Tests', () => {
|
||||
let userGroupId = '';
|
||||
const userGroupName = 'UserGroupTest';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.userGroup.ensureNameNotExists(userGroupName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.userGroup.delete(userGroupId);
|
||||
});
|
||||
|
||||
test('can create a user group', async ({umbracoApi}) => {
|
||||
// Act
|
||||
userGroupId = await umbracoApi.userGroup.createEmptyUserGroup(userGroupName);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.userGroup.doesExist(userGroupId)).toBeTruthy();
|
||||
});
|
||||
|
||||
test('can update a user group', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
userGroupId = await umbracoApi.userGroup.createEmptyUserGroup('WrongUserGroupName');
|
||||
const userGroupData = await umbracoApi.userGroup.get(userGroupId);
|
||||
userGroupData.name = userGroupName;
|
||||
|
||||
// Act
|
||||
await umbracoApi.userGroup.update(userGroupId, userGroupData);
|
||||
|
||||
// Assert
|
||||
const updatedUserGroupData = await umbracoApi.userGroup.get(userGroupId);
|
||||
expect(updatedUserGroupData.name).toEqual(userGroupName);
|
||||
});
|
||||
|
||||
test('can delete a user group', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
userGroupId = await umbracoApi.userGroup.createEmptyUserGroup(userGroupName);
|
||||
|
||||
// Act
|
||||
await umbracoApi.userGroup.delete(userGroupId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.userGroup.doesExist(userGroupId)).toBeFalsy();
|
||||
});
|
||||
});
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
import {expect} from '@playwright/test';
|
||||
import {ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
|
||||
// DocumentType
|
||||
const documentTypeName = 'TestDocumentType';
|
||||
let documentTypeId = '';
|
||||
const groupName = 'TestGroup';
|
||||
|
||||
// Content
|
||||
const contentName = 'TestContent';
|
||||
let contentId = '';
|
||||
|
||||
// Property Value
|
||||
const wrongPropertyValue = 'This is a test with wrong value**';
|
||||
const correctPropertyValue = 'Test';
|
||||
|
||||
// ElementTypes
|
||||
// TextString Element Type (for Block List)
|
||||
const textStringElementGroupName = 'TextStringElementGroup';
|
||||
const textStringElementTypeName = 'TestElementWithTextString';
|
||||
const textStringElementRegex = '^[a-zA-Z0-9]*$';
|
||||
let textStringElementTypeId = '';
|
||||
// Area Element Type (for Block Grid)
|
||||
const areaElementTypeName = 'TestElementArea';
|
||||
const areaAlias = 'testArea';
|
||||
let areaElementTypeId = '';
|
||||
// Rich Text Editor Element Type (for Block Grid)
|
||||
const richTextEditorElementGroupName = 'RichTextEditorElementGroup';
|
||||
const richTextEditorElementTypeName = 'RichTextEditorTestElement';
|
||||
let richTextEditorElementTypeId = '';
|
||||
// Block List Element Type
|
||||
const blockListElementTypeName = 'BlockListElement';
|
||||
const blockListGroupName = 'BlockListGroup';
|
||||
let blockListElementTypeId = '';
|
||||
|
||||
// DataTypes
|
||||
const blockGridDataTypeName = 'TestBlockGridEditor';
|
||||
const blockListDataTypeName = 'TestBlockListEditor';
|
||||
const textStringElementDataTypeName = 'Textstring';
|
||||
const richTextDataTypeName = 'Rich Text Editor';
|
||||
let blockListDataTypeId = '';
|
||||
let blockGridDataTypeId = '';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(areaElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextEditorElementTypeName);
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(areaElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextEditorElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
});
|
||||
|
||||
test('can update property value nested in a block grid area with an RTE with a block list editor', {tag: '@smoke'}, async ({umbracoApi, umbracoUi}) => {
|
||||
test.slow();
|
||||
// Arrange
|
||||
// ElementType with Textstring And REGEX only accept letters and numbers
|
||||
const textStringElementDataType = await umbracoApi.dataType.getByName(textStringElementDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createElementTypeWithRegexValidation(textStringElementTypeName, textStringElementGroupName, textStringElementDataTypeName, textStringElementDataType.id, textStringElementRegex);
|
||||
// Block List Editor with Textstring
|
||||
blockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(blockListDataTypeName, textStringElementTypeId);
|
||||
// ElementType with Block List Editor
|
||||
blockListElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockListElementTypeName, blockListGroupName, blockListDataTypeName, blockListDataTypeId);
|
||||
// Rich Text Editor in an ElementType, with a Block(Element Type), the block contains a Block List Editor
|
||||
const richTextEditorId = await umbracoApi.dataType.createRichTextEditorWithABlock(richTextDataTypeName, blockListElementTypeId);
|
||||
richTextEditorElementTypeId = await umbracoApi.documentType.createDefaultElementType(richTextEditorElementTypeName, richTextEditorElementGroupName, richTextDataTypeName, richTextEditorId);
|
||||
// ElementType Area that is Empty
|
||||
areaElementTypeId = await umbracoApi.documentType.createEmptyElementType(areaElementTypeName);
|
||||
// Block Grid with 2 blocks, one with RTE and Inline, and one with areas
|
||||
blockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockWithInlineEditingModeAndABlockWithAnArea(blockGridDataTypeName, richTextEditorElementTypeId, true, areaElementTypeId, areaAlias);
|
||||
// Document Type with the following
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockGridDataTypeName, blockGridDataTypeId, groupName);
|
||||
// Creates Content
|
||||
contentId = await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
await umbracoUi.content.clickAddBlockGridElementWithName(areaElementTypeName);
|
||||
await umbracoUi.content.clickSelectBlockElementWithName(areaElementTypeName);
|
||||
await umbracoUi.content.clickAddBlockGridElementWithName(richTextEditorElementTypeName);
|
||||
await umbracoUi.content.clickExactLinkWithName(richTextEditorElementTypeName);
|
||||
await umbracoUi.content.clickInsertBlockButton();
|
||||
await umbracoUi.content.clickExactLinkWithName(blockListElementTypeName);
|
||||
await umbracoUi.content.clickAddBlockGridElementWithName(textStringElementTypeName);
|
||||
await umbracoUi.content.clickExactLinkWithName(textStringElementTypeName);
|
||||
// Enter text in the textstring block that won't match regex
|
||||
await umbracoUi.content.enterPropertyValue(textStringElementDataTypeName, wrongPropertyValue);
|
||||
await umbracoUi.content.clickCreateButtonForModalWithElementTypeNameAndGroupName(textStringElementTypeName, textStringElementGroupName);
|
||||
await umbracoUi.content.clickCreateButtonForModalWithElementTypeNameAndGroupName(blockListElementTypeName, blockListGroupName);
|
||||
await umbracoUi.content.clickCreateButtonForModalWithElementTypeNameAndGroupName(richTextEditorElementTypeName, richTextEditorElementGroupName);
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
// Checks that the error notification is shown since the textstring block has the wrong value
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved, true, true);
|
||||
await umbracoUi.content.doesErrorNotificationHaveText(NotificationConstantHelper.error.documentCouldNotBePublished, true, true);
|
||||
// Updates the textstring block with the correct value
|
||||
await umbracoUi.waitForTimeout(1000);
|
||||
await umbracoUi.content.clickBlockElementWithName(blockListElementTypeName);
|
||||
await umbracoUi.content.clickEditBlockListEntryWithName(textStringElementTypeName);
|
||||
await umbracoUi.content.enterPropertyValue(textStringElementDataTypeName, correctPropertyValue);
|
||||
await umbracoUi.content.clickUpdateButtonForModalWithElementTypeNameAndGroupName(textStringElementTypeName, textStringElementGroupName);
|
||||
await umbracoUi.content.clickUpdateButtonForModalWithElementTypeNameAndGroupName(blockListElementTypeName, blockListGroupName);
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved, true, true);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published, true, true);
|
||||
// Checks if published
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.variants[0].state).toBe('Published');
|
||||
// Checks if the textstring block has the correct value after reloading the page
|
||||
await umbracoUi.reloadPage();
|
||||
// Waits to make sure the page has loaded
|
||||
await umbracoUi.waitForTimeout(2000);
|
||||
await umbracoUi.content.clickBlockElementWithName(blockListElementTypeName);
|
||||
// Needs to wait to make sure it has loaded
|
||||
await umbracoUi.waitForTimeout(2000);
|
||||
await umbracoUi.content.clickEditBlockListEntryWithName(textStringElementTypeName);
|
||||
await umbracoUi.content.doesPropertyContainValue(textStringElementDataTypeName, correctPropertyValue);
|
||||
});
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
import {AliasHelper, ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
// Content Name
|
||||
const contentName = 'ContentName';
|
||||
|
||||
// Document Type
|
||||
const documentTypeName = 'DocumentTypeName';
|
||||
let documentTypeId = null;
|
||||
const documentTypeGroupName = 'DocumentGroup';
|
||||
|
||||
// Block Grid
|
||||
const blockGridDataTypeName = 'BlockGridName';
|
||||
let blockGridDataTypeId = null;
|
||||
|
||||
// Text String
|
||||
const textStringElementTypeName = 'TextStringElementName';
|
||||
let textStringElementTypeId = null;
|
||||
let textStringGroupName = 'TextGroup';
|
||||
const textStringDataTypeName = 'Textstring';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
});
|
||||
|
||||
test('can publish a block grid editor with a rich text editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const richTextEditorValue = 'Hello World';
|
||||
const expectedRichTextEditorOutputValue = '<p>Hello World</p>';
|
||||
const richTextDataTypeName = 'RichTextDataTypeName';
|
||||
const richTextElementTypeName = 'RichTextElementName';
|
||||
const richTextElementGroupName = 'RichTextElementGroupName';
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextElementTypeName);
|
||||
|
||||
const richTextEditorDataTypeId = await umbracoApi.dataType.createDefaultTiptapDataType(richTextDataTypeName);
|
||||
const richTextElementTypeId = await umbracoApi.documentType.createDefaultElementType(richTextElementTypeName, richTextElementGroupName, richTextDataTypeName, richTextEditorDataTypeId);
|
||||
blockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockAndAllowAtRoot(blockGridDataTypeName, richTextElementTypeId, true);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockGridDataTypeName, blockGridDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(richTextElementTypeName, true);
|
||||
await umbracoUi.content.enterRTETipTapEditor(richTextEditorValue);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the RTE is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentValues = documentData.values.find(value => value.alias === AliasHelper.toAlias(blockGridDataTypeName));
|
||||
expect(documentValues.value.contentData[0].values[0].value.markup).toContain(expectedRichTextEditorOutputValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextElementTypeName);
|
||||
});
|
||||
|
||||
test('can publish a block grid editor with a block list editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const textStringValue = 'Hello World';
|
||||
const blockListDataTypeName = 'BlockListName';
|
||||
const blockListElementTypeName = 'BlockListElementName';
|
||||
const blockListElementGroupName = 'BlockListElementGroupName';
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createDefaultElementType(textStringElementTypeName, textStringGroupName, textStringDataTypeName, textStringDataType.id);
|
||||
const blockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(blockListDataTypeName, textStringElementTypeId);
|
||||
const blockListElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockListElementTypeName, blockListElementGroupName, blockListDataTypeName, blockListDataTypeId);
|
||||
blockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockAndAllowAtRoot(blockGridDataTypeName, blockListElementTypeId, true);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockGridDataTypeName, blockGridDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(blockListElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(textStringElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(textStringElementTypeName, true);
|
||||
await umbracoUi.content.enterTextstring(textStringValue);
|
||||
await umbracoUi.content.clickCreateForModalWithHeadline('Add ' + textStringElementTypeName);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the BlockList is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentValues = documentData.values.find(value => value.alias === AliasHelper.toAlias(blockGridDataTypeName));
|
||||
expect(documentValues.value.contentData[0].values[0].value.contentData[0].values[0].value).toContain(textStringValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
});
|
||||
|
||||
test('can publish a block grid editor with a block grid editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const textStringValue = 'Hello World';
|
||||
const secondBlockGridDataTypeName = 'SecondBlockGridDataTypeName';
|
||||
const blockGridElementTypeName = 'BlockGridElementTypeName';
|
||||
const blockGridElementGroupName = 'BlockGridElementGroupName';
|
||||
await umbracoApi.dataType.ensureNameNotExists(secondBlockGridDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockGridElementTypeName);
|
||||
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createDefaultElementType(textStringElementTypeName, textStringGroupName, textStringDataTypeName, textStringDataType.id);
|
||||
const secondBlockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockAndAllowAtRoot(secondBlockGridDataTypeName, textStringElementTypeId);
|
||||
const blockGridElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockGridElementTypeName, blockGridElementGroupName, secondBlockGridDataTypeName, secondBlockGridDataTypeId);
|
||||
blockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockAndAllowAtRoot(blockGridDataTypeName, blockGridElementTypeId, true);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockGridDataTypeName, blockGridDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(blockGridElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(textStringElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(textStringElementTypeName, true);
|
||||
await umbracoUi.content.enterTextstring(textStringValue);
|
||||
await umbracoUi.content.clickCreateForModalWithHeadline('Add ' + textStringElementTypeName);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the BlockGrid is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentValues = documentData.values.find(value => value.alias === AliasHelper.toAlias(blockGridDataTypeName));
|
||||
expect(documentValues.value.contentData[0].values[0].value.contentData[0].values[0].value).toContain(textStringValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(secondBlockGridDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockGridElementTypeName);
|
||||
});
|
||||
+161
@@ -0,0 +1,161 @@
|
||||
import {AliasHelper, ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
// Content Name
|
||||
const contentName = 'ContentName';
|
||||
|
||||
// Document Type
|
||||
const documentTypeName = 'DocumentTypeName';
|
||||
let documentTypeId = null;
|
||||
const documentTypeGroupName = 'DocumentGroup';
|
||||
|
||||
// Block List
|
||||
const blockListDataTypeName = 'BlockListName';
|
||||
let blockListDataTypeId = null;
|
||||
|
||||
// Text String
|
||||
const textStringElementTypeName = 'TextStringElementName';
|
||||
let textStringElementTypeId = null;
|
||||
let textStringGroupName = 'TextGroup';
|
||||
const textStringDataTypeName = 'Textstring';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
});
|
||||
|
||||
test('can publish a block list editor with a rich text editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const richTextEditorValue = 'Hello World';
|
||||
const expectedRichTextEditorOutputValue = '<p>Hello World</p>';
|
||||
const richTextDataTypeName = 'RichTextName';
|
||||
const richTextElementTypeName = 'RichTextElementName';
|
||||
const richTextElementGroupName = 'RTEElementGroup';
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextElementTypeName);
|
||||
|
||||
const richTextEditorDataTypeId = await umbracoApi.dataType.createDefaultTiptapDataType(richTextDataTypeName);
|
||||
const richTextElementTypeId = await umbracoApi.documentType.createDefaultElementType(richTextElementTypeName, richTextElementGroupName, richTextDataTypeName, richTextEditorDataTypeId);
|
||||
blockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(blockListDataTypeName, richTextElementTypeId);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockListDataTypeName, blockListDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(richTextElementTypeName, true);
|
||||
await umbracoUi.content.enterRTETipTapEditor(richTextEditorValue);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the RTE is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentRichTextValues = documentData.values[0].value.contentData[0].values.find(value => value.alias === AliasHelper.toAlias(richTextDataTypeName));
|
||||
expect(documentRichTextValues.value.markup).toContain(expectedRichTextEditorOutputValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextElementTypeName);
|
||||
});
|
||||
|
||||
test('can publish a block list editor with a block grid editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const textStringValue = 'Hello World';
|
||||
const blockGridDataTypeName = 'BlockGridDataTypeName';
|
||||
const blockGridElementTypeName = 'BlockGridElementName';
|
||||
const blockGridElementGroupName = 'GridElementGroup';
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockGridElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createDefaultElementType(textStringElementTypeName, textStringGroupName, textStringDataTypeName, textStringDataType.id);
|
||||
const blockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockAndAllowAtRoot(blockGridDataTypeName, textStringElementTypeId);
|
||||
const blockGridElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockGridElementTypeName, blockGridElementGroupName, blockGridDataTypeName, blockGridDataTypeId);
|
||||
blockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(blockListDataTypeName, blockGridElementTypeId);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockListDataTypeName, blockListDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(blockGridElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(textStringElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(textStringElementTypeName, true);
|
||||
await umbracoUi.content.enterTextstring(textStringValue);
|
||||
await umbracoUi.content.clickCreateForModalWithHeadline('Add ' + textStringElementTypeName);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the BlockGrid is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentValues = documentData.values.find(value => value.alias === AliasHelper.toAlias(blockListDataTypeName));
|
||||
expect(documentValues.value.contentData[0].values[0].value.contentData[0].values[0].value).toContain(textStringValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockGridElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeId);
|
||||
});
|
||||
|
||||
test('can publish a block list editor with a block list editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const textStringValue = 'Hello World';
|
||||
const secondBlockListDataTypeName = 'SecondBlockListName';
|
||||
const blockListElementTypeName = 'BlockListElementName';
|
||||
const blockListElementGroupName = 'ListElementGroup';
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(secondBlockListDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createDefaultElementType(textStringElementTypeName, textStringGroupName, textStringDataTypeName, textStringDataType.id);
|
||||
const secondBlockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(secondBlockListDataTypeName, textStringElementTypeId);
|
||||
const blockListElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockListElementTypeName, blockListElementGroupName, secondBlockListDataTypeName, secondBlockListDataTypeId);
|
||||
blockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(blockListDataTypeName, blockListElementTypeId);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, blockListDataTypeName, blockListDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickAddBlockElementButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(blockListElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(textStringElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(textStringElementTypeName, true);
|
||||
await umbracoUi.content.enterTextstring(textStringValue);
|
||||
await umbracoUi.content.clickCreateForModalWithHeadline('Add ' + textStringElementTypeName);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the BlockList is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentValues = documentData.values.find(value => value.alias === AliasHelper.toAlias(blockListDataTypeName));
|
||||
expect(documentValues.value.contentData[0].values[0].value.contentData[0].values[0].value).toContain(textStringValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(secondBlockListDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
});
|
||||
+2
@@ -55,6 +55,7 @@ test('can create child content in a collection', async ({umbracoApi, umbracoUi})
|
||||
await umbracoUi.content.chooseDocumentType(childDocumentTypeName);
|
||||
await umbracoUi.content.enterContentName(firstChildContentName);
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
await umbracoUi.content.isSuccessNotificationVisible();
|
||||
|
||||
// Assert
|
||||
const childData = await umbracoApi.document.getChildren(contentId);
|
||||
@@ -87,6 +88,7 @@ test('can create multiple child nodes in a collection', async ({umbracoApi, umbr
|
||||
await umbracoUi.content.chooseDocumentType(childDocumentTypeName);
|
||||
await umbracoUi.content.enterContentName(secondChildContentName);
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
await umbracoUi.content.isSuccessNotificationVisible();
|
||||
|
||||
// Assert
|
||||
const childData = await umbracoApi.document.getChildren(contentId);
|
||||
|
||||
+2
-2
@@ -68,7 +68,7 @@ test('can publish content with the media picker data type', async ({umbracoApi,
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.created);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
expect(await umbracoApi.document.doesNameExist(contentName)).toBeTruthy();
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
@@ -159,4 +159,4 @@ test('can not publish a mandatory media picker with an empty value', async ({umb
|
||||
expect(contentData.values[0].value[0].mediaTypeAlias).toEqual(mediaTypeName);
|
||||
expect(contentData.values[0].value[0].focalPoint).toBeNull();
|
||||
expect(contentData.values[0].value[0].crops).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ test('cannot input the text that exceeds the allowed amount of characters', asyn
|
||||
// Arrange
|
||||
const maxChars = 100;
|
||||
const textExceedMaxChars = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam mattis porttitor orci id cursus. Nulla';
|
||||
const warningMessage = 'This field exceeds the allowed amount of characters';
|
||||
const warningMessage = 'The string length exceeds the maximum length of ' + maxChars + ' characters, 1 too many.';
|
||||
const dataTypeId = await umbracoApi.dataType.createTextareaDataType(customDataTypeName, maxChars);
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, dataTypeId);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
|
||||
+2
-2
@@ -14,7 +14,7 @@ test.beforeEach(async ({umbracoApi, umbracoUi}) => {
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
});
|
||||
|
||||
@@ -84,7 +84,7 @@ test('cannot input the text that exceeds the allowed amount of characters', asyn
|
||||
// Arrange
|
||||
const maxChars = 20;
|
||||
const textExceedMaxChars = 'Lorem ipsum dolor sit';
|
||||
const warningMessage = 'This field exceeds the allowed amount of characters';
|
||||
const warningMessage = 'The string length exceeds the maximum length of ' + maxChars + ' characters, 1 too many.';
|
||||
const dataTypeId = await umbracoApi.dataType.createTextstringDataType(customDataTypeName, maxChars);
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, dataTypeId);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
import {AliasHelper, ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
// Content Name
|
||||
const contentName = 'ContentName';
|
||||
|
||||
// Document Type
|
||||
const documentTypeName = 'DocumentTypeName';
|
||||
let documentTypeId = null;
|
||||
const documentTypeGroupName = 'DocumentGroup';
|
||||
|
||||
// Rich Text Editor
|
||||
const richTextDataTypeName = 'RichTextDataType';
|
||||
let richTextDataTypeId = null;
|
||||
|
||||
// Text String
|
||||
const textStringElementTypeName = 'TextStringElementName';
|
||||
let textStringElementTypeId = null;
|
||||
let textStringGroupName = 'TextGroup';
|
||||
const textStringDataTypeName = 'Textstring';
|
||||
|
||||
test.beforeEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
});
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(richTextDataTypeName);
|
||||
});
|
||||
|
||||
test('can publish a rich text editor with a rich text editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const richTextEditorValue = 'Hello First World';
|
||||
const secondRichTextEditorValue = 'Hello Second World';
|
||||
const expectedRichTextEditorOutputValue = '<p>' + richTextEditorValue + '</p>';
|
||||
const secondExpectedRichTextEditorOutputValue = '<p>' + secondRichTextEditorValue + '</p>';
|
||||
const secondRichTextDataTypeName = 'SecondRichTextName';
|
||||
const richTextElementTypeName = 'RichTextElementName';
|
||||
const richTextElementGroupName = 'RichTextElementGroupName';
|
||||
await umbracoApi.dataType.ensureNameNotExists(secondRichTextDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextElementGroupName);
|
||||
|
||||
const secondRichTextEditorDataTypeId = await umbracoApi.dataType.createDefaultTiptapDataType(secondRichTextDataTypeName);
|
||||
const richTextElementTypeId = await umbracoApi.documentType.createDefaultElementType(richTextElementTypeName, richTextElementGroupName, secondRichTextDataTypeName, secondRichTextEditorDataTypeId);
|
||||
richTextDataTypeId = await umbracoApi.dataType.createRichTextEditorWithABlock(richTextDataTypeName, richTextElementTypeId);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, richTextDataTypeName, richTextDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.enterRTETipTapEditor(richTextEditorValue);
|
||||
await umbracoUi.content.clickInsertBlockButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(richTextElementTypeName, true);
|
||||
await umbracoUi.content.enterRTETipTapEditorWithName(AliasHelper.toAlias(secondRichTextDataTypeName), secondRichTextEditorValue);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the RTE is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
const documentValues = documentData.values.find(value => value.alias === AliasHelper.toAlias(richTextDataTypeName));
|
||||
// Value in the first RTE
|
||||
expect(documentValues.value.markup).toContain(expectedRichTextEditorOutputValue);
|
||||
// Value in the second RTE
|
||||
const secondRTEInBlock = documentValues.value.blocks.contentData[0].values.find(value => value.alias === AliasHelper.toAlias(secondRichTextDataTypeName));
|
||||
expect(secondRTEInBlock.value.markup).toContain(secondExpectedRichTextEditorOutputValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.documentType.ensureNameNotExists(richTextElementGroupName);
|
||||
});
|
||||
|
||||
test('can publish a rich text editor with a block grid editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const textStringValue = 'Hello World';
|
||||
const blockGridDataTypeName = 'BlockGridDataTypeName';
|
||||
const blockGridElementTypeName = 'BlockGridElementTypeName';
|
||||
const blockGridElementGroupName = 'BlockGridElementGroupName';
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockGridElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createDefaultElementType(textStringElementTypeName, textStringGroupName, textStringDataTypeName, textStringDataType.id);
|
||||
const blockGridDataTypeId = await umbracoApi.dataType.createBlockGridWithABlockWithInlineEditingMode(blockGridDataTypeName, textStringElementTypeId, true);
|
||||
const blockGridElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockGridElementTypeName, blockGridElementGroupName, blockGridDataTypeName, blockGridDataTypeId);
|
||||
richTextDataTypeId = await umbracoApi.dataType.createRichTextEditorWithABlock(richTextDataTypeName, blockGridElementTypeId);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, richTextDataTypeName, richTextDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickInsertBlockButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(blockGridElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(textStringElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(textStringElementTypeName, true);
|
||||
await umbracoUi.content.enterTextstring(textStringValue);
|
||||
await umbracoUi.content.clickCreateForModalWithHeadline('Add ' + textStringElementTypeName);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the BlockGrid is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(documentData.values[0].value.blocks.contentData[0].values[0].value.contentData[0].values[0].value).toContain(textStringValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockGridDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockGridElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
});
|
||||
|
||||
test('can publish a rich text editor with a block list editor', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
const textStringValue = 'Hello World';
|
||||
const blockListDataTypeName = 'BlockListName';
|
||||
const blockListElementTypeName = 'BlockListElementName';
|
||||
const blockListElementGroupName = 'BlockListGroupName';
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
|
||||
const textStringDataType = await umbracoApi.dataType.getByName(textStringDataTypeName);
|
||||
textStringElementTypeId = await umbracoApi.documentType.createDefaultElementType(textStringElementTypeName, textStringGroupName, textStringDataTypeName, textStringDataType.id);
|
||||
const blockListDataTypeId = await umbracoApi.dataType.createBlockListDataTypeWithABlock(blockListDataTypeName, textStringElementTypeId);
|
||||
const blockListElementTypeId = await umbracoApi.documentType.createDefaultElementType(blockListElementTypeName, blockListElementGroupName, blockListDataTypeName, blockListDataTypeId);
|
||||
richTextDataTypeId = await umbracoApi.dataType.createRichTextEditorWithABlock(richTextDataTypeName, blockListElementTypeId);
|
||||
documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, richTextDataTypeName, richTextDataTypeId, documentTypeGroupName);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.clickInsertBlockButton();
|
||||
await umbracoUi.content.clickBlockCardWithName(blockListElementTypeName, true);
|
||||
await umbracoUi.content.clickAddBlockWithNameButton(textStringElementTypeName);
|
||||
await umbracoUi.content.clickBlockCardWithName(textStringElementTypeName, true);
|
||||
await umbracoUi.content.enterTextstring(textStringValue);
|
||||
await umbracoUi.content.clickCreateForModalWithHeadline('Add ' + textStringElementTypeName);
|
||||
await umbracoUi.content.clickCreateModalButton();
|
||||
await umbracoUi.content.clickSaveAndPublishButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.published);
|
||||
// Asserts that the value in the BlockGrid is as expected
|
||||
const documentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(documentData.values[0].value.blocks.contentData[0].values[0].value.contentData[0].values[0].value).toContain(textStringValue);
|
||||
|
||||
// Clean
|
||||
await umbracoApi.dataType.ensureNameNotExists(blockListDataTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(blockListElementTypeName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(textStringElementTypeName);
|
||||
});
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
import {ConstantHelper, NotificationConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
import {expect} from "@playwright/test";
|
||||
|
||||
const contentName = 'TestContent';
|
||||
const documentTypeName = 'TestDocumentTypeForContent';
|
||||
const customDataTypeName = 'Test RTE Tiptap Style Select';
|
||||
const inputText = 'This is Tiptap test';
|
||||
|
||||
test.beforeEach(async ({umbracoApi, umbracoUi}) => {
|
||||
const customDataTypeId = await umbracoApi.dataType.createTiptapDataTypeWithStyleSelect(customDataTypeName);
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, customDataTypeName, customDataTypeId);
|
||||
await umbracoApi.document.createDefaultDocument(contentName, documentTypeId);
|
||||
await umbracoUi.goToBackOffice();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
await umbracoUi.content.goToContentWithName(contentName);
|
||||
await umbracoUi.content.enterRTETipTapEditor(inputText);
|
||||
await umbracoUi.content.selectAllRTETipTapEditorText();
|
||||
})
|
||||
|
||||
test.afterEach(async ({umbracoApi}) => {
|
||||
await umbracoApi.document.ensureNameNotExists(contentName);
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
await umbracoApi.dataType.ensureNameNotExists(customDataTypeName);
|
||||
});
|
||||
|
||||
test('can apply page header format', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
await umbracoUi.content.clickStyleSelectButton();
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.hoverCascadingMenuItemWithName('Headers');
|
||||
await umbracoUi.content.clickCascadingMenuItemWithName('Page header');
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.values[0].value.markup).toEqual('<h2>' + inputText + '</h2><p></p>');
|
||||
});
|
||||
|
||||
test('can apply section header format', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
await umbracoUi.content.clickStyleSelectButton();
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.hoverCascadingMenuItemWithName('Headers');
|
||||
await umbracoUi.content.clickCascadingMenuItemWithName('Section header');
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.values[0].value.markup).toEqual('<h3>' + inputText + '</h3><p></p>');
|
||||
});
|
||||
|
||||
test('can apply paragraph header format', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
await umbracoUi.content.clickStyleSelectButton();
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.hoverCascadingMenuItemWithName('Headers');
|
||||
await umbracoUi.content.clickCascadingMenuItemWithName('Paragraph header');
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.values[0].value.markup).toEqual('<h4>' + inputText + '</h4><p></p>');
|
||||
});
|
||||
|
||||
test('can apply paragraph blocks format', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
await umbracoUi.content.clickStyleSelectButton();
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.hoverCascadingMenuItemWithName('Blocks');
|
||||
await umbracoUi.content.clickCascadingMenuItemWithName('Paragraph');
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.values[0].value.markup).toEqual('<p>' + inputText + '</p>');
|
||||
});
|
||||
|
||||
test('can apply block quote format', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
await umbracoUi.content.clickStyleSelectButton();
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.hoverCascadingMenuItemWithName('Containers');
|
||||
await umbracoUi.content.clickCascadingMenuItemWithName('Block quote');
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.values[0].value.markup).toEqual('<blockquote><p>' + inputText + '</p></blockquote><p></p>');
|
||||
});
|
||||
|
||||
test('can apply code block format', async ({umbracoApi, umbracoUi}) => {
|
||||
// Arrange
|
||||
await umbracoUi.content.clickStyleSelectButton();
|
||||
|
||||
// Act
|
||||
await umbracoUi.content.hoverCascadingMenuItemWithName('Containers');
|
||||
await umbracoUi.content.clickCascadingMenuItemWithName('Code block');
|
||||
await umbracoUi.content.clickSaveButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.doesSuccessNotificationHaveText(NotificationConstantHelper.success.saved);
|
||||
const contentData = await umbracoApi.document.getByName(contentName);
|
||||
expect(contentData.values[0].value.markup).toEqual('<pre><code>' + inputText + '</code></pre><p></p>');
|
||||
});
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -0,0 +1,28 @@
|
||||
// TODO: Consider refactoring the initialization process to improve readability or simplify the builder configuration.
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(args);
|
||||
|
||||
builder.CreateUmbracoBuilder()
|
||||
.AddBackOffice()
|
||||
.AddWebsite()
|
||||
.AddDeliveryApi()
|
||||
.AddComposers()
|
||||
.Build();
|
||||
|
||||
WebApplication app = builder.Build();
|
||||
|
||||
await app.BootUmbracoAsync();
|
||||
|
||||
|
||||
app.UseUmbraco()
|
||||
.WithMiddleware(u =>
|
||||
{
|
||||
u.UseBackOffice();
|
||||
u.UseWebsite();
|
||||
})
|
||||
.WithEndpoints(u =>
|
||||
{
|
||||
u.UseBackOfficeEndpoints();
|
||||
u.UseWebsiteEndpoints();
|
||||
});
|
||||
|
||||
await app.RunAsync();
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"$schema": "appsettings-schema.json",
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information",
|
||||
"System": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Async",
|
||||
"Args": {
|
||||
"Configure": [
|
||||
{
|
||||
"Name": "Console"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Umbraco": {
|
||||
"CMS": {
|
||||
"DeliveryApi": {
|
||||
"Enabled": true,
|
||||
"Media": {
|
||||
"Enabled": true
|
||||
}
|
||||
},
|
||||
"Unattended": {
|
||||
"InstallUnattended": true,
|
||||
"UnattendedUserName": "Playwright Test",
|
||||
"UnattendedUserEmail": "playwright@umbraco.com",
|
||||
"UnattendedUserPassword": "UmbracoAcceptance123!"
|
||||
},
|
||||
"Content": {
|
||||
"ContentVersionCleanupPolicy": {
|
||||
"EnableCleanup": false
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"DisableElectionForSingleServer": true,
|
||||
"InstallMissingDatabase": true,
|
||||
"Id": "00000000-0000-0000-0000-000000000042",
|
||||
"VersionCheckPeriod": 0,
|
||||
"UseHttps": true
|
||||
},
|
||||
"HealthChecks": {
|
||||
"Notification": {
|
||||
"Enabled": false
|
||||
}
|
||||
},
|
||||
"KeepAlive": {
|
||||
"DisableKeepAliveTask": true
|
||||
},
|
||||
"WebRouting": {
|
||||
"UmbracoApplicationUrl": "https://localhost:44331/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import {expect} from '@playwright/test';
|
||||
import {AliasHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
|
||||
test('can get content from delivery api', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const documentTypeName = 'TestDocumentType';
|
||||
const contentName = 'TestContent';
|
||||
const dataTypeName = 'Textstring';
|
||||
const textStringValue = 'This is a test text string value';
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
const dataType = await umbracoApi.dataType.getByName(dataTypeName);
|
||||
const documentTypeId = await umbracoApi.documentType.createDocumentTypeWithPropertyEditor(documentTypeName, dataTypeName, dataType.id, 'TestGroup');
|
||||
const documentId = await umbracoApi.document.createDocumentWithTextContent(contentName, documentTypeId, textStringValue, dataTypeName);
|
||||
const propertyValue = {
|
||||
dataTypeName: AliasHelper.toAlias(dataTypeName),
|
||||
dataTypeValue: textStringValue
|
||||
}
|
||||
|
||||
// Act
|
||||
await umbracoApi.document.publish(documentId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.deliveryApi.doesContentItemWithIdContainValues(documentId, contentName, AliasHelper.toAlias(documentTypeName), [propertyValue])).toBeTruthy();
|
||||
|
||||
// Clean
|
||||
await umbracoApi.documentType.ensureNameNotExists(documentTypeName);
|
||||
});
|
||||
|
||||
test('can get media image from delivery api', async ({umbracoApi}) => {
|
||||
// Arrange
|
||||
const mediaName = 'TestMedia';
|
||||
const mediaTypeName = 'File';
|
||||
await umbracoApi.media.ensureNameNotExists(mediaName);
|
||||
const mediaId = await umbracoApi.media.createDefaultMediaFile(mediaName);
|
||||
const mediaUrl = await umbracoApi.media.getMediaUrlById(mediaId);
|
||||
|
||||
// Assert
|
||||
expect(await umbracoApi.deliveryApi.doesMediaItemWithIdContainValues(mediaId, mediaName, mediaTypeName, mediaUrl)).toBeTruthy();
|
||||
|
||||
// Clean
|
||||
await umbracoApi.media.ensureNameNotExists(mediaName);
|
||||
});
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"$schema": "../../umbraco-package-schema.json",
|
||||
"name": "Azure B2C Login",
|
||||
"allowPublicAccess": true,
|
||||
"extensions": [
|
||||
{
|
||||
"type": "authProvider",
|
||||
"alias": "Test.AzureB2C",
|
||||
"name": "Azure AD B2C",
|
||||
"forProviderName": "Umbraco.AzureB2C",
|
||||
"meta": {
|
||||
"label": "Sign in with Azure AD B2C",
|
||||
"defaultView": {
|
||||
"icon": "icon-cloud"
|
||||
},
|
||||
"behavior": {
|
||||
"autoRedirect": false
|
||||
},
|
||||
"linking": {
|
||||
"allowManualLinking": true
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Authentication.OpenIdConnect;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Tests.AcceptanceTest.ExternalLogin.AzureADB2C
|
||||
{
|
||||
public static class AzureB2CAuthenticationExtensions
|
||||
{
|
||||
public static IUmbracoBuilder ConfigureAuthentication(this IUmbracoBuilder builder,
|
||||
IConfiguration configuration)
|
||||
{
|
||||
var b2cSettings = new AzureB2CSettings();
|
||||
|
||||
builder.AddBackOfficeExternalLogins(logins =>
|
||||
{
|
||||
const string schemeName = AzureB2COptions.SchemeName;
|
||||
var backOfficeScheme = Constants.Security.BackOfficeExternalAuthenticationTypePrefix + schemeName;
|
||||
|
||||
logins.AddBackOfficeLogin(backOfficeAuth =>
|
||||
{
|
||||
backOfficeAuth.AddOpenIdConnect(backOfficeScheme, options =>
|
||||
{
|
||||
options.RequireHttpsMetadata = true;
|
||||
options.SaveTokens = true;
|
||||
options.ClientId = b2cSettings.ClientId;
|
||||
options.ClientSecret = b2cSettings.ClientSecret;
|
||||
options.CallbackPath = "/umbraco-b2c-users-signin";
|
||||
options.MetadataAddress =
|
||||
$"https://{b2cSettings.Domain}/{b2cSettings.Tenant}/{b2cSettings.Policy}/v2.0/.well-known/openid-configuration";
|
||||
|
||||
options.ResponseType = OpenIdConnectResponseType.Code;
|
||||
options.TokenValidationParameters.SaveSigninToken = true;
|
||||
options.GetClaimsFromUserInfoEndpoint = true;
|
||||
options.TokenValidationParameters.NameClaimType = "name";
|
||||
options.TokenValidationParameters.RoleClaimType = "role";
|
||||
|
||||
options.Events = new OpenIdConnectEvents
|
||||
{
|
||||
OnTokenResponseReceived = context =>
|
||||
{
|
||||
if (string.IsNullOrEmpty(context.TokenEndpointResponse.AccessToken))
|
||||
{
|
||||
context.TokenEndpointResponse.AccessToken = "empty_access_token";
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
},
|
||||
|
||||
OnTokenValidated = context =>
|
||||
{
|
||||
var identity = context.Principal!.Identities.First();
|
||||
|
||||
var email = identity.FindFirst("emails")?.Value
|
||||
?? identity.FindFirst(ClaimTypes.Email)?.Value;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(email))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.Email, email));
|
||||
identity.AddClaim(new Claim("email", email));
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return builder;
|
||||
}
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
using Umbraco.Cms.Core.Composing;
|
||||
|
||||
namespace Umbraco.Cms.Tests.AcceptanceTest.ExternalLogin.AzureADB2C
|
||||
{
|
||||
public class AzureB2CComposer : IComposer
|
||||
{
|
||||
public void Compose(IUmbracoBuilder builder)
|
||||
{
|
||||
builder.Services.ConfigureOptions<AzureB2COptions>();
|
||||
|
||||
builder.ConfigureAuthentication(builder.Config);
|
||||
}
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Api.Management.Security;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Tests.AcceptanceTest.ExternalLogin.AzureADB2C
|
||||
{
|
||||
public class AzureB2COptions : IConfigureNamedOptions<BackOfficeExternalLoginProviderOptions>
|
||||
{
|
||||
public const string SchemeName = "AzureB2C";
|
||||
|
||||
public void Configure(string? name, BackOfficeExternalLoginProviderOptions options)
|
||||
{
|
||||
if (name != Constants.Security.BackOfficeExternalAuthenticationTypePrefix + SchemeName)
|
||||
return;
|
||||
|
||||
options.AutoLinkOptions = new ExternalSignInAutoLinkOptions(
|
||||
autoLinkExternalAccount: true,
|
||||
defaultUserGroups: [Constants.Security.AdminGroupAlias],
|
||||
defaultCulture: "en-US",
|
||||
allowManualLinking: true
|
||||
)
|
||||
{
|
||||
OnAutoLinking = (user, loginInfo) => { user.IsApproved = true; },
|
||||
OnExternalLogin = (user, loginInfo) => { return true; }
|
||||
};
|
||||
}
|
||||
|
||||
public void Configure(BackOfficeExternalLoginProviderOptions options) =>
|
||||
Configure(Constants.Security.BackOfficeExternalAuthenticationTypePrefix + SchemeName, options);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
namespace Umbraco.Cms.Tests.AcceptanceTest.ExternalLogin.AzureADB2C
|
||||
{
|
||||
public class AzureB2CSettings
|
||||
{
|
||||
public string Domain { get; set; } = Environment.GetEnvironmentVariable("AZUREADB2CDOMAIN") ?? string.Empty;
|
||||
public string Tenant { get; set; } = Environment.GetEnvironmentVariable("AZUREADB2CTENANT") ?? string.Empty;
|
||||
public string Policy { get; set; } = Environment.GetEnvironmentVariable("AZUREADB2CPOLICY") ?? string.Empty;
|
||||
public string ClientId { get; set; } = Environment.GetEnvironmentVariable("AZUREADB2CCLIENTID") ?? string.Empty;
|
||||
public string ClientSecret { get; set; } = Environment.GetEnvironmentVariable("AZUREADB2CCLIENTSECRET") ?? string.Empty;
|
||||
}
|
||||
}
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
{
|
||||
"$schema": "appsettings-schema.json",
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information",
|
||||
"System": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Async",
|
||||
"Args": {
|
||||
"Configure": [
|
||||
{
|
||||
"Name": "Console"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Umbraco": {
|
||||
"CMS": {
|
||||
"Unattended": {
|
||||
"InstallUnattended": true,
|
||||
"UnattendedUserName": "Playwright Test",
|
||||
"UnattendedUserEmail": "playwright@umbraco.com",
|
||||
"UnattendedUserPassword": "UmbracoAcceptance123!"
|
||||
},
|
||||
"Content": {
|
||||
"ContentVersionCleanupPolicy": {
|
||||
"EnableCleanup": false
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"DisableElectionForSingleServer": true,
|
||||
"InstallMissingDatabase": true,
|
||||
"Id": "00000000-0000-0000-0000-000000000042",
|
||||
"VersionCheckPeriod": 0,
|
||||
"UseHttps": true
|
||||
},
|
||||
"HealthChecks": {
|
||||
"Notification": {
|
||||
"Enabled": false
|
||||
}
|
||||
},
|
||||
"KeepAlive": {
|
||||
"DisableKeepAliveTask": true
|
||||
},
|
||||
"WebRouting": {
|
||||
"UmbracoApplicationUrl": "https://localhost:44331/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import {ConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
|
||||
const azureEmail = process.env.AZUREADB2CTESTUSEREMAIL;
|
||||
const azurePassword = process.env.AZUREADB2CTESTUSERPASSWORD;
|
||||
|
||||
// Really simple test to check if we can log in using Azure AD B2C
|
||||
test('Log in to Umbraco using Azure AD B2C', async ({umbracoUi}) => {
|
||||
test.slow();
|
||||
// Arrange
|
||||
await umbracoUi.goToBackOffice();
|
||||
|
||||
// Act
|
||||
await umbracoUi.login.clickSignInWithAzureADB2CButton();
|
||||
await umbracoUi.login.enterAzureADB2CEmail(azureEmail);
|
||||
await umbracoUi.login.enterAzureADB2CPassword(azurePassword);
|
||||
await umbracoUi.login.clickSignInButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
});
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
{
|
||||
"$schema": "appsettings-schema.json",
|
||||
"Serilog": {
|
||||
"MinimumLevel": {
|
||||
"Default": "Information",
|
||||
"Override": {
|
||||
"Microsoft": "Warning",
|
||||
"Microsoft.Hosting.Lifetime": "Information",
|
||||
"System": "Warning"
|
||||
}
|
||||
},
|
||||
"WriteTo": [
|
||||
{
|
||||
"Name": "Async",
|
||||
"Args": {
|
||||
"Configure": [
|
||||
{
|
||||
"Name": "Console"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"Umbraco": {
|
||||
"CMS": {
|
||||
"Unattended": {
|
||||
"InstallUnattended": false
|
||||
},
|
||||
"Content": {
|
||||
"ContentVersionCleanupPolicy": {
|
||||
"EnableCleanup": false
|
||||
}
|
||||
},
|
||||
"Global": {
|
||||
"DisableElectionForSingleServer": true,
|
||||
"Id": "00000000-0000-0000-0000-000000000042",
|
||||
"VersionCheckPeriod": 0,
|
||||
"UseHttps": true
|
||||
},
|
||||
"HealthChecks": {
|
||||
"Notification": {
|
||||
"Enabled": false
|
||||
}
|
||||
},
|
||||
"KeepAlive": {
|
||||
"DisableKeepAliveTask": true
|
||||
},
|
||||
"WebRouting": {
|
||||
"UmbracoApplicationUrl": "https://localhost:44331/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// To be able to test different databases, we need to set an additional UnattendedInstallConfig up because we would have to start from scratch, otherwise we would be using the same database.
|
||||
import {ConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
|
||||
const name = 'TestName';
|
||||
const email = process.env.UMBRACO_USER_LOGIN;
|
||||
const password = process.env.UMBRACO_USER_PASSWORD;
|
||||
|
||||
test('Install Umbraco using SQLServer Express', async ({umbracoUi}) => {
|
||||
test.slow();
|
||||
// Arrange
|
||||
await umbracoUi.install.goToInstallPage();
|
||||
|
||||
// Act
|
||||
await umbracoUi.install.enterName(name);
|
||||
await umbracoUi.install.enterEmail(email);
|
||||
await umbracoUi.install.enterPassword(password);
|
||||
await umbracoUi.install.clickNextButton();
|
||||
await umbracoUi.install.clickNextButton();
|
||||
await umbracoUi.install.setDatabaseType('SQL Server Express LocalDB');
|
||||
await umbracoUi.install.doesDatabaseHaveType('SQL Server Express LocalDB');
|
||||
await umbracoUi.install.clickInstallButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.login.enterEmail(email);
|
||||
await umbracoUi.login.enterPassword(password);
|
||||
await umbracoUi.login.clickLoginButton();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
});
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// To be able to test different databases, we need to set an additional UnattendedInstallConfig up because we would have to start from scratch, otherwise we would be using the same database.
|
||||
import {ConstantHelper, test} from '@umbraco/playwright-testhelpers';
|
||||
|
||||
const name = 'TestName';
|
||||
const email = process.env.UMBRACO_USER_LOGIN;
|
||||
const password = process.env.UMBRACO_USER_PASSWORD;
|
||||
|
||||
test('Install Umbraco using SQLite', async ({umbracoUi}) => {
|
||||
test.slow();
|
||||
// Arrange
|
||||
await umbracoUi.install.goToInstallPage();
|
||||
|
||||
// Act
|
||||
await umbracoUi.install.enterName(name);
|
||||
await umbracoUi.install.enterEmail(email);
|
||||
await umbracoUi.install.enterPassword(password);
|
||||
await umbracoUi.install.clickNextButton();
|
||||
await umbracoUi.install.clickNextButton();
|
||||
await umbracoUi.install.doesDatabaseHaveType('SQLite');
|
||||
await umbracoUi.install.clickInstallButton();
|
||||
|
||||
// Assert
|
||||
await umbracoUi.login.enterEmail(email);
|
||||
await umbracoUi.login.enterPassword(password);
|
||||
await umbracoUi.login.clickLoginButton();
|
||||
await umbracoUi.content.goToSection(ConstantHelper.sections.content);
|
||||
});
|
||||
@@ -1,6 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
|
||||
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Umbraco.Cms.Tests.Integration.ManagementApi.Policies.AllCultureControllerTests</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Umbraco.Cms.Tests.Integration.ManagementApi.Preview.EndPreviewTests</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Umbraco.Cms.Tests.Integration.ManagementApi.Preview.EnterPreviewTests</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0001</DiagnosticId>
|
||||
<Target>T:Umbraco.Cms.Tests.Integration.Umbraco.Core.Services.DocumentUrlServiceTest</Target>
|
||||
@@ -78,6 +99,20 @@
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.ManagementApi.ManagementApiTest`1.Setup</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.Testing.UmbracoIntegrationTestBase.UseTestDatabase(Microsoft.AspNetCore.Builder.IApplicationBuilder)</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0002</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.Umbraco.Core.Services.DocumentNavigationServiceTests.Bin_Structure_Can_Rebuild</Target>
|
||||
@@ -141,4 +176,46 @@
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0005</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.ManagementApi.ManagementApiTest`1.set_MethodSelector(System.Linq.Expressions.Expression{System.Func{`0,System.Object}})</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0012</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.ManagementApi.ManagementApiTest`1.get_Url</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0012</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.TestServerTest.UmbracoTestServerTestBase.get_Services</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0012</DiagnosticId>
|
||||
<Target>P:Umbraco.Cms.Tests.Integration.ManagementApi.ManagementApiTest`1.Url</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0012</DiagnosticId>
|
||||
<Target>P:Umbraco.Cms.Tests.Integration.TestServerTest.UmbracoTestServerTestBase.Services</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
<Suppression>
|
||||
<DiagnosticId>CP0012</DiagnosticId>
|
||||
<Target>M:Umbraco.Cms.Tests.Integration.TestServerTest.UmbracoTestServerTestBase.CustomMvcSetup(Microsoft.Extensions.DependencyInjection.IMvcBuilder)</Target>
|
||||
<Left>lib/net9.0/Umbraco.Tests.Integration.dll</Left>
|
||||
<Right>lib/net9.0/Umbraco.Tests.Integration.dll</Right>
|
||||
<IsBaselineSuppression>true</IsBaselineSuppression>
|
||||
</Suppression>
|
||||
</Suppressions>
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Culture;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Culture;
|
||||
|
||||
public class AllCultureControllerTests : ManagementApiUserGroupTestBase<AllCultureController>
|
||||
{
|
||||
ILanguageService LanguageService => GetRequiredService<ILanguageService>();
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var langDa = new LanguageBuilder()
|
||||
.WithCultureInfo("da-DK")
|
||||
.Build();
|
||||
await LanguageService.CreateAsync(langDa, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<AllCultureController, object>> MethodSelector =>
|
||||
x => x.GetAll(CancellationToken.None, 0, 100);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class ByKeyDataTypeControllerTests : ManagementApiUserGroupTestBase<ByKeyDataTypeController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var response = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ByKeyDataTypeController, object>> MethodSelector =>
|
||||
x => x.ByKey(CancellationToken.None, _dataTypeKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class CopyDataTypeControllerTests : ManagementApiUserGroupTestBase<CopyDataTypeController>
|
||||
{
|
||||
private IDataTypeContainerService DataTypeContainerService => GetRequiredService<IDataTypeContainerService>();
|
||||
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
private Guid _folderKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Folder
|
||||
var responseFolder = await DataTypeContainerService.CreateAsync(Guid.NewGuid(), "TestFolder", Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
_folderKey = responseFolder.Result.Key;
|
||||
|
||||
// Datatype
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var responseDataType = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeKey = responseDataType.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<CopyDataTypeController, object>> MethodSelector =>
|
||||
x => x.Copy(CancellationToken.None, _dataTypeKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
CopyDataTypeRequestModel copyDataTypeRequestModel = new() { Target = new ReferenceByIdModel(_folderKey) };
|
||||
|
||||
return await Client.PostAsync(Url, JsonContent.Create(copyDataTypeRequestModel));
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DataType;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class CreateDataTypeControllerTests : ManagementApiUserGroupTestBase<CreateDataTypeController>
|
||||
{
|
||||
protected override Expression<Func<CreateDataTypeController, object>> MethodSelector =>
|
||||
x => x.Create(CancellationToken.None, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
CreateDataTypeRequestModel createDataTypeRequestModel = new()
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
Parent = null,
|
||||
Name = "TestDataType",
|
||||
EditorAlias = "Umbraco.CheckBoxList",
|
||||
EditorUiAlias = "Umb.PropertyEditorUi.CheckBoxList",
|
||||
};
|
||||
|
||||
return await Client.PostAsync(Url, JsonContent.Create(createDataTypeRequestModel));
|
||||
}
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class DeleteDataTypeControllerTests : ManagementApiUserGroupTestBase<DeleteDataTypeController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var response = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<DeleteDataTypeController, object>> MethodSelector =>
|
||||
x => x.Delete(CancellationToken.None, _dataTypeKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest() => await Client.DeleteAsync(Url);
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Folder;
|
||||
|
||||
public class ByKeyDataTypeFolderControllerTests : ManagementApiUserGroupTestBase<ByKeyDataTypeFolderController>
|
||||
{
|
||||
private IDataTypeContainerService DataTypeContainerService => GetRequiredService<IDataTypeContainerService>();
|
||||
|
||||
private Guid _folderKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var response = await DataTypeContainerService.CreateAsync(Guid.NewGuid(), "TestFolder", Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
_folderKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ByKeyDataTypeFolderController, object>> MethodSelector =>
|
||||
x => x.ByKey(CancellationToken.None, _folderKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Folder;
|
||||
|
||||
public class CreateDataTypeFolderControllerTests : ManagementApiUserGroupTestBase<CreateDataTypeFolderController>
|
||||
{
|
||||
protected override Expression<Func<CreateDataTypeFolderController, object>> MethodSelector =>
|
||||
x => x.Create(CancellationToken.None, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
CreateFolderRequestModel createFolderModel =
|
||||
new() { Id = Guid.NewGuid(), Parent = null, Name = "TestFolderName" };
|
||||
|
||||
return await Client.PostAsync(Url, JsonContent.Create(createFolderModel));
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Folder;
|
||||
|
||||
public class DeleteDataTypeFolderControllerTests : ManagementApiUserGroupTestBase<DeleteDataTypeFolderController>
|
||||
{
|
||||
private IDataTypeContainerService DataTypeContainerService => GetRequiredService<IDataTypeContainerService>();
|
||||
|
||||
private Guid _folderKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var response = await DataTypeContainerService.CreateAsync(Guid.NewGuid(), "TestFolder", Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
_folderKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<DeleteDataTypeFolderController, object>> MethodSelector =>
|
||||
x => x.Delete(CancellationToken.None, _folderKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest() => await Client.DeleteAsync(Url);
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Folder;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Folder;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Folder;
|
||||
|
||||
public class UpdateDataTypeFolderControllerTests : ManagementApiUserGroupTestBase<UpdateDataTypeFolderController>
|
||||
{
|
||||
private IDataTypeContainerService DataTypeContainerService => GetRequiredService<IDataTypeContainerService>();
|
||||
|
||||
private Guid _folderKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var response = await DataTypeContainerService.CreateAsync(Guid.NewGuid(), "TestFolder", Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
_folderKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<UpdateDataTypeFolderController, object>> MethodSelector =>
|
||||
x => x.Update(CancellationToken.None, _folderKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
UpdateFolderResponseModel updateFolderModel = new() { Name = "TestUpdatedName" };
|
||||
|
||||
return await Client.PutAsync(Url, JsonContent.Create(updateFolderModel));
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class IsUsedDataTypeControllerTests : ManagementApiUserGroupTestBase<IsUsedDataTypeController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var response = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<IsUsedDataTypeController, object>> MethodSelector =>
|
||||
x => x.IsUsed(CancellationToken.None, _dataTypeKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Item;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Item;
|
||||
|
||||
public class ItemDatatypeItemControllerTests : ManagementApiUserGroupTestBase<ItemDatatypeItemController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var response = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
_dataTypeKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ItemDatatypeItemController, object>> MethodSelector =>
|
||||
x => x.Item(CancellationToken.None, new HashSet<Guid> { _dataTypeKey });
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DataType;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class MoveDataTypeControllerTests : ManagementApiUserGroupTestBase<MoveDataTypeController>
|
||||
{
|
||||
private IDataTypeContainerService DataTypeContainerService => GetRequiredService<IDataTypeContainerService>();
|
||||
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
private Guid _folderKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var responseFolder = await DataTypeContainerService.CreateAsync(Guid.NewGuid(), "TestFolder", Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
_folderKey = responseFolder.Result.Key;
|
||||
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var responseDataType = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeKey = responseDataType.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<MoveDataTypeController, object>> MethodSelector =>
|
||||
x => x.Move(CancellationToken.None, _dataTypeKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
MoveDataTypeRequestModel moveDataTypeRequestModel = new() { Target = new ReferenceByIdModel(_folderKey) };
|
||||
|
||||
return await Client.PutAsync(Url, JsonContent.Create(moveDataTypeRequestModel));
|
||||
}
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class ReferencesDataTypeControllerTests : ManagementApiUserGroupTestBase<ReferencesDataTypeController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var response = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ReferencesDataTypeController, object>> MethodSelector =>
|
||||
x => x.References(CancellationToken.None, _dataTypeKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Tree;
|
||||
|
||||
public class ChildrenDataTypeTreeControllerTests : ManagementApiUserGroupTestBase<ChildrenDataTypeTreeController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private IDataTypeContainerService DataTypeContainerService => GetRequiredService<IDataTypeContainerService>();
|
||||
|
||||
private Guid _dataTypeFolderKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Folder
|
||||
_dataTypeFolderKey = Guid.NewGuid();
|
||||
await DataTypeContainerService.CreateAsync(_dataTypeFolderKey, Guid.NewGuid().ToString(), Constants.System.RootKey, Constants.Security.SuperUserKey);
|
||||
var createdFolder = await DataTypeContainerService.GetAsync(_dataTypeFolderKey);
|
||||
var folderId = createdFolder.Id;
|
||||
|
||||
// Datatype
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.WithParentId(folderId)
|
||||
.Build();
|
||||
await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<ChildrenDataTypeTreeController, object>> MethodSelector =>
|
||||
x => x.Children(CancellationToken.None, _dataTypeFolderKey, 0, 100, false);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType.Tree;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType.Tree;
|
||||
|
||||
public class RootDataTypeTreeControllerTests : ManagementApiUserGroupTestBase<RootDataTypeTreeController>
|
||||
{
|
||||
protected override Expression<Func<RootDataTypeTreeController, object>> MethodSelector =>
|
||||
x => x.Root(CancellationToken.None, 0, 100, false);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.DataType;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.DataType;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.DataType;
|
||||
|
||||
public class UpdateDataTypeControllerTests : ManagementApiUserGroupTestBase<UpdateDataTypeController>
|
||||
{
|
||||
private IDataTypeService DataTypeService => GetRequiredService<IDataTypeService>();
|
||||
|
||||
private Guid _dataTypeId;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dataType = new DataTypeBuilder()
|
||||
.WithId(0)
|
||||
.WithName("Custom list view")
|
||||
.WithDatabaseType(ValueStorageType.Nvarchar)
|
||||
.AddEditor()
|
||||
.WithAlias(Constants.PropertyEditors.Aliases.ListView)
|
||||
.Done()
|
||||
.Build();
|
||||
var response = await DataTypeService.CreateAsync(dataType, Constants.Security.SuperUserKey);
|
||||
|
||||
_dataTypeId = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<UpdateDataTypeController, object>> MethodSelector =>
|
||||
x => x.Update(CancellationToken.None, _dataTypeId, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
UpdateDataTypeRequestModel updateDataTypeRequestModel =
|
||||
new()
|
||||
{
|
||||
Name = "TestNameUpdated",
|
||||
EditorAlias = "Umbraco.Label",
|
||||
EditorUiAlias = "Umb.PropertyEditorUi.Label",
|
||||
Values = new List<DataTypePropertyPresentationModel>
|
||||
{
|
||||
new DataTypePropertyPresentationModel { Alias = "ValueAlias", Value = "TestValue", },
|
||||
},
|
||||
};
|
||||
|
||||
return await Client.PutAsync(Url, JsonContent.Create(updateDataTypeRequestModel));
|
||||
}
|
||||
}
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class AllDictionaryControllerTests : ManagementApiUserGroupTestBase<AllDictionaryController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
await DictionaryItemService.CreateAsync(dictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<AllDictionaryController, object>> MethodSelector =>
|
||||
x => x.All(CancellationToken.None, null, 0, 100);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class ByKeyDictionaryControllerTests : ManagementApiUserGroupTestBase<ByKeyDictionaryController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _dictionaryKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
_dictionaryKey = dictionaryItem.Key;
|
||||
await DictionaryItemService.CreateAsync(dictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<ByKeyDictionaryController, object>> MethodSelector =>
|
||||
x => x.ByKey(CancellationToken.None, _dictionaryKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class CreateDictionaryControllerTests : ManagementApiUserGroupTestBase<CreateDictionaryController>
|
||||
{
|
||||
protected override Expression<Func<CreateDictionaryController, object>> MethodSelector =>
|
||||
x => x.Create(CancellationToken.None, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
CreateDictionaryItemRequestModel createDictionaryItemRequestModel =
|
||||
new() { Id = Guid.NewGuid(), Parent = null, Name = Guid.NewGuid().ToString() };
|
||||
return await Client.PostAsync(Url, JsonContent.Create(createDictionaryItemRequestModel));
|
||||
}
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class DeleteDictionaryControllerTests : ManagementApiUserGroupTestBase<DeleteDictionaryController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _dictionaryKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
_dictionaryKey = dictionaryItem.Key;
|
||||
await DictionaryItemService.CreateAsync(dictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<DeleteDictionaryController, object>> MethodSelector =>
|
||||
x => x.Delete(CancellationToken.None, _dictionaryKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest() => await Client.DeleteAsync(Url);
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class ExportDictionaryControllerTests : ManagementApiUserGroupTestBase<ExportDictionaryController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _dictionaryKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
_dictionaryKey = dictionaryItem.Key;
|
||||
await DictionaryItemService.CreateAsync(dictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<ExportDictionaryController, object>> MethodSelector =>
|
||||
x => x.Export(CancellationToken.None, _dictionaryKey, false);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Models.TemporaryFile;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class ImportDictionaryControllerTests : ManagementApiUserGroupTestBase<ImportDictionaryController>
|
||||
{
|
||||
private ITemporaryFileService TemporaryFileService => GetRequiredService<ITemporaryFileService>();
|
||||
|
||||
private Guid _temporaryFileKey;
|
||||
|
||||
// We need to override the setup to add the file extension for dictionaries
|
||||
protected override void CustomTestSetup(IUmbracoBuilder builder)
|
||||
{
|
||||
base.CustomTestSetup(builder);
|
||||
|
||||
builder.Services.Configure<ContentSettings>(options =>
|
||||
{
|
||||
options.AllowedUploadedFileExtensions = ["udt"];
|
||||
});
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var createTempFileModel = new CreateTemporaryFileModel
|
||||
{
|
||||
FileName = "test.udt",
|
||||
Key = Guid.NewGuid(),
|
||||
OpenReadStream = () =>
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
var writer = new StreamWriter(stream);
|
||||
writer.Write("<DictionaryItem Key=\"0115a059-4668-49d6-b1a9-7eef8b483fe0\" Name=\"test\" />");
|
||||
writer.Flush();
|
||||
stream.Position = 0;
|
||||
return stream;
|
||||
},
|
||||
};
|
||||
|
||||
var response = await TemporaryFileService.CreateAsync(createTempFileModel);
|
||||
_temporaryFileKey = response.Result.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ImportDictionaryController, object>> MethodSelector =>
|
||||
x => x.Import(CancellationToken.None, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
ImportDictionaryRequestModel importDictionaryRequestModel =
|
||||
new() { TemporaryFile = new ReferenceByIdModel(_temporaryFileKey) };
|
||||
return await Client.PostAsync(Url, JsonContent.Create(importDictionaryRequestModel));
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary.Item;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary.Item;
|
||||
|
||||
public class ItemDictionaryItemControllerTests : ManagementApiUserGroupTestBase<ItemDictionaryItemController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _dictionaryKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
_dictionaryKey = dictionaryItem.Key;
|
||||
await DictionaryItemService.CreateAsync(dictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<ItemDictionaryItemController, object>> MethodSelector =>
|
||||
x => x.Item(CancellationToken.None, new HashSet<Guid> { _dictionaryKey });
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class MoveDictionaryControllerTests : ManagementApiUserGroupTestBase<MoveDictionaryController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _originalId;
|
||||
private Guid _targetId;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var originalDictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
var targetDictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
|
||||
_originalId = originalDictionaryItem.Key;
|
||||
_targetId = targetDictionaryItem.Key;
|
||||
|
||||
await DictionaryItemService.CreateAsync(originalDictionaryItem, Constants.Security.SuperUserKey);
|
||||
await DictionaryItemService.CreateAsync(targetDictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<MoveDictionaryController, object>> MethodSelector =>
|
||||
x => x.Move(CancellationToken.None, _originalId, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
MoveDictionaryRequestModel moveDictionaryRequestModel =
|
||||
new() { Target = new ReferenceByIdModel(_targetId) };
|
||||
return await Client.PutAsync(Url, JsonContent.Create(moveDictionaryRequestModel));
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary.Tree;
|
||||
|
||||
public class ChildrenDictionaryTreeControllerTests : ManagementApiUserGroupTestBase<ChildrenDictionaryTreeController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _parentDictionaryKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Parent dictionary
|
||||
var dictionaryParentItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
_parentDictionaryKey = dictionaryParentItem.Key;
|
||||
await DictionaryItemService.CreateAsync(dictionaryParentItem, Constants.Security.SuperUserKey);
|
||||
|
||||
// Child dictionary
|
||||
var dictionaryChildItem = new DictionaryItem(_parentDictionaryKey, Guid.NewGuid().ToString());
|
||||
await DictionaryItemService.CreateAsync(dictionaryChildItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<ChildrenDictionaryTreeController, object>> MethodSelector =>
|
||||
x => x.Children(CancellationToken.None, _parentDictionaryKey, 0, 100);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary.Tree;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary.Tree;
|
||||
|
||||
public class RootDictionaryTreeControllerTests : ManagementApiUserGroupTestBase<RootDictionaryTreeController>
|
||||
{
|
||||
protected override Expression<Func<RootDictionaryTreeController, object>> MethodSelector =>
|
||||
x => x.Root(CancellationToken.None, 0, 100);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Dictionary;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Dictionary;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Dictionary;
|
||||
|
||||
public class UpdateDictionaryControllerTests : ManagementApiUserGroupTestBase<UpdateDictionaryController>
|
||||
{
|
||||
private IDictionaryItemService DictionaryItemService => GetRequiredService<IDictionaryItemService>();
|
||||
|
||||
private Guid _dictionaryKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
var dictionaryItem = new DictionaryItem(Constants.System.RootKey, Guid.NewGuid().ToString());
|
||||
|
||||
_dictionaryKey = dictionaryItem.Key;
|
||||
|
||||
await DictionaryItemService.CreateAsync(dictionaryItem, Constants.Security.SuperUserKey);
|
||||
}
|
||||
|
||||
protected override Expression<Func<UpdateDictionaryController, object>> MethodSelector => x => x.Update(CancellationToken.None, _dictionaryKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
UpdateDictionaryItemRequestModel updateDictionaryItemRequestModel =
|
||||
new() { Name = Guid.NewGuid().ToString(), };
|
||||
return await Client.PutAsync(Url, JsonContent.Create(updateDictionaryItemRequestModel));
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class ByKeyDocumentControllerTests : ManagementApiUserGroupTestBase<ByKeyDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private Guid _documentKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content
|
||||
var createModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var response = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
_documentKey = response.Result.Content.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ByKeyDocumentController, object>> MethodSelector =>
|
||||
x => x.ByKey(CancellationToken.None, _documentKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class CopyDocumentControllerTests : ManagementApiUserGroupTestBase<CopyDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private Guid _targetContentKey;
|
||||
private Guid _moveContentKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
contentType.AllowedContentTypes = [new ContentTypeSort(contentType.Key, 0, contentType.Alias)];
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Target Content
|
||||
var targetCreateModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseParent = await ContentEditingService.CreateAsync(targetCreateModel, Constants.Security.SuperUserKey);
|
||||
_targetContentKey = responseParent.Result.Content.Key;
|
||||
|
||||
// Move Content
|
||||
var moveCreateModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseChild = await ContentEditingService.CreateAsync(moveCreateModel, Constants.Security.SuperUserKey);
|
||||
_moveContentKey = responseChild.Result.Content.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<CopyDocumentController, object>> MethodSelector =>
|
||||
x => x.Copy(CancellationToken.None, _moveContentKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
CopyDocumentRequestModel copyDocumentRequestModel = new()
|
||||
{
|
||||
Target = new ReferenceByIdModel(_targetContentKey), RelateToOriginal = true, IncludeDescendants = true,
|
||||
};
|
||||
|
||||
return await Client.PostAsync(Url, JsonContent.Create(copyDocumentRequestModel));
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class CreateDocumentControllerTests : ManagementApiUserGroupTestBase<CreateDocumentController>
|
||||
{
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private Guid _templateKey;
|
||||
private Guid _contentTypeKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
_templateKey = template.Key;
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
_contentTypeKey = contentType.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<CreateDocumentController, object>> MethodSelector =>
|
||||
x => x.Create(CancellationToken.None, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
CreateDocumentRequestModel createDocumentRequestModel = new()
|
||||
{
|
||||
Template = new ReferenceByIdModel(_templateKey),
|
||||
DocumentType = new ReferenceByIdModel(_contentTypeKey),
|
||||
Parent = null,
|
||||
Id = Guid.NewGuid(),
|
||||
Values = new DocumentValueModel[] { },
|
||||
Variants = new DocumentVariantRequestModel[]
|
||||
{
|
||||
new() { Culture = null, Segment = null, Name = "The en-US name", },
|
||||
},
|
||||
};
|
||||
|
||||
return await Client.PostAsync(Url, JsonContent.Create(createDocumentRequestModel));
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.PublicAccess;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class
|
||||
CreatePublicAccessDocumentControllerTests : ManagementApiUserGroupTestBase<CreatePublicAccessDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private IMemberTypeService MemberTypeService => GetRequiredService<IMemberTypeService>();
|
||||
|
||||
private IMemberService MemberService => GetRequiredService<IMemberService>();
|
||||
|
||||
private Guid _contentDefaultPageKey;
|
||||
private Guid _contentLoginPageKey;
|
||||
private Guid _contentErrorPageKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Default page
|
||||
var createDefaultPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseDefaultPage = await ContentEditingService.CreateAsync(createDefaultPageModel, Constants.Security.SuperUserKey);
|
||||
_contentDefaultPageKey = responseDefaultPage.Result.Content.Key;
|
||||
|
||||
// Login page
|
||||
var createLoginPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseLoginPage = await ContentEditingService.CreateAsync(createLoginPageModel, Constants.Security.SuperUserKey);
|
||||
_contentLoginPageKey = responseLoginPage.Result.Content.Key;
|
||||
|
||||
// Error page
|
||||
var createErrorPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseErrorPage = await ContentEditingService.CreateAsync(createErrorPageModel, Constants.Security.SuperUserKey);
|
||||
_contentErrorPageKey = responseErrorPage.Result.Content.Key;
|
||||
|
||||
// Member
|
||||
var memberType = MemberTypeBuilder.CreateSimpleMemberType();
|
||||
await MemberTypeService.CreateAsync(memberType, Constants.Security.SuperUserKey);
|
||||
var member = MemberService.CreateMember("test", "test@test.com", "T. Est", memberType.Alias);
|
||||
MemberService.Save(member);
|
||||
}
|
||||
|
||||
protected override Expression<Func<CreatePublicAccessDocumentController, object>> MethodSelector =>
|
||||
x => x.Create(CancellationToken.None, _contentDefaultPageKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Created
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
PublicAccessRequestModel publicAccessRequestModel = new()
|
||||
{
|
||||
MemberUserNames = ["test@test.com"],
|
||||
MemberGroupNames = [],
|
||||
LoginDocument = new ReferenceByIdModel(_contentLoginPageKey),
|
||||
ErrorDocument = new ReferenceByIdModel(_contentErrorPageKey),
|
||||
};
|
||||
|
||||
return await Client.PostAsync(Url, JsonContent.Create(publicAccessRequestModel));
|
||||
}
|
||||
}
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class DeletePublicAccessDocumentControllerTests : ManagementApiUserGroupTestBase<DeletePublicAccessDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private IMemberTypeService MemberTypeService => GetRequiredService<IMemberTypeService>();
|
||||
|
||||
private IMemberService MemberService => GetRequiredService<IMemberService>();
|
||||
|
||||
private IPublicAccessService PublicAccessService => GetRequiredService<IPublicAccessService>();
|
||||
|
||||
private Guid _contentDefaultPageKey;
|
||||
private Guid _contentLoginPageKey;
|
||||
private Guid _contentErrorPageKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Default page
|
||||
var createDefaultPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseDefaultPage = await ContentEditingService.CreateAsync(createDefaultPageModel, Constants.Security.SuperUserKey);
|
||||
_contentDefaultPageKey = responseDefaultPage.Result.Content.Key;
|
||||
|
||||
// Login page
|
||||
var createLoginPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseLoginPage = await ContentEditingService.CreateAsync(createLoginPageModel, Constants.Security.SuperUserKey);
|
||||
_contentLoginPageKey = responseLoginPage.Result.Content.Key;
|
||||
|
||||
// Error page
|
||||
var createErrorPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseErrorPage = await ContentEditingService.CreateAsync(createErrorPageModel, Constants.Security.SuperUserKey);
|
||||
_contentErrorPageKey = responseErrorPage.Result.Content.Key;
|
||||
|
||||
// Member
|
||||
var memberType = MemberTypeBuilder.CreateSimpleMemberType();
|
||||
await MemberTypeService.CreateAsync(memberType, Constants.Security.SuperUserKey);
|
||||
|
||||
var member = MemberService.CreateMember("test", "test@test.com", "T. Est", memberType.Alias);
|
||||
MemberService.Save(member);
|
||||
|
||||
// Public Access
|
||||
PublicAccessEntrySlim publicAccessEntry = new()
|
||||
{
|
||||
ContentId = _contentDefaultPageKey,
|
||||
ErrorPageId = _contentErrorPageKey,
|
||||
LoginPageId = _contentLoginPageKey,
|
||||
MemberUserNames = [member.Email],
|
||||
MemberGroupNames = [],
|
||||
};
|
||||
await PublicAccessService.CreateAsync(publicAccessEntry);
|
||||
}
|
||||
|
||||
protected override Expression<Func<DeletePublicAccessDocumentController, object>> MethodSelector =>
|
||||
x => x.Delete(CancellationToken.None, _contentDefaultPageKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest() => await Client.DeleteAsync(Url);
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Models.ContentPublishing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class DomainsControllerTests : ManagementApiUserGroupTestBase<DomainsController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private IContentPublishingService ContentPublishingService => GetRequiredService<IContentPublishingService>();
|
||||
|
||||
private IDomainService DomainService => GetRequiredService<IDomainService>();
|
||||
|
||||
private ILanguageService LanguageService => GetRequiredService<ILanguageService>();
|
||||
|
||||
private Guid _documentKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content
|
||||
var createModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var response = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
_documentKey = response.Result.Content.Key;
|
||||
|
||||
// Publish
|
||||
var contentSchedule = new ContentScheduleCollection();
|
||||
var cultureAndSchedule = new CultureAndScheduleModel
|
||||
{
|
||||
CulturesToPublishImmediately = new HashSet<string> { "*" }, Schedules = contentSchedule,
|
||||
};
|
||||
await ContentPublishingService.PublishAsync(_documentKey, cultureAndSchedule, Constants.Security.SuperUserKey);
|
||||
|
||||
// Language
|
||||
await LanguageService.CreateAsync(new Core.Models.Language("da-DK", "Danish"), Constants.Security.SuperUserKey);
|
||||
|
||||
// Domain
|
||||
var domainsUpdateModel = new DomainsUpdateModel
|
||||
{
|
||||
DefaultIsoCode = "en-US", Domains = new DomainModel { DomainName = "Test", IsoCode = "da-DK" }.Yield(),
|
||||
};
|
||||
await DomainService.UpdateDomainsAsync(_documentKey, domainsUpdateModel);
|
||||
}
|
||||
|
||||
protected override Expression<Func<DomainsController, object>> MethodSelector =>
|
||||
x => x.Domains(CancellationToken.None, _documentKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class GetPublicAccessDocumentControllerTests : ManagementApiUserGroupTestBase<GetPublicAccessDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private IMemberTypeService MemberTypeService => GetRequiredService<IMemberTypeService>();
|
||||
|
||||
private IMemberService MemberService => GetRequiredService<IMemberService>();
|
||||
|
||||
private IPublicAccessService PublicAccessService => GetRequiredService<IPublicAccessService>();
|
||||
|
||||
private Guid _contentDefaultPageKey;
|
||||
private Guid _contentLoginPageKey;
|
||||
private Guid _contentErrorPageKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Default page
|
||||
var createDefaultPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseDefaultPage = await ContentEditingService.CreateAsync(createDefaultPageModel, Constants.Security.SuperUserKey);
|
||||
_contentDefaultPageKey = responseDefaultPage.Result.Content.Key;
|
||||
|
||||
// Login page
|
||||
var createLoginPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseLoginPage = await ContentEditingService.CreateAsync(createLoginPageModel, Constants.Security.SuperUserKey);
|
||||
_contentLoginPageKey = responseLoginPage.Result.Content.Key;
|
||||
|
||||
// Error page
|
||||
var createErrorPageModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseErrorPage = await ContentEditingService.CreateAsync(createErrorPageModel, Constants.Security.SuperUserKey);
|
||||
_contentErrorPageKey = responseErrorPage.Result.Content.Key;
|
||||
|
||||
// Member
|
||||
var memberType = MemberTypeBuilder.CreateSimpleMemberType();
|
||||
await MemberTypeService.CreateAsync(memberType, Constants.Security.SuperUserKey);
|
||||
var member = MemberService.CreateMember("test", "test@test.com", "T. Est", memberType.Alias);
|
||||
MemberService.Save(member);
|
||||
|
||||
// Public Access
|
||||
PublicAccessEntrySlim publicAccessEntry = new()
|
||||
{
|
||||
ContentId = _contentDefaultPageKey,
|
||||
ErrorPageId = _contentErrorPageKey,
|
||||
LoginPageId = _contentLoginPageKey,
|
||||
MemberUserNames = [member.Email],
|
||||
MemberGroupNames = [],
|
||||
};
|
||||
await PublicAccessService.CreateAsync(publicAccessEntry);
|
||||
}
|
||||
|
||||
protected override Expression<Func<GetPublicAccessDocumentController, object>> MethodSelector =>
|
||||
x => x.GetPublicAccess(CancellationToken.None, _contentDefaultPageKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document.Item;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document.Item;
|
||||
|
||||
public class ItemDocumentItemControllerTests : ManagementApiUserGroupTestBase<ItemDocumentItemController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private Guid _contentKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// ContentType
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content
|
||||
var createModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var response = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
_contentKey = response.Result.Content.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<ItemDocumentItemController, object>> MethodSelector =>
|
||||
x => x.Item(CancellationToken.None, new HashSet<Guid> { _contentKey });
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using System.Net.Http.Json;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Api.Management.ViewModels;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class MoveDocumentControllerTests : ManagementApiUserGroupTestBase<MoveDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private Guid _targetContentKey;
|
||||
private Guid _moveContentKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
contentType.AllowedContentTypes = [new ContentTypeSort(contentType.Key, 0, contentType.Alias)];
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Target Content
|
||||
var targetCreateModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseTarget = await ContentEditingService.CreateAsync(targetCreateModel, Constants.Security.SuperUserKey);
|
||||
_targetContentKey = responseTarget.Result.Content.Key;
|
||||
|
||||
// Move Content
|
||||
var moveCreateModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var responseMove = await ContentEditingService.CreateAsync(moveCreateModel, Constants.Security.SuperUserKey);
|
||||
_moveContentKey = responseMove.Result.Content.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<MoveDocumentController, object>> MethodSelector =>
|
||||
x => x.Move(CancellationToken.None, _moveContentKey, null);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest()
|
||||
{
|
||||
MoveDocumentRequestModel moveDocumentRequestModel = new() { Target = new ReferenceByIdModel(_targetContentKey), };
|
||||
|
||||
return await Client.PutAsync(Url, JsonContent.Create(moveDocumentRequestModel));
|
||||
}
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Net;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Api.Management.Controllers.Document;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Tests.Common.Builders;
|
||||
|
||||
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document;
|
||||
|
||||
public class MoveToRecycleBinDocumentControllerTests : ManagementApiUserGroupTestBase<MoveToRecycleBinDocumentController>
|
||||
{
|
||||
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
|
||||
|
||||
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
|
||||
|
||||
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
|
||||
|
||||
private Guid _documentKey;
|
||||
|
||||
[SetUp]
|
||||
public async Task Setup()
|
||||
{
|
||||
// Template
|
||||
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
|
||||
await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content Type
|
||||
var contentType = ContentTypeBuilder.CreateTextPageContentType(defaultTemplateId: template.Id, name: Guid.NewGuid().ToString(), alias: Guid.NewGuid().ToString());
|
||||
contentType.AllowedAsRoot = true;
|
||||
await ContentTypeService.CreateAsync(contentType, Constants.Security.SuperUserKey);
|
||||
|
||||
// Content
|
||||
var createModel = new ContentCreateModel
|
||||
{
|
||||
ContentTypeKey = contentType.Key,
|
||||
TemplateKey = template.Key,
|
||||
ParentKey = Constants.System.RootKey,
|
||||
InvariantName = Guid.NewGuid().ToString(),
|
||||
};
|
||||
var response = await ContentEditingService.CreateAsync(createModel, Constants.Security.SuperUserKey);
|
||||
_documentKey = response.Result.Content.Key;
|
||||
}
|
||||
|
||||
protected override Expression<Func<MoveToRecycleBinDocumentController, object>> MethodSelector =>
|
||||
x => x.MoveToRecycleBin(CancellationToken.None, _documentKey);
|
||||
|
||||
protected override UserGroupAssertionModel AdminUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel EditorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.OK
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel SensitiveDataUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel TranslatorUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel WriterUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Forbidden
|
||||
};
|
||||
|
||||
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
|
||||
{
|
||||
ExpectedStatusCode = HttpStatusCode.Unauthorized
|
||||
};
|
||||
|
||||
protected override async Task<HttpResponseMessage> ClientRequest() => await Client.PutAsync(Url, null);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user