Compare commits

...
Author SHA1 Message Date
Nhu DinhandGitHub 59f9bf290d Build: V15 Disable schedule nightly E2E trigger (#22203)
Disable schedule nightly E2E trigger
2026-03-20 17:00:08 +07:00
b6b8f54c65 V15 QA Added the authorization integration tests (#18419)
* Added authorization integration tests

* Removed unnecessary tests and update tests for preview controller

* Updated to use the newest changes from v15/dev and added an override for the AuthenticateClientAsync to use the userGroupKey

* Updated CompatibilitySuppressions to include changes from integration tests

* Updated pipelines

* Skips managementApi tests

* Only run necessary tests

* Added new schema per fixture to reduce test setup time

* Fixed failing tests

* Updated test setup

* Updated test

* Added suppression

* Fixed failing tests

* Updated addOnTeardown methods to protected

* Added method for clearing the host

* Added teardown

* Updated model usage

* Added a lot of cleanup for memory leak issues when running tests

* Added CompatibilitySuppressions.xml

* Updated tests

* Cleaned up

* Adjusted base classes

* Updated pipeline

* Updated CompatibilitySuppressions.xml

* Updated test logging

* Fixed reponse

* Updated condition to skip tests

* Updated tests, not done

* Reworked test to expect correct responses with correct setup

* Updated tests

* More updates to tests

* Updated tests

* Cleaned up tests

* Updated setup

* Cleaned up tests to match setup

* Cleaned up setup

* Removed suppression

* Fixed tests

* Move order of checks

* Fix naming

* Formatting

* Dispose of host

* Keep track of if we're disposed

* Compat suppression

* Dont dispose

* Fix failing tests

* removed unused virtual

* Updated CompatibilitySuppressions.xml

---------

Co-authored-by: Andreas Zerbst <andr317c@live.dk>
Co-authored-by: Zeegaan <skrivdetud@gmail.com>
Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
2025-10-06 20:49:09 +02:00
Andreas ZerbstandGitHub 50139ee506 E2E Pipeline: QA Remove continue on error condition (#20356)
* Removed continue on error

* Planted flaky test for testing on pipeline

* Fixed test
2025-10-03 09:39:05 +07:00
Andreas ZerbstandGitHub 62947b2862 V15 QA Added external login provider tests and split pipeline into templates (#20049)
* Added setup for external login

* Started on yaml

* Added test file

* Updated pipeline

* Use env vars

* Added env variables and commented out test we don't need to run

* Removed list from matrix

* Updated condition

* Updated package path

* Updated testFolder

* double slash

* Updated condition

* Updated condition again

* Added port

* Removed redundant values

* Set as env vars

* Added env vars beneath matrix

* Get env

* Updated naming

* Updated usage of values

* Added a check for client id, to see if value set

* Moved env out of pool

* Tried moving env

* Trying to fix the env being empty

* Removed env

* Updated name of variable

* Fixed A cyclical reference

* Updated typo

* More logging

* Reverted change

* Added env

* Added env to tests

* Cleaned up

* Added yaml template files

* Updated nighly pipepline to use templates

* Updated sln

* Split yaml into templates for e2e setup

* Updated pipeline

* Updated solution file

* Set value

* Added if statement

* Added variables

* Set default values

* Updated values

* Updated condition

* Run multiple tests

* Added env

* Updated from parameter to variable

* Fixed condition

* Fixed condition to use actual value

* Updated npx wait on command

* Updated pwsh

* Updated port again

* Updated port value

* Updated wait on

* Updated condition

* Restructured

* Updated var

* Updated run application steps

* Added echo

* Updated to boolean

* Updated conditions

* Updated test template usage

* Added databaseType

* Added another databaseType

* Split up templates

* Fixed indentation

* Updated condition

* updated path

* removed build from path

* Updated conditions for azureAd

* Fixed indentation

* Updated to single qoutes

* Cleaned up

* Removed unused file

* Clarified namin

* Moved

* Updated pipeline, not done

* Updated locator

* Updated pipelines

* Updated test helpers package

* Skipped build stage for default app settings tests

* Updated password var

* Updated locators

* Updated defaultconfig build setup

* Split E2E stage in two

* Added parameter for skipping integration tests

* Cleaned up

* Added ASPNETCORE_URLS
2025-09-05 08:42:58 +02:00
Andreas ZerbstandGitHub 1748a08f7b V15 QA updated failing acceptance tests on the nightly pipeline (#19882)
* Updated tests

* Bumped test helpers
2025-08-11 09:05:17 +02:00
Andreas ZerbstandGitHub 3264d58f13 V15 QA acceptance tests with appsettings (#19550)
* Start of appsetting

* Updated setup of playwright

* Adjusted the pipeline

* Updated appsetting

* Added install test

* Added comments

* Updated pipeline

* Updated development app settings

* Commented tests out

* comment

* Added if statement

* Updated pipeline

* Fixed condition

* Changed to production

* Added a log

* Updated copy item

* Added

* Updated app settings

* Updated pipeline

* Moved playwright login

* Updated pipeline

* Updated app setting

* Updated nightly

* Updated appsettings

* Updated get

* Updated wait on

* Updated appsettings

* Updated connection string

* Updates

* Skips code

* Updated variable

* Updated pipeline

* We want to always retain the trace, to see if the test runs as expected on the pipeline

* Added a temporary wait till port is open

* Fixed condition

* Added missing tcp for wait on

* Updated URL env

* Updated setup

* Fixed string

* Updated locator

* Split tests into SQLite and SQLServer

* Updated pipeline to run all tests

* Retain trace on failure

* Added testFolder var

* Added appsettings and program for delivery api tests

* Updated playwright config

* Split test runners into defaultconfig and different app settings

* Added delivery api tests

* Cleaned up tests

* Bumped version

* Updated pipeline

* Small fixes

* Added password

* Updated connection string

* Fixed

* Removed quotes

* Removed unnecessary connection string

* Added missing password

* Cleaned up

* Cleaned up

* Cleaned up

* Updated to use helpers

* Bumped version

* Updated helper usage

* Added password to variables and a condition

* Added check

* Indented value

* Fixed condition

* More updates

* Updated variable
2025-08-05 11:22:03 +02:00
Andy Butland b6be468b3a Merge branch 'v15/dev' of https://github.com/umbraco/Umbraco-CMS into v15/dev 2025-07-29 07:18:37 +02:00
Andy Butland 3ec88aab65 Merge branch 'release/15.4.4' into v15/dev
# Conflicts:
#	src/Umbraco.Web.UI.Client/package.json
#	version.json
2025-07-29 07:18:24 +02:00
da43086017 Merge commit from fork
Co-authored-by: kjac <kja@umbraco.dk>
2025-07-29 05:10:52 +02:00
d62fe5e315 Fix issue with use of EF Core scopes within notification handlers (take 2 - handling scopes with a base parent) (#19797)
* Add integration tests that shows the problem

* Fix the problem and add explenation

* Improved comments slightly to help when we come back here!
Moved tests alongside existing ones related to scopes.
Removed long running attribute from tests (they are quite fast).

* Fixed casing in comment.

---------

Co-authored-by: Andy Butland <abutland73@gmail.com>
2025-07-25 13:10:44 +02:00
Andy Butland 852192a5d2 Bumped package.json version to 15.4.4. 2025-07-24 09:27:21 +02:00
Andy Butland f4498c3d05 Bumped version to 15.4.4. 2025-07-21 11:56:22 +02:00
Nhu DinhandGitHub b045b33049 V15 QA Removed unused API acceptance tests (#19680)
Removed unused API acceptance tests
2025-07-09 10:11:37 +07:00
297 changed files with 15516 additions and 2489 deletions
+74 -254
View File
@@ -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:
@@ -522,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)
@@ -674,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
+75
View File
@@ -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
+105
View File
@@ -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)"
+69
View File
@@ -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
+274 -314
View File
@@ -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
@@ -92,10 +108,10 @@ stages:
inputs:
targetPath: $(Build.ArtifactStagingDirectory)/npm
artifactName: npm
- stage: Integration
displayName: Integration Tests
dependsOn: Build
condition: ${{ eq(parameters.skipIntegrationTests, false) }}
jobs:
# Integration Tests (SQLite)
- job:
@@ -105,31 +121,39 @@ stages:
matrix:
# Windows:
# vmImage: 'windows-latest'
# We split the tests into 3 parts for each OS to reduce the time it takes to run them on the pipeline
LinuxPart1Of3:
# 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)"
LinuxPart2Of3:
LinuxPart2Of4:
vmImage: "ubuntu-latest"
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
LinuxPart3Of3:
LinuxPart3Of4:
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)"
macOSPart1Of3:
# 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)"
macOSPart2Of3:
macOSPart2Of4:
vmImage: "macOS-latest"
# Filter tests that are part of the Umbraco.Infrastructure.Service namespace
testFilter: "(FullyQualifiedName~Umbraco.Infrastructure.Service)"
macOSPart3Of3:
macOSPart3Of4:
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.
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:
@@ -165,48 +189,59 @@ stages:
- job:
timeoutInMinutes: 180
displayName: Integration Tests (SQL Server)
variables:
SA_PASSWORD: UmbracoAcceptance123!
strategy:
matrix:
# We split the tests into 3 parts for each OS to reduce the time it takes to run them on the pipeline
WindowsPart1Of3:
# 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)"
WindowsPart2Of3:
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)"
WindowsPart3Of3:
WindowsPart3Of4:
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)"
LinuxPart1Of3:
# 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"
SA_PASSWORD: UmbracoIntegration123!
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)"
LinuxPart2Of3:
LinuxPart2Of4:
vmImage: "ubuntu-latest"
SA_PASSWORD: UmbracoIntegration123!
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)"
LinuxPart3Of3:
LinuxPart3Of4:
vmImage: "ubuntu-latest"
SA_PASSWORD: UmbracoIntegration123!
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 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.
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:
@@ -276,8 +311,8 @@ stages:
displayName: Stop SQL Server LocalDB (Windows)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- stage: E2E
displayName: E2E Tests
- stage: DefaultConfigE2E
displayName: Default Config E2E Tests
dependsOn: Build
variables:
npm_config_cache: $(Pipeline.Workspace)/.npm_e2e
@@ -305,365 +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 chromium
displayName: Install Playwright only with Chromium browser
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);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);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);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 }}
- powershell: |
$maxAttempts = 12
$attempt = 0
$status = ""
# Run tests Template
- template: nightly-E2E-run-tests-template.yml
parameters:
testCommand: $(testCommand)
ASPNETCORE_URLS: ${{ variables.ASPNETCORE_URLS }}
DatabaseType: ${{ variables.DatabaseType }}
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
- 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 }}
if ($status -ne 'running') {
Write-Host "Waiting for SQL Server to be ready... Attempt $($attempt + 1)"
$attempt++
}
}
# 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'], ''))
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'))
# Build application Template
- template: nightly-E2E-build-template.yml
parameters:
testFolder: $(testFolder)
buildConfiguration: ${{ variables.buildConfiguration }}
additionalEnvironmentVariables: ${{ eq(variables['additionalEnvironmentVariables'], true) }}
- pwsh: SqlLocalDB start MSSQLLocalDB
displayName: Start SQL Server LocalDB (Windows)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
# 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
# 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 chromium
displayName: Install Playwright only with Chromium browser
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();
+2
View File
@@ -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()
+4 -4
View File
@@ -8,7 +8,7 @@
"hasInstallScript": true,
"dependencies": {
"@umbraco/json-models-builders": "^2.0.33",
"@umbraco/playwright-testhelpers": "^15.0.52",
"@umbraco/playwright-testhelpers": "^15.0.56",
"camelize": "^1.0.0",
"dotenv": "^16.3.1",
"node-fetch": "^2.6.7"
@@ -66,9 +66,9 @@
}
},
"node_modules/@umbraco/playwright-testhelpers": {
"version": "15.0.52",
"resolved": "https://registry.npmjs.org/@umbraco/playwright-testhelpers/-/playwright-testhelpers-15.0.52.tgz",
"integrity": "sha512-HJ+kiafLX0ck0/nYol0Kr7yks/hBbnCKotr1+TaxIBgowvbirIt0paY7wluQpHQi0e6nAmJZsjZZ08abh9ZKBA==",
"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",
@@ -21,7 +21,7 @@
},
"dependencies": {
"@umbraco/json-models-builders": "^2.0.33",
"@umbraco/playwright-testhelpers": "^15.0.52",
"@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();
});
});
@@ -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);
});
});
@@ -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();
});
});
@@ -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();
});
});
@@ -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);
@@ -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([]);
});
});
@@ -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);
@@ -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);
@@ -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);
});
@@ -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
}
}
}
]
}
@@ -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;
}
}
}
@@ -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);
}
}
}
@@ -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);
}
}
@@ -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;
}
}
@@ -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);
});
@@ -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/"
}
}
}
}
@@ -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);
});
@@ -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
};
}
@@ -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));
}
}
@@ -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));
}
}
@@ -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);
}
@@ -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
};
}
@@ -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));
}
}
@@ -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);
}
@@ -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));
}
}
@@ -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
};
}
@@ -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));
}
}
@@ -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
};
}
@@ -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
};
}
@@ -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
};
}
@@ -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));
}
}
@@ -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
};
}
@@ -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
};
}
@@ -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));
}
}
@@ -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);
}
@@ -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
};
}
@@ -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));
}
}
@@ -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
};
}
@@ -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));
}
}
@@ -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
};
}
@@ -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
};
}
@@ -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));
}
}
@@ -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
};
}
@@ -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));
}
}
@@ -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));
}
}
@@ -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));
}
}
@@ -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
};
}
@@ -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
};
}
@@ -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
};
}
@@ -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));
}
}
@@ -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);
}
@@ -0,0 +1,88 @@
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 NotificationsControllerTests : ManagementApiUserGroupTestBase<NotificationsController>
{
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private IUserService UserService => GetRequiredService<IUserService>();
private INotificationService NotificationService => GetRequiredService<INotificationService>();
private Guid _contentKey;
[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);
_contentKey = response.Result.Content.Key;
// User
var user = await UserService.GetAsync(Constants.Security.SuperUserKey);
// Notification
NotificationService.CreateNotification(user, contentType, "X");
}
protected override Expression<Func<NotificationsController, object>> MethodSelector =>
x => x.Notifications(CancellationToken.None, _contentKey);
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,94 @@
using System.Linq.Expressions;
using System.Net;
using NUnit.Framework;
using Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.ContentTypeEditing;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Services.Querying.RecycleBin;
using Umbraco.Cms.Tests.Common.Builders;
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document.RecycleBin;
public class ChildrenDocumentRecycleBinControllerTests : ManagementApiUserGroupTestBase<ChildrenDocumentRecycleBinController>
{
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private Guid _parentKey;
[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);
// Parent Content
var parentCreateModel = new ContentCreateModel
{
ContentTypeKey = contentType.Key,
TemplateKey = template.Key,
ParentKey = Constants.System.RootKey,
InvariantName = Guid.NewGuid().ToString(),
};
var responseParent = await ContentEditingService.CreateAsync(parentCreateModel, Constants.Security.SuperUserKey);
_parentKey = responseParent.Result.Content.Key;
// Child Content
var childCreateModel = new ContentCreateModel
{
ContentTypeKey = contentType.Key,
TemplateKey = template.Key,
ParentKey = _parentKey,
InvariantName = Guid.NewGuid().ToString(),
};
await ContentEditingService.CreateAsync(childCreateModel, Constants.Security.SuperUserKey);
await ContentEditingService.MoveToRecycleBinAsync(_parentKey, Constants.Security.SuperUserKey);
}
protected override Expression<Func<ChildrenDocumentRecycleBinController, object>> MethodSelector =>
x => x.Children(CancellationToken.None, _parentKey, 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.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,80 @@
using System.Linq.Expressions;
using System.Net;
using NUnit.Framework;
using Umbraco.Cms.Api.Management.Controllers.Document.RecycleBin;
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.RecycleBin;
public class RootDocumentRecycleBinControllerTests : ManagementApiUserGroupTestBase<RootDocumentRecycleBinController>
{
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;
await ContentEditingService.MoveToRecycleBinAsync(_documentKey, Constants.Security.SuperUserKey);
}
protected override Expression<Func<RootDocumentRecycleBinController, object>> MethodSelector =>
x => x.Root(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.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,93 @@
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.Sorting;
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 SortDocumentControllerTests : ManagementApiUserGroupTestBase<SortDocumentController>
{
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);
// 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);
// 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<SortDocumentController, object>> MethodSelector =>
x => x.Sort(CancellationToken.None, 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()
{
SortingRequestModel sortingRequestModel = new()
{
Parent = null, Sorting = new[] { new ItemSortingRequestModel { Id = _contentKey, SortOrder = 0 } },
};
return await Client.PutAsync(Url, JsonContent.Create(sortingRequestModel));
}
}
@@ -0,0 +1,90 @@
using System.Linq.Expressions;
using System.Net;
using NUnit.Framework;
using Umbraco.Cms.Api.Management.Controllers.Document.Tree;
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.Tree;
public class ChildrenDocumentTreeControllerTests : ManagementApiUserGroupTestBase<ChildrenDocumentTreeController>
{
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private Guid _parentKey;
[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);
// Parent Content
var parentCreateModel = new ContentCreateModel
{
ContentTypeKey = contentType.Key,
TemplateKey = template.Key,
ParentKey = Constants.System.RootKey,
InvariantName = Guid.NewGuid().ToString(),
};
var responseParent = await ContentEditingService.CreateAsync(parentCreateModel, Constants.Security.SuperUserKey);
_parentKey = responseParent.Result.Content.Key;
// Child Content
var childCreateModel = new ContentCreateModel
{
ContentTypeKey = contentType.Key,
TemplateKey = template.Key,
ParentKey = _parentKey,
InvariantName = Guid.NewGuid().ToString(),
};
await ContentEditingService.CreateAsync(childCreateModel, Constants.Security.SuperUserKey);
}
protected override Expression<Func<ChildrenDocumentTreeController, object>> MethodSelector =>
x => x.Children(CancellationToken.None, _parentKey, 0, 100, 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.OK
};
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
{
ExpectedStatusCode = HttpStatusCode.Unauthorized
};
}
@@ -0,0 +1,42 @@
using System.Linq.Expressions;
using System.Net;
using Umbraco.Cms.Api.Management.Controllers.Document.Tree;
namespace Umbraco.Cms.Tests.Integration.ManagementApi.Document.Tree;
public class RootDocumentTreeControllerTests : ManagementApiUserGroupTestBase<RootDocumentTreeController>
{
protected override Expression<Func<RootDocumentTreeController, object>> MethodSelector =>
x => x.Root(CancellationToken.None, 0, 100, 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.OK
};
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
{
ExpectedStatusCode = HttpStatusCode.Unauthorized
};
}
@@ -0,0 +1,95 @@
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.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 UpdateDocumentControllerTests : ManagementApiUserGroupTestBase<UpdateDocumentController>
{
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private Guid _templateKey;
private Guid _documentKey;
[SetUp]
public async Task Setup()
{
// Template
var template = TemplateBuilder.CreateTextPageTemplate(Guid.NewGuid().ToString());
var templateResponse = await TemplateService.CreateAsync(template, Constants.Security.SuperUserKey);
_templateKey = templateResponse.Result.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);
// Content
var createModel = new ContentCreateModel
{
ContentTypeKey = contentType.Key,
TemplateKey = _templateKey,
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<UpdateDocumentController, object>> MethodSelector =>
x => x.Update(CancellationToken.None, _documentKey, 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.OK
};
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
{
ExpectedStatusCode = HttpStatusCode.Unauthorized
};
protected override async Task<HttpResponseMessage> ClientRequest()
{
UpdateDocumentRequestModel updateDocumentRequestModel = new()
{
Variants = new DocumentVariantRequestModel[]
{
new() { Culture = null, Segment = null, Name = "The new name", },
},
};
return await Client.PutAsync(Url, JsonContent.Create(updateDocumentRequestModel));
}
}
@@ -0,0 +1,121 @@
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.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 UpdateDomainsControllerTests : ManagementApiUserGroupTestBase<UpdateDomainsController>
{
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 = Guid.NewGuid().ToString(), IsoCode = "da-DK" }.Yield(),
};
await DomainService.UpdateDomainsAsync(_documentKey, domainsUpdateModel);
}
protected override Expression<Func<UpdateDomainsController, object>> MethodSelector =>
x => x.Update(CancellationToken.None, _documentKey, 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.OK
};
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
{
ExpectedStatusCode = HttpStatusCode.Unauthorized
};
protected override async Task<HttpResponseMessage> ClientRequest()
{
UpdateDomainsRequestModel updateDomainsRequestModel = new()
{
DefaultIsoCode = "en-US",
Domains = new DomainPresentationModel[]
{
new() { DomainName = Guid.NewGuid().ToString(), IsoCode = "en-US", },
},
};
return await Client.PutAsync(Url, JsonContent.Create(updateDomainsRequestModel));
}
}
@@ -0,0 +1,100 @@
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.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 UpdateNotificationsControllerTests : ManagementApiUserGroupTestBase<UpdateNotificationsController>
{
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private IUserService UserService => GetRequiredService<IUserService>();
private INotificationService NotificationService => GetRequiredService<INotificationService>();
private Guid _contentKey;
[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);
_contentKey = response.Result.Content.Key;
// User
var user = await UserService.GetAsync(Constants.Security.SuperUserKey);
// Notification
NotificationService.CreateNotification(user, contentType, "X");
}
protected override Expression<Func<UpdateNotificationsController, object>> MethodSelector =>
x => x.UpdateNotifications(CancellationToken.None, _contentKey, 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.OK
};
protected override UserGroupAssertionModel UnauthorizedUserGroupAssertionModel => new()
{
ExpectedStatusCode = HttpStatusCode.Unauthorized
};
protected override async Task<HttpResponseMessage> ClientRequest()
{
UpdateDocumentNotificationsRequestModel updateDocumentNotificationsRequestModel = new()
{
SubscribedActionIds = ["Umb.Document.Create"],
};
return await Client.PutAsync(Url, JsonContent.Create(updateDocumentNotificationsRequestModel));
}
}
@@ -0,0 +1,154 @@
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;
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 UpdatePublicAccessDocumentControllerTests : ManagementApiUserGroupTestBase<UpdatePublicAccessDocumentController>
{
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;
private Guid _newContentErrorPageKey;
[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);
// 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;
// New error page
var createNewErrorPageModel = new ContentCreateModel
{
ContentTypeKey = contentType.Key,
TemplateKey = template.Key,
ParentKey = Constants.System.RootKey,
InvariantName = Guid.NewGuid().ToString(),
};
var responseNewErrorPage = await ContentEditingService.CreateAsync(createNewErrorPageModel, Constants.Security.SuperUserKey);
_newContentErrorPageKey = responseNewErrorPage.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<UpdatePublicAccessDocumentController, object>> MethodSelector =>
x => x.Update(CancellationToken.None, _contentDefaultPageKey, 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()
{
PublicAccessRequestModel publicAccessRequestModel = new()
{
MemberUserNames = ["test@test.com"],
MemberGroupNames = [],
LoginDocument = new ReferenceByIdModel(_contentDefaultPageKey),
ErrorDocument = new ReferenceByIdModel(_newContentErrorPageKey),
};
return await Client.PutAsync(Url, JsonContent.Create(publicAccessRequestModel));
}
}
@@ -0,0 +1,85 @@
using System.Linq.Expressions;
using System.Net;
using NUnit.Framework;
using Umbraco.Cms.Api.Management.Controllers.DocumentBlueprint.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.DocumentBlueprint.Item;
public class ItemDocumentBlueprintControllerTests : ManagementApiUserGroupTestBase<ItemDocumentBlueprintController>
{
private IContentEditingService ContentEditingService => GetRequiredService<IContentEditingService>();
private ITemplateService TemplateService => GetRequiredService<ITemplateService>();
private IContentTypeService ContentTypeService => GetRequiredService<IContentTypeService>();
private IContentBlueprintEditingService ContentBlueprintEditingService => GetRequiredService<IContentBlueprintEditingService>();
private Guid _contentKey;
private Guid _blueprintKey;
[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);
_contentKey = response.Result.Content.Key;
// Blueprint
_blueprintKey = Guid.NewGuid();
await ContentBlueprintEditingService.CreateFromContentAsync(_contentKey, createModel.InvariantName, _blueprintKey, Constants.Security.SuperUserKey);
}
protected override Expression<Func<ItemDocumentBlueprintController, object>> MethodSelector =>
x => x.Item(CancellationToken.None, new HashSet<Guid> { _blueprintKey });
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
};
}

Some files were not shown because too many files have changed in this diff Show More